mirror of
https://github.com/lens-protocol/core.git
synced 2026-04-22 03:02:03 -04:00
feat: Block feature impl
This commit is contained in:
@@ -202,10 +202,7 @@ contract FollowNFT is HubRestricted, LensNFTBase, IFollowNFT {
|
||||
|
||||
function _follow(uint256 follower, uint256 followId) internal {
|
||||
_followIdByFollowerId[follower] = followId;
|
||||
_followDataByFollowId[followId].follower = FollowData(
|
||||
uint160(follower),
|
||||
uint96(block.timestamp)
|
||||
);
|
||||
_followDataByFollowId[followId] = FollowData(uint160(follower), uint96(block.timestamp));
|
||||
}
|
||||
|
||||
function _followWithUnwrappedToken(
|
||||
@@ -359,7 +356,7 @@ contract FollowNFT is HubRestricted, LensNFTBase, IFollowNFT {
|
||||
super.burn(followId);
|
||||
}
|
||||
|
||||
function block(uint256 follower, bool blocked) external onlyHub {
|
||||
function block(uint256 follower) external override onlyHub {
|
||||
uint256 followId = _followIdByFollowerId[follower];
|
||||
if (followId != 0) {
|
||||
_unfollow(follower, followId);
|
||||
|
||||
@@ -391,13 +391,12 @@ contract LensHub is LensNFTBase, VersionedInitializable, LensMultiState, LensHub
|
||||
return GeneralLib.followWithSig(vars);
|
||||
}
|
||||
|
||||
//TODO: Add to ILensHub
|
||||
function setBlockStatus(
|
||||
uint256 byProfile,
|
||||
uint256[] calldata profileIds,
|
||||
bool[] calldata blocked
|
||||
) external whenNotPaused {
|
||||
//
|
||||
) external override whenNotPaused {
|
||||
return GeneralLib.setBlockStatus(byProfile, profileIds, blocked);
|
||||
}
|
||||
|
||||
/// @inheritdoc ILensHub
|
||||
|
||||
@@ -32,4 +32,5 @@ abstract contract LensHubStorage {
|
||||
// new storage
|
||||
mapping(address => mapping(address => bool)) internal _delegatedExecutorApproval; // slot 25
|
||||
mapping(uint256 => string) internal _metadataByProfile; // slot 26
|
||||
mapping(uint256 => mapping(uint256 => bool)) internal _blockStatusByProfileByBlockee; // slot 27
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ interface IFollowNFT {
|
||||
*/
|
||||
function mint(address to) external returns (uint256);
|
||||
|
||||
function block(uint256 follower) external;
|
||||
|
||||
/**
|
||||
* @notice Delegates the caller's governance power to the given delegatee address.
|
||||
*
|
||||
|
||||
@@ -313,6 +313,12 @@ interface ILensHub {
|
||||
external
|
||||
returns (uint256[] memory);
|
||||
|
||||
function setBlockStatus(
|
||||
uint256 byProfile,
|
||||
uint256[] calldata profileIds,
|
||||
bool[] calldata blocked
|
||||
) external;
|
||||
|
||||
/**
|
||||
* @notice Collects a given publication, executing collect module logic and minting a collectNFT to the caller.
|
||||
*
|
||||
|
||||
@@ -33,7 +33,7 @@ uint256 constant GOVERNANCE_SLOT = 23;
|
||||
uint256 constant EMERGENCY_ADMIN_SLOT = 24;
|
||||
uint256 constant DELEGATED_EXECUTOR_APPROVAL_MAPPING_SLOT = 25;
|
||||
uint256 constant PROFILE_METADATA_MAPPING_SLOT = 26;
|
||||
uint256 constant PROFILE_BLOCKED_MAPPING_SLOT = 27;
|
||||
uint256 constant BLOCK_STATUS_MAPPING_SLOT = 27;
|
||||
uint256 constant NAME_SLOT_GT_31 = 0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563;
|
||||
|
||||
// We store the polygon chain ID and domain separator as constants to save gas.
|
||||
|
||||
@@ -362,6 +362,8 @@ library Events {
|
||||
uint48 followTimestamp
|
||||
);
|
||||
|
||||
event BlockStatusSet(uint256 indexed byProfile, uint256[] profileIds, bool[] blocked);
|
||||
|
||||
/**
|
||||
* @dev Emitted via callback when a followNFT is transferred.
|
||||
*
|
||||
|
||||
@@ -183,6 +183,15 @@ library GeneralLib {
|
||||
return InteractionHelpers.follow(follower, signer, vars.profileIds, vars.datas);
|
||||
}
|
||||
|
||||
function setBlockStatus(
|
||||
uint256 byProfile,
|
||||
uint256[] calldata profileIds,
|
||||
bool[] calldata blocked
|
||||
) external {
|
||||
GeneralHelpers.validateCallerIsOwnerOrDispatcherOrExecutor(byProfile);
|
||||
InteractionHelpers.setBlockStatus(byProfile, profileIds, blocked);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Collects the given publication, executing the necessary logic and module call before minting the
|
||||
* collect NFT to the collector.
|
||||
|
||||
@@ -105,6 +105,52 @@ library InteractionHelpers {
|
||||
return tokenIds;
|
||||
}
|
||||
|
||||
function setBlockStatus(
|
||||
uint256 byProfile,
|
||||
uint256[] calldata profileIds,
|
||||
bool[] calldata blocked
|
||||
) external {
|
||||
if (profileIds.length != blocked.length) {
|
||||
revert Errors.ArrayMismatch();
|
||||
}
|
||||
uint256 blockStatusByProfileSlot;
|
||||
// Calculates the slot of the block status internal mapping once accessed by `byProfile`.
|
||||
// i.e. the slot of `_blockStatusByProfileByBlockee[byProfile]`
|
||||
assembly {
|
||||
mstore(0, byProfile)
|
||||
mstore(32, BLOCK_STATUS_MAPPING_SLOT)
|
||||
blockStatusByProfileSlot := keccak256(0, 64)
|
||||
}
|
||||
address followNFT;
|
||||
// Loads the Follow NFT address from storage.
|
||||
// i.e. `followNFT = _profileById[byProfile].followNFT;`
|
||||
assembly {
|
||||
mstore(0, byProfile)
|
||||
mstore(32, PROFILE_BY_ID_MAPPING_SLOT)
|
||||
followNFT := sload(add(keccak256(0, 64), PROFILE_FOLLOW_NFT_OFFSET))
|
||||
}
|
||||
uint256 i;
|
||||
uint256 profileId;
|
||||
bool blockStatus;
|
||||
while (i < profileIds.length) {
|
||||
profileId = profileIds[i];
|
||||
if (followNFT != address(0) && (blockStatus = blocked[i])) {
|
||||
IFollowNFT(followNFT).block(profileId);
|
||||
}
|
||||
// Stores the block status.
|
||||
// i.e. `_blockStatusByProfileByBlockee[byProfile][profileId] = blockStatus;`
|
||||
assembly {
|
||||
mstore(0, profileId)
|
||||
mstore(32, blockStatusByProfileSlot)
|
||||
sstore(keccak256(0, 64), blockStatus)
|
||||
}
|
||||
unchecked {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
emit Events.BlockStatusSet(byProfile, profileIds, blocked);
|
||||
}
|
||||
|
||||
function collect(
|
||||
address collector,
|
||||
address delegatedExecutor,
|
||||
|
||||
Reference in New Issue
Block a user