Lens Protocol V2 - Emmanuel's results

An open technology stack, builders can create social front-ends or integrate Lens social capabilities.

General Information

Platform: Code4rena

Start Date: 17/07/2023

Pot Size: $85,500 USDC

Total HM: 11

Participants: 26

Period: 14 days

Judge: Picodes

Total Solo HM: 1

Id: 263

League: ETH

Lens Protocol

Findings Distribution

Researcher Performance

Rank: 3/26

Findings: 5

Award: $7,481.06

QA:
grade-b

🌟 Selected for report: 0

πŸš€ Solo Findings: 0

Findings Information

🌟 Selected for report: MiloTruck

Also found by: Emmanuel

Labels

bug
2 (Med Risk)
satisfactory
duplicate-146

Awards

2660.5978 USDC - $2,660.60

External Links

Lines of code

https://github.com/code-423n4/2023-07-lens/blob/main/contracts/FollowNFT.sol#L480-L520

Vulnerability details

Impact

A user can follow multiple times, specifically by first following through LensHub#follow, which then calls FollowNFT#follow. After that, the user can call LensV2Migration#batchMigrateFollows if they had a pre-upgrade followNFT. Furthermore, they can repeat this process as many times as they have pre-upgrade NFTs accessible to them.

Proof of Concept

The FollowNFT#tryMigrate function does not verify if the profileId being migrated is already following.

A malicious user with a pre-upgrade FollowNFT can exploit this by first calling FollowNFT#follow through LensHub and then proceeding to migrate their FollowNFT.

As a result, this leads to double following, and in a scenario where everyone follows this pattern, a profile will end up with twice as many followers as it should have. However, these followers will only be backed by half the number of unique profiles due to the duplication.

Tools Used

Manual Review

Ensure that the followerProfileId in FollowNFT#tryMigrate is not following already. A similar check used in follow function can be used here:

if (_followTokenIdByFollowerProfileId[followerProfileId] != 0) {
    revert AlreadyFollowing();
}

Assessed type

Invalid Validation

#0 - c4-pre-sort

2023-08-03T16:34:48Z

141345 marked the issue as duplicate of #146

#1 - c4-judge

2023-08-28T15:56:26Z

Picodes marked the issue as satisfactory

Findings Information

🌟 Selected for report: juancito

Also found by: Emmanuel, evmboi32

Labels

2 (Med Risk)
partial-50
duplicate-106

Awards

798.1793 USDC - $798.18

External Links

Judge has assessed an item in Issue #112 as 2 risk. The relevant finding follows:

A profile can follow itself by receiving a pre-upgrade followNFT and then using the batchMigrateFollows function."

#0 - c4-judge

2023-08-28T16:10:22Z

Picodes marked the issue as duplicate of #106

#1 - c4-judge

2023-08-28T16:10:26Z

Picodes marked the issue as satisfactory

#2 - c4-judge

2023-09-03T16:58:00Z

Picodes marked the issue as partial-50

Findings Information

🌟 Selected for report: juancito

Also found by: Emmanuel

Labels

bug
2 (Med Risk)
disagree with severity
satisfactory
edited-by-warden
duplicate-104

Awards

2660.5978 USDC - $2,660.60

External Links

Lines of code

https://github.com/code-423n4/2023-07-lens/blob/main/contracts/misc/LensV2Migration.sol#L37 https://github.com/code-423n4/2023-07-lens/blob/main/contracts/FollowNFT.sol#L502

Vulnerability details

Impact

Adversary that possesses a followNFT that was minted before the upgrade, can send it to a target address that owns a particular profile and then execute the LensV2Migration#batchMigrateFollows function. By providing the necessary inputs such as the profileId, idOfProfileFollowed, and the transferred tokenId, the adversary successfully enforces the target profile to follow the specified profile.

This introduces several potential attacks:

  • An adversary can force any profile they wish to follow a particular profile.
  • The adversary can forcefully change the tokenId that an already migrated user or post-upgrade minter is registered with.
  • If a profile gets blocked, the user can refollow by accepting a pre-upgrade followNFT and then using the batchMigrateFollows function.
  • A profile can follow itself by receiving a pre-upgrade followNFT and then using the batchMigrateFollows function."

Proof of Concept

The tryMigrate function does not consider the fact that any address will be forced to be the ownerOf a tokenId if it gets sent that token. This is common to all NFTs. Alice cannot stop Bob from sending her his NFTs.

For follow tokens that were minted before the upgrade, the batchMigrateFollows which downstream calls the tryMigrate function, is used to re-register the profileId that owns those tokens and grant them functionalities equivalent to those of tokens minted after the upgrade.

As an owner of a pre-upgrade followNFT, you can forcefully register ANY address with your tokenId. This can be achieved by simply sending your followNFT to an address that owns a specific profileId and then calling the LensV2Migration#batchMigrateFollows function, providing that profileId, idOfProfileFollowed, and the tokenId you just transferred.

Here are the checks that tryMigrate does:

// Migrated FollowNFTs should have `originalFollowTimestamp` set
if (_followDataByFollowTokenId[followTokenId].originalFollowTimestamp != 0) {
    return 0; // Already migrated
}

if (_followedProfileId != idOfProfileFollowed) {
    revert Errors.InvalidParameter();
}

if (!_exists(followTokenId)) {
    return 0; // Doesn't exist
}

address followTokenOwner = ownerOf(followTokenId);

// ProfileNFT and FollowNFT should be in the same account
if (followerProfileOwner != followTokenOwner) {
    return 0; // Not holding both Profile & Follow NFTs together
}

If the tokenId has not been used in migration before, and the adversary's input parameters are valid, and the tokenId exists, the first three checks will pass. The last check ensures that the owner of the followTokenId is the same as the followerProfileOwner. Since the adversary can control the ownerOf a followTokenId (by sending it to any address they wish) and can also provide any profile as an input parameter, this check will pass. Consequently, it would lead to the registration of that profile as a follower of any profile the adversary desires.

Tools Used

Manual Review

I suggest allowing only the protocol or current owner of a followNFT to migrate his followNFT. Normal users should not be able to migrate another profile's followNFT unless with a signature. This way, if a malicious user sends his followNFT to another address, he won't be able to tryMigrate because he is not the current owner of the token, while the token recipient can tryMigrate at will.

Assessed type

Invalid Validation

#0 - vicnaum

2023-08-08T17:25:56Z

This is a valid issue and should be fixed before the upgrade. There are several similar issued in the duplicates section which we also confirm. This shouldn't be High because users assets are not at risk, it's rather a way of minting unexpected assets (and also all other duplicate issues are ranked as Medium).

#1 - c4-sponsor

2023-08-08T17:26:03Z

vicnaum marked the issue as disagree with severity

#2 - c4-judge

2023-08-28T16:00:34Z

Picodes changed the severity to 2 (Med Risk)

#3 - c4-judge

2023-08-28T16:00:40Z

Picodes marked the issue as primary issue

#4 - c4-judge

2023-08-28T16:05:57Z

Picodes marked issue #104 as primary and marked this issue as a duplicate of 104

#5 - c4-judge

2023-08-28T16:07:11Z

Picodes marked the issue as satisfactory

#6 - c4-judge

2023-08-28T16:09:12Z

Picodes marked the issue as not a duplicate

#7 - c4-judge

2023-08-28T16:09:18Z

Picodes changed the severity to QA (Quality Assurance)

#8 - c4-judge

2023-08-28T16:10:01Z

This previously downgraded issue has been upgraded by Picodes

#9 - c4-judge

2023-08-28T16:10:02Z

This previously downgraded issue has been upgraded by Picodes

#10 - c4-judge

2023-08-28T16:10:12Z

Picodes marked the issue as duplicate of #104

#11 - MiloTruck

2023-08-29T02:04:39Z

Hi @Picodes,

This isn't my issue but wouldn't it be fairer towards the warden if it was split into three with partial rewards?

The finding here has grouped all findings related to tryMigrate() under one bug, which is the function has missing checks. As seen below, it has correctly identified the potential impacts mentioned in #40 and #106 in point 3 and 4:

  • An adversary can force any profile they wish to follow a particular profile.
  • The adversary can forcefully change the tokenId that an already migrated user or post-upgrade minter is registered with.
  • If a profile gets blocked, the user can refollow by accepting a pre-upgrade followNFT and then using the batchMigrateFollows function.
  • A profile can follow itself by receiving a pre-upgrade followNFT and then using the batchMigrateFollows function."

Therefore, I think it would be fair for it to be split into three and duplicated to #40 and #106 as well, perhaps with partial rewards due to the lack of explanation for each root cause and mitigation.

The alternative would be to group all three findings together and duplicate them under this issue, but I don't think that's correct given that their mitigations are different.

Also, impact 2 seems to be an overlap of impact 1 and #146 (fixing either of these would fix impact 2 as well), so I don't think it should be separated into an individual finding.

Thanks!

#12 - 0xJuancito

2023-08-29T02:52:44Z

Hi @Picodes. As the author of both #104 and #106, I would like to point out the difference in root and mitigations for both issues, as demonstrated on their respective Coded POCs on each issue + the Recommended Mitigation Steps, making them independent.

As for #40 and #146 they are also independent issues as well, with their own root and mitigations.

#13 - Emedudu

2023-08-29T04:32:49Z

Hi @Picodes ,

This issue mentioned 4 different issues, as can be found under the impact section:

  1. An adversary can force any profile they wish to follow a particular profile.==issue 104
  2. The adversary can forcefully change the tokenId that an already migrated user or post-upgrade minter is registered with.(No other issue mentioned this)
  3. If a profile gets blocked, the user can refollow by accepting a pre-upgrade followNFT and then using the batchMigrateFollows function.==issue 40
  4. A profile can follow itself by receiving a pre-upgrade followNFT and then using the batchMigrateFollows function.==issue 106

Personally, I'm not sure of the best way to judge this to be fair to all the wardens. If judges are allowed to split a finding, then this should probably be split into 4 findings.

  • the first should be a dup of issue 104
  • the second should be a separate finding
  • the third should be a dup of issue 40
  • the fourth should be a dup of issue 106

Thanks for your effort!

#14 - vicnaum

2023-08-30T15:53:42Z

Me and @donosonaumczuk also agree with splitting this into 4 separate issues as proposed above

#15 - Picodes

2023-09-03T17:12:09Z

So before the QA period, I had split this issue in 2: one dup of #104 and one dup of #106 (https://github.com/code-423n4/2023-07-lens-findings/issues/189).

To me, this report is primarily a duplicate of #104 as the same scenario is described. Then, it seems that the warden correctly identified scenarios #40 and #106 but doesn't go into details and doesn't provide a mitigation.

I see 3 bugs:

  • you can send and migrate someone without its consent: that is #104, #112 and covers scenario 2 of this report
  • when migrating yourself you could self-follow: that is #106 and is evocated by this issue but no mitigation / proper scenario is described so I'll correct to partial-50
  • you could bypass blocking: that is #40 and would be a different mitigation as well but is mentioned here. I'll create a duplicate of this report and mark it partial-50.

Then, for scenario 2 described here, it's another impact but not another issue in my opinion.

#16 - c4-judge

2023-09-03T17:12:42Z

Picodes marked the issue as not a duplicate

#17 - c4-judge

2023-09-03T17:12:47Z

Picodes changed the severity to QA (Quality Assurance)

#18 - c4-judge

2023-09-03T17:13:07Z

This previously downgraded issue has been upgraded by Picodes

#19 - c4-judge

2023-09-03T17:13:07Z

This previously downgraded issue has been upgraded by Picodes

#20 - c4-judge

2023-09-03T17:13:17Z

Picodes marked the issue as duplicate of #104

Findings Information

🌟 Selected for report: klau5

Also found by: Emmanuel

Labels

2 (Med Risk)
partial-50
duplicate-40

Awards

1330.2989 USDC - $1,330.30

External Links

Judge has assessed an item in Issue #112 as 2 risk. The relevant finding follows:

If a profile gets blocked, the user can refollow by accepting a pre-upgrade followNFT and then using the batchMigrateFollows function.

#0 - c4-judge

2023-09-03T17:13:55Z

Picodes marked the issue as duplicate of #40

#1 - c4-judge

2023-09-03T17:14:00Z

Picodes marked the issue as partial-50

Awards

31.3772 USDC - $31.38

Labels

bug
grade-b
QA (Quality Assurance)
Q-09

External Links

Low 001

Title

First follower is spending more gas

Impact

the first follower of a profile is spending more gas than subsequent followers. This will be unfair to them.

Proof of Concept

As we can see in FollowLib#_follow, if that profile has no followNFT, the first follower does the deployment, which will consume more gas.

function _follow()private returns (uint256){
    ...
    address followNFT = _profileToFollow.followNFT;
    if (followNFT == address(0)) {
        followNFT = _deployFollowNFT(idOfProfileToFollow);
        _profileToFollow.followNFT = followNFT;
    }
    ...
}

Tools Used

Manual Review

Recommendation

Consider deploying a followNFT at profile creation, so profile owner pays for that, while all followers spend same amount of gas to follow.

Low 002

Title

Non EOA is allowed to have a profile and follow other profiles

Impact

I think this is an issue because a user that wants a lot of followers can have many contract accounts follow him. Also, this would lead to bad UX in frontend as there will be a lot of fake profiles.

Given the peculiarity of this protocol, I consider this to be a valid issue.

Proof of Concept

Looking at LensHub#createProfile function, we can see that there is no check that prevents a non EOA from being the createProfileParams.to. This will allow minting of profiles to a non EOA account.

Tools Used

Manual Review

Recommendation

Consider adding an onlyEOA modifier to LensHub#createProfile

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax Β© 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter