// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.10; import 'test/base/BaseTest.t.sol'; import {DegreesOfSeparationReferenceModule, ModuleConfig} from 'contracts/modules/reference/DegreesOfSeparationReferenceModule.sol'; import {Errors} from 'contracts/libraries/constants/Errors.sol'; import {StorageLib} from 'contracts/libraries/StorageLib.sol'; contract DegreesOfSeparationReferenceModuleTest is BaseTest { // The one that performed the original publication that is being commented/quoted/mirrored. TestAccount originalPublisher; // The one performing the comment/mirror/quote. TestAccount currentPublisher; // Expected to be used mostly as 1st degree profile in the path, when needed. TestAccount firstAccount; // Expected to be used mostly as 2nd degree profile in the path, when needed. TestAccount secondAccount; // Expected to be used mostly as 3rd degree profile in the path, when needed. TestAccount thirdAccount; address hubAddress; uint8 MAX_DEGREES_OF_SEPARATION; DegreesOfSeparationReferenceModule module; function testDegreesOfSeparationReferenceModule() public { // Prevents being counted in Foundry Coverage } function setUp() public virtual override { super.setUp(); originalPublisher = _loadAccountAs('PUBLISHER'); currentPublisher = _loadAccountAs('ANOTHER_PUBLISHER'); firstAccount = _loadAccountAs('FIRST_ACCOUNT'); secondAccount = _loadAccountAs('SECOND_ACCOUNT'); thirdAccount = _loadAccountAs('THIRD_ACCOUNT'); hubAddress = address(hub); module = DegreesOfSeparationReferenceModule(loadOrDeploy_DegreesOfSeparationReferenceModule()); MAX_DEGREES_OF_SEPARATION = module.MAX_DEGREES_OF_SEPARATION(); } function _getInitData( bool commentsRestricted, bool quotesRestricted, bool mirrorsRestricted, uint8 degreesOfSeparation, uint96 sourceProfile ) private pure returns (bytes memory) { return abi.encode(commentsRestricted, quotesRestricted, mirrorsRestricted, degreesOfSeparation, sourceProfile); } function testCannotInitialize_IfSenderIsNotTheLensHub(address notHub) public { vm.assume(notHub != address(0)); vm.assume(notHub != hubAddress); vm.expectRevert(Errors.NotHub.selector); vm.prank(notHub); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, sourceProfile: uint96(originalPublisher.profileId) }) ); } function testCannotInitialize_IfDegreesExceedsMaxAllowedValue(uint8 unallowedDegreesValue) public { vm.assume(unallowedDegreesValue > MAX_DEGREES_OF_SEPARATION); vm.expectRevert(DegreesOfSeparationReferenceModule.InvalidDegreesOfSeparation.selector); vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: unallowedDegreesValue, sourceProfile: uint96(originalPublisher.profileId) }) ); } function testCannotInitialize_IfDataHasWrongFormat() public { bytes memory wrongData = abi.encode(true, 69); vm.expectRevert(); vm.prank(hubAddress); module.initializeReferenceModule(originalPublisher.profileId, 1, originalPublisher.owner, wrongData); } function testCannotInitialize_IfSourceProfileDoesNotExist(uint96 unexistentProfileId) public { vm.assume(!hub.exists(unexistentProfileId)); vm.expectRevert(Errors.TokenDoesNotExist.selector); vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, sourceProfile: unexistentProfileId }) ); } function testInitialize( bool commentsRestricted, bool quotesRestricted, bool mirrorsRestricted, uint8 degrees ) public { degrees = uint8(bound(degrees, 0, MAX_DEGREES_OF_SEPARATION)); vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: commentsRestricted, quotesRestricted: quotesRestricted, mirrorsRestricted: mirrorsRestricted, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); ModuleConfig memory config = module.getModuleConfig(originalPublisher.profileId, 1); assertTrue(config.setUp); assertEq(config.commentsRestricted, commentsRestricted); assertEq(config.quotesRestricted, quotesRestricted); assertEq(config.mirrorsRestricted, mirrorsRestricted); assertEq(config.degreesOfSeparation, degrees); assertEq(config.sourceProfile, uint96(originalPublisher.profileId)); } function testCannotProcessComment_IfDegreesOfSeparationRestrictionIsNotMet_PathLength(uint8 degrees) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: false, mirrorsRestricted: false, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildWrongPathLengthPath(); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.ProfilePathExceedsDegreesOfSeparation.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessMirror_IfDegreesOfSeparationRestrictionIsNotMet_PathLength(uint8 degrees) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: false, quotesRestricted: false, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildWrongPathLengthPath(); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: false, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.ProfilePathExceedsDegreesOfSeparation.selector); vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessQuote_IfDegreesOfSeparationRestrictionIsNotMet_PathLength(uint8 degrees) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: false, quotesRestricted: true, mirrorsRestricted: false, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildWrongPathLengthPath(); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: false, quotesRestricted: false, mirrorsRestricted: false, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.ProfilePathExceedsDegreesOfSeparation.selector); vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessComment_IfDegreesOfSeparationRestrictionIsNotMet_OriginalPublisherDoesNotFollowFirstPathNode( uint8 degrees ) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildPathWhereOriginalPublisherDoesNotFollowFirstNode(degrees); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(Errors.NotFollowing.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessMirror_IfDegreesOfSeparationRestrictionIsNotMet_OriginalPublisherDoesNotFollowFirstPathNode( uint8 degrees ) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildPathWhereOriginalPublisherDoesNotFollowFirstNode(degrees); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(Errors.NotFollowing.selector); vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessQuote_IfDegreesOfSeparationRestrictionIsNotMet_OriginalPublisherDoesNotFollowFirstPathNode( uint8 degrees ) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildPathWhereOriginalPublisherDoesNotFollowFirstNode(degrees); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(Errors.NotFollowing.selector); vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessComment_IfDegreesOfSeparationRestrictionIsNotMet_LastPathNodeDoesNotFollowCurrentPublisher( uint8 degrees ) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildPathWhereLastPathNodeDoesNotFollowCurrentPublisher(degrees); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(Errors.NotFollowing.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessMirror_IfDegreesOfSeparationRestrictionIsNotMet_LastPathNodeDoesNotFollowCurrentPublisher( uint8 degrees ) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildPathWhereLastPathNodeDoesNotFollowCurrentPublisher(degrees); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(Errors.NotFollowing.selector); vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } function testCannotProcessQuote_IfDegreesOfSeparationRestrictionIsNotMet_LastPathNodeDoesNotFollowCurrentPublisher( uint8 degrees ) public { // Degrees 0 is a special case that will be tested separetly. degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Performs follows and builds path. uint256[] memory path = _buildPathWhereLastPathNodeDoesNotFollowCurrentPublisher(degrees); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: currentPublisherPubCount) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(Errors.NotFollowing.selector); vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(path) }) ); } // function testCannotProcessComment_IfDegreesOfSeparationRestrictionIsNotMet_MissingFollowLinkInThePath() public { // // Note: This test just makes sense for degrees = 3, the rest of the cases are already covered by other tests. // // Initializes module for (profile: originalPublisher.profileId, pubId: 1) // vm.prank(hubAddress); // module.initializeReferenceModule( // originalPublisher.profileId, // 1, // originalPublisher.owner, // _getInitData({ // commentsRestricted: true, // quotesRestricted: true, // mirrorsRestricted: true, // degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, // sourceProfile: uint96(originalPublisher.profileId) // }) // ); // // Performs follows and builds path. // uint256[] memory path = new uint256[](MAX_DEGREES_OF_SEPARATION - 1); // _follow({follower: originalPublisher, target: firstAccount}); // path[0] = firstAccount.profileId; // // Intentonally missing _follow(firstAccount, secondAccount) linkage. // _follow({follower: secondAccount, target: currentPublisher}); // path[1] = secondAccount.profileId; // // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: 1) // vm.prank(hubAddress); // module.initializeReferenceModule( // currentPublisher.profileId, // 1, // currentPublisher.owner, // _getInitData({ // commentsRestricted: true, // quotesRestricted: true, // mirrorsRestricted: true, // degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, // sourceProfile: uint96(originalPublisher.profileId) // }) // ); // _mockLensHubPubCountResponse({account: currentPublisher, pubCount: 1}); // vm.expectRevert(Errors.NotFollowing.selector); // vm.prank(hubAddress); // module.processComment( // Types.ProcessCommentParams({ // profileId: currentPublisher.profileId, // transactionExecutor: currentPublisher.owner, // pointedProfileId: originalPublisher.profileId, // pointedPubId: 1, // referrerProfileIds: _emptyUint256Array(), // referrerPubIds: _emptyUint256Array(), // referrerPubTypes: _emptyPubTypesArray(), // data: abi.encode(path) // }) // ); // } // function testCannotProcessMirror_IfDegreesOfSeparationRestrictionIsNotMet_MissingFollowLinkInThePath() public { // // Note: This test just makes sense for degrees = 3, the rest of the cases are already covered by other tests. // // Initializes module for (profile: originalPublisher.profileId, pubId: 1) // vm.prank(hubAddress); // module.initializeReferenceModule( // originalPublisher.profileId, // 1, // originalPublisher.owner, // _getInitData({ // commentsRestricted: true, // quotesRestricted: true, // mirrorsRestricted: true, // degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, // sourceProfile: uint96(originalPublisher.profileId) // }) // ); // // Performs follows and builds path. // uint256[] memory path = new uint256[](MAX_DEGREES_OF_SEPARATION - 1); // _follow({follower: originalPublisher, target: firstAccount}); // path[0] = firstAccount.profileId; // // Intentonally missing _follow(firstAccount, secondAccount) linkage. // _follow({follower: secondAccount, target: currentPublisher}); // path[1] = secondAccount.profileId; // // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: 1) // vm.prank(hubAddress); // module.initializeReferenceModule( // currentPublisher.profileId, // 1, // currentPublisher.owner, // _getInitData({ // commentsRestricted: true, // quotesRestricted: true, // mirrorsRestricted: true, // degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, // sourceProfile: uint96(originalPublisher.profileId) // }) // ); // _mockLensHubPubCountResponse({account: currentPublisher, pubCount: 1}); // vm.expectRevert(Errors.NotFollowing.selector); // vm.prank(hubAddress); // module.processMirror( // Types.ProcessMirrorParams({ // profileId: currentPublisher.profileId, // transactionExecutor: currentPublisher.owner, // pointedProfileId: originalPublisher.profileId, // pointedPubId: 1, // referrerProfileIds: _emptyUint256Array(), // referrerPubIds: _emptyUint256Array(), // referrerPubTypes: _emptyPubTypesArray(), // data: abi.encode(path) // }) // ); // } // function testCannotProcessQuote_IfDegreesOfSeparationRestrictionIsNotMet_MissingFollowLinkInThePath() public { // // Note: This test just makes sense for degrees = 3, the rest of the cases are already covered by other tests. // // Initializes module for (profile: originalPublisher.profileId, pubId: 1) // vm.prank(hubAddress); // module.initializeReferenceModule( // originalPublisher.profileId, // 1, // originalPublisher.owner, // _getInitData({ // commentsRestricted: true, // quotesRestricted: true, // mirrorsRestricted: true, // degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, // sourceProfile: uint96(originalPublisher.profileId) // }) // ); // // Performs follows and builds path. // uint256[] memory path = new uint256[](MAX_DEGREES_OF_SEPARATION - 1); // _follow({follower: originalPublisher, target: firstAccount}); // path[0] = firstAccount.profileId; // // Intentonally missing _follow(firstAccount, secondAccount) linkage. // _follow({follower: secondAccount, target: currentPublisher}); // path[1] = secondAccount.profileId; // // Initializes module for config inheritance (profile: currentPublisher.profileId, pubId: 1) // vm.prank(hubAddress); // module.initializeReferenceModule( // currentPublisher.profileId, // 1, // currentPublisher.owner, // _getInitData({ // commentsRestricted: true, // quotesRestricted: true, // mirrorsRestricted: true, // degreesOfSeparation: MAX_DEGREES_OF_SEPARATION, // sourceProfile: uint96(originalPublisher.profileId) // }) // ); // _mockLensHubPubCountResponse({account: currentPublisher, pubCount: 1}); // vm.expectRevert(Errors.NotFollowing.selector); // vm.prank(hubAddress); // module.processQuote( // Types.ProcessQuoteParams({ // profileId: currentPublisher.profileId, // transactionExecutor: currentPublisher.owner, // pointedProfileId: originalPublisher.profileId, // pointedPubId: 1, // referrerProfileIds: _emptyUint256Array(), // referrerPubIds: _emptyUint256Array(), // referrerPubTypes: _emptyPubTypesArray(), // data: abi.encode(path) // }) // ); // } function testCannotProcessComment_IfNotInheritingConfig_NotUsingSameReferenceModule(uint8 degrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; vm.expectRevert(DegreesOfSeparationReferenceModule.NotInheritingPointedPubConfig.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testCannotProcessComment_IfNotInheritingConfig_NotRestrictingComments(uint8 degrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: false, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.NotInheritingPointedPubConfig.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testCannotProcessComment_IfNotInheritingConfig_WrongSourceProfile( uint8 degrees, uint96 wrongSourceProfile ) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); vm.assume(hub.exists(wrongSourceProfile)); vm.assume(wrongSourceProfile != uint96(originalPublisher.profileId)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: wrongSourceProfile }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.NotInheritingPointedPubConfig.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testCannotProcessComment_IfNotInheritingConfig_WrongDegrees(uint8 degrees, uint8 wrongDegrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); wrongDegrees = uint8(bound(wrongDegrees, 0, MAX_DEGREES_OF_SEPARATION)); vm.assume(degrees != wrongDegrees); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, currentPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: wrongDegrees, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.NotInheritingPointedPubConfig.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessQuote_EvenWhenNotInheritingConfig(uint8 degrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // NOTE: Quote is not even using the reference same module! vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessMirror_EvenWhenNotInheritingConfig(uint8 degrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // NOTE: Mirror is not even using the reference same module! vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessComment_IfCommentNotRestricted(uint8 degrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: false, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // NOTE: Comment is not using the reference same module. vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessMirror_IfMirrorNotRestricted(uint8 degrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: false, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // NOTE: Mirror is not using the reference same module. vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessQuote_IfQuoteNotRestricted(uint8 degrees) public { degrees = uint8(bound(degrees, 1, MAX_DEGREES_OF_SEPARATION)); // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: false, mirrorsRestricted: true, degreesOfSeparation: degrees, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // NOTE: Quote is not using the reference same module. vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: currentPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessComment_WhenRestrictedWithZeroDegrees_ButCurrentPublisherIsSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 2, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: originalPublisher.profileId, pubId: 2, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessComment_WhenRestricted_ButCurrentPublisherIsSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 2, sourceProfile: uint96(originalPublisher.profileId) }) ); // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 2, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 2, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: originalPublisher.profileId, pubId: 2, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessMirror_WhenRestrictedWithZeroDegrees_ButCurrentPublisherIsSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 2, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: originalPublisher.profileId, pubId: 2, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessMirror_WhenRestricted_ButCurrentPublisherIsSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 2, sourceProfile: uint96(originalPublisher.profileId) }) ); // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 2, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 2, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: originalPublisher.profileId, pubId: 2, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessQuote_WhenRestrictedWithZeroDegrees_ButCurrentPublisherIsSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 2, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); _mockLensHubPubCountResponse({account: originalPublisher, pubCount: 2}); vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: originalPublisher.profileId, pubId: 2, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testProcessQuote_WhenRestricted_ButCurrentPublisherIsSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 2, sourceProfile: uint96(originalPublisher.profileId) }) ); // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 2, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 2, sourceProfile: uint96(originalPublisher.profileId) }) ); _mockLensHubPubCountResponse({account: originalPublisher, pubCount: 2}); vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: originalPublisher.profileId, pubId: 2, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testCannotProcessComment_WhenRestrictedWithZeroDegrees_AndCurrentPublisherIsNotSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.OperationDisabled.selector); vm.prank(hubAddress); module.processComment( Types.ProcessCommentParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testCannotProcessMirror_WhenRestrictedWithZeroDegrees_AndCurrentPublisherIsNotSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.OperationDisabled.selector); vm.prank(hubAddress); module.processMirror( Types.ProcessMirrorParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } function testCannotProcessQuote_WhenRestrictedWithZeroDegrees_AndCurrentPublisherIsNotSourceProfile() public { // Initializes module for (profile: originalPublisher.profileId, pubId: 1) vm.prank(hubAddress); module.initializeReferenceModule( originalPublisher.profileId, 1, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); // Makes current publisher to be one degree of separation from original publisher. _follow({follower: originalPublisher, target: currentPublisher}); uint256 currentPublisherPubCount = hub.getProfile(currentPublisher.profileId).pubCount; // Initializes module for (profile: originalPublisher.profileId, pubId: 2) vm.prank(hubAddress); module.initializeReferenceModule( currentPublisher.profileId, currentPublisherPubCount, originalPublisher.owner, _getInitData({ commentsRestricted: true, quotesRestricted: true, mirrorsRestricted: true, degreesOfSeparation: 0, sourceProfile: uint96(originalPublisher.profileId) }) ); vm.expectRevert(DegreesOfSeparationReferenceModule.OperationDisabled.selector); vm.prank(hubAddress); module.processQuote( Types.ProcessQuoteParams({ profileId: currentPublisher.profileId, pubId: currentPublisherPubCount, transactionExecutor: originalPublisher.owner, pointedProfileId: originalPublisher.profileId, pointedPubId: 1, referrerProfileIds: _emptyUint256Array(), referrerPubIds: _emptyUint256Array(), referrerPubTypes: _emptyPubTypesArray(), data: abi.encode(_emptyUint256Array()) }) ); } // TODO - test the new logic: // - if the current publisher is the originalAuthor or source profile, then it can reply without restrictions // - you cannot init degrees on a comment, only on post and quote // etc //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function _mockLensHubPubCountResponse(TestAccount memory account, uint256 pubCount) internal { uint256 profileId = account.profileId; uint256 profilesMappingSlot = StorageLib.PROFILES_MAPPING_SLOT; uint256 pubCountSlot; assembly { mstore(0, profileId) mstore(32, profilesMappingSlot) pubCountSlot := keccak256(0, 64) } vm.store(hubAddress, bytes32(pubCountSlot), bytes32(pubCount)); } function _buildWrongPathLengthPath() internal returns (uint256[] memory) { uint256[] memory path = new uint256[](MAX_DEGREES_OF_SEPARATION); _follow({follower: originalPublisher, target: firstAccount}); path[0] = firstAccount.profileId; _follow({follower: firstAccount, target: secondAccount}); path[1] = secondAccount.profileId; _follow({follower: secondAccount, target: thirdAccount}); return path; } function _buildPathWhereOriginalPublisherDoesNotFollowFirstNode( uint256 degrees ) internal returns (uint256[] memory) { uint256[] memory path = new uint256[](degrees - 1); if (degrees == 1) { return path; } if (degrees == 2) { _follow({follower: firstAccount, target: currentPublisher}); path[0] = firstAccount.profileId; } if (degrees == 3) { _follow({follower: firstAccount, target: secondAccount}); path[0] = firstAccount.profileId; _follow({follower: secondAccount, target: currentPublisher}); path[1] = secondAccount.profileId; } return path; } function _buildPathWhereLastPathNodeDoesNotFollowCurrentPublisher( uint256 degrees ) internal returns (uint256[] memory) { uint256[] memory path = new uint256[](degrees - 1); if (degrees == 1) { return path; } if (degrees == 2) { _follow({follower: originalPublisher, target: firstAccount}); path[0] = firstAccount.profileId; } if (degrees == 3) { _follow({follower: originalPublisher, target: firstAccount}); path[0] = firstAccount.profileId; _follow({follower: firstAccount, target: secondAccount}); path[1] = secondAccount.profileId; } return path; } function _follow(TestAccount memory follower, TestAccount memory target) internal { vm.prank(follower.owner); hub.follow(follower.profileId, _toUint256Array(target.profileId), _toUint256Array(0), _toBytesArray('')); } }