feat: Block feature impl

This commit is contained in:
donosonaumczuk
2022-11-15 18:43:55 +00:00
parent 14f4b4a1d9
commit a43cd04dd7
9 changed files with 71 additions and 9 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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
}

View File

@@ -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.
*

View File

@@ -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.
*

View File

@@ -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.

View File

@@ -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.
*

View File

@@ -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.

View File

@@ -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,