lukso-network / lsp-smart-contracts

The reference implementation for universal profiles smart contracts
https://www.npmjs.com/package/@lukso/lsp-smart-contracts
Apache License 2.0
76 stars 50 forks source link

Sub - LSP26 follower system upgrade - private mode, remove follower, block/unblock #977

Closed Heisenburgirs closed 1 week ago

Heisenburgirs commented 1 week ago

Enhanced LSP26 Follower System

This PR introduces several new features to the LSP26 Follower System, providing users with greater control over their Universal Profile and social interactions. These enhancements aim to address common issues in social networks and create a more user-controlled environment.

New Features

1. Private Account Mode

Users can now set their account to private, requiring approval for new follow requests.

Example:

// Set account to private
followerSystem.setRequiresApproval(true);

// Approve a follow request
followerSystem.respondToFollowRequest(requesterAddress, true);

// Reject a follow request
followerSystem.respondToFollowRequest(requesterAddress, false);

2. Follower Removal

Account owners can now remove followers from their list.

Example:

// Remove a single follower
followerSystem.removeFollower(followerAddress);

// Remove multiple followers
followerSystem.removeFollowerBatch([follower1, follower2, follower3]);

3. Blocking

Users can block other accounts, preventing them from following and potentially interacting in other ways.

Example:

// Block a single address
followerSystem.blockAddress(addressToBlock);

// Block multiple addresses
followerSystem.blockBatch([address1, address2, address3]);

4. Unblocking

Blocked accounts can be unblocked, allowing normal interactions to resume.

Example:

// Unblock a single address
followerSystem.unblockAddress(addressToUnblock);

// Unblock multiple addresses
followerSystem.unblockBatch([address1, address2, address3]);

What was changed?

Here's list of new functions, internal functions, errors, constants, events and state variables introduced in this PR.

New functions introduced in the LSP26 interface & contract:

setRequiresApproval
respondToFollowRequest
respondToFollowRequestBatch
removeFollower
removeFollowerBatch
blockAddress
blockBatch
unblockAddress
unblockBatch
isApprovalRequired
isBlocked
pendingRequestCount
getPendingFollowRequests
blockedCount
getBlockedAddresses

New internal functions in the LSP26 contract:

_createFollowRequest
_addFollower
_removeFollower
_block
_unblock

New errors:

LSP26CannotRemoveSelf
LSP26CannotBlockSelf
LSP26BlockedFromFollowing
LSP26CannotUnblockSelf
LSP26UserBlocked
LSP26AlreadyBlocked
LSP26NotBlocked
LSP26NoFollowRequestPending
LSP26FollowRequestAlreadyPending

New constants:

_TYPEID_LSP26_REMOVE_FOLLOWER
_TYPEID_LSP26_BLOCK
_TYPEID_LSP26_UNBLOCK
_TYPEID_LSP26_REQUIRES_APPROVAL_SET
_TYPEID_LSP26_FOLLOW_REQUEST_SENT
_TYPEID_LSP26_FOLLOW_REQUEST_APPROVED
_TYPEID_LSP26_FOLLOW_REQUEST_REJECTED

New events:

RemovedFollower
Block
Unblock
RequiresApprovalSet
FollowRequestSent
FollowRequestApproved
FollowRequestRejected

New state variables:

_requiresApproval
_pendingFollowRequests
_blockedAddresses

Testing and Quality Assurance

We've run our new features through Remix. So far, everything's working as intended, which is great news. But we know how crucial thorough testing is in smart contract development.

Moving forward:

  1. LSP26FollowerSystem.test.ts needs to be updated to test new functionalities.
  2. There might be edge cases - or use cases - that we haven't thought of before. Needs more investigating.
  3. We need to ensure smooth integration with other LSP standards, particularly LSP1 to make sure nothing reverts.

We'd really appreciate input from the community on additional test scenarios. Fresh perspectives often uncover things we might have missed.

Rationale

These new features address several key issues:

  1. Spam Prevention: By allowing users to remove followers and block accounts, we reduce the impact of bot accounts and spam followers.

  2. Privacy Control: Private account mode gives users the ability to curate their follower list, ensuring that only approved accounts can follow them.

  3. Content Filtering: Blocking functionality can be used by dApps to filter content, allowing users to avoid seeing posts or interactions from blocked accounts.

  4. Enhanced Security: These features provide a foundation for more secure interactions. For example, blocking could be integrated with LSP1 to prevent unwanted token transfers or contract interactions from blocked Universal Profiles.

  5. Flexible Implementation: While these features provide powerful tools for user control, they are implemented in a way that allows dApps to utilize them flexibly, potentially creating more nuanced social experiences.

Impact

I believe these new features make the LSP26 Follower System more robust and open up possibilities for more nuanced use cases. The idea for these enhancements came from looking at the current implementation of LSP26 and seeing the issues that users faced with botted accounts or otherwise.

For example - as mentioned earlier - the blocking feature could be used in conjunction with token transfers. Imagine a scenario where you don't want to receive tokens from a specific Universal Profile - blocking could be integrated with LSP1 to prevent such unwanted transfers.

These additions give users more control over their social interactions within the LUKSO ecosystem. They're not just abstract concepts; they address practical concerns like spam followers, unwanted interactions, and privacy control.

While there's always room for further improvements, I think these changes represent a solid step towards a more user-centric and flexible follower system for Universal Profiles. They provide a foundation that developers can build upon to create safer and more customizable social experiences in their dApps.

Thanks for reading! Let me know your thoughts

Heisenburgirs commented 1 week ago

I had thought about integrating "Mute" functionality, but that can be done on dApp level.

Insofar as blocking is concerned - Farcaster has block lists public. We already see precedence of this implementation and it seems to work just fine. Hence why I don't think having block list be private is necessary. Blocking can also expand to other use-cases other than social interactions - stopping someone from sending you spam tokens, blocking interactions with exploited contracts etc.

It's also worth mentioning that I took the overall approach of the "follower system" from web2 social apps like Facebook, Instagram and Twitter - this is where we most of social interactions happen these days and these features are to be expected on any social platform.

CJ42 commented 1 week ago

Hi @Heisenburgirs thanks a lot for your contribution! šŸ™‚ šŸ™ŒšŸ» This looks definitely interesting.

There are a couple of feedbacks I would like to mention:

  1. When it comes to changing the core implementation of the standards + adding new features, it is better to discuss them first by opening a Feature Request issue. You can then link to your implementation in your fork, so that other people can see it and participate with their feedbacks.

Could you please open an issue first to discuss the code and the logic? :) We will then look over the implementation in your fork

  1. We cannot implement this change as it is. This is introducing new functions in the public interface and therefore the interface ID would change. So as a result, this is considered a breaking change.

  2. I think this implementation could be better as an extension of LSP26 (the same as we implement for tokens extensions in LSP7 + LSP8)

Heisenburgirs commented 1 week ago

opened an issue - https://github.com/lukso-network/lsp-smart-contracts/issues/979

frozeman commented 1 week ago

Also to add the current follower system is a singleton smart contract that is deployed and unchangeable. This means introducing a different one would mean that everyone needs to change, and abandon the old one. And re-follow.

What you are proposing here is more fitting to a connect/friend system.

Because here the one being connected with has a say.

While a follower system is for the one interested in the followed one. You can not prevent to be followed when you are public. the notion of private would be an illusion as your action can still be followed, hence why this makes more sense in a friend/connect system.

We planned to propose a friend/connect system as well. And we can use this as a basis for discussion and include you that discussion.

Heisenburgirs commented 4 days ago

Also to add the current follower system is a singleton smart contract that is deployed and unchangeable. This means introducing a different one would mean that everyone needs to change, and abandon the old one. And re-follow.

What you are proposing here is more fitting to a connect/friend system.

Because here the one being connected with has a say.

While a follower system is for the one interested in the followed one. You can not prevent to be followed when you are public. the notion of private would be an illusion as your action can still be followed, hence why this makes more sense in a friend/connect system.

We planned to propose a friend/connect system as well. And we can use this as a basis for discussion and include you that discussion.

I'm wondering how friend/connect/follower UX will look like. If someone opens up our dApp and sees "Follow" button, they immediately assume it to have same functionality as on other platforms.

Will there be "Follow" and "Add Friend" separately? How do regular users know what the difference is? Looking at it from regular joe's perspective who wants to have a profile and use SocialFi dApp, they might only be interested in connect/friend system, while "follower" system can be used for listening to account activities, for whatever reason - "Bob followed Alice", "Alice sent tokens" etc.