Platform: Code4rena
Start Date: 10/02/2022
Pot Size: $100,000 USDC
Total HM: 13
Participants: 21
Period: 7 days
Judge: leastwood
Total Solo HM: 10
Id: 85
League: ETH
Rank: 8/21
Findings: 3
Award: $2,781.75
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: cmichel
Also found by: csanuragjain, gzeon
User will pay lesser Collect Module fees and the difference will be borne by Publication owner. This way Publication owner will always be on loss
Attacker can also make this a business in which he can collect victim nft at discounted price and then sell that NFT to other users using transfer function
User A create a new post publication using createPost in PublishingLogic.sol#L122
User B wants to collect the post publication by User A. He call collect function on InteractionLogic.sol#L97
Collect function will call processCollect on Collect Module and asks User B for fees X (Treasury fees + User A fees)
User B does not approve and transaction fails
Now to reduce this fees X, User B simply creates a mirror for User A publication using createMirror function at PublishingLogic.sol#L247
A new mirror gets created pointing to User A publication and owned by User B
User B simply call collect function on InteractionLogic.sol#L97
This time again processCollect on Collect Module is ran but since the call is coming from mirror, a referral fees is calculated for mirror owner
In our case mirror owner is User B so final fees becomes ((Treasury fees + User B referral fees + (User A fees -User B referral fees) )
So In this case User B gets a discount of User B referral fees and User A incur that lose
User should not be allowed to collect using a mirror owned by his own profile. Although there is a bypass in which User can create mirror to victim publication from one wallet and user other wallet to make the collect
#0 - oneski
2022-02-16T20:15:27Z
decline, this functionality is as designed.
User A by setting referral fees understands that their per Publication fees are minus the referral rate. Additional collect modules can be built blocking bad referral behavior .
#1 - 0xleastwood
2022-05-04T17:57:05Z
I believe this is a duplicate of #20 which is pending the sponsor's reply.
8 Low issue identified as depicted below:
Remediation: Change the _setGovernance like below:
function _setGovernance(address newGovernance) internal { require(newGovernance!=address(0), "Incorrect Governance"); address prevGovernance = _governance; _governance = newGovernance; emit Events.GovernanceSet(msg.sender, prevGovernance, newGovernance, block.timestamp); }
Remediation: If followModule is changed using setFollowModule then new followModule should run on existing followers
Remediation: Similar to follow function, implement checks in comment, publication, mirror creation to see if target profile exists/active
Remediation: Change all collect module treasury fees calculation to below (Like change LimitedTimedFeeCollectModule.sol#L159 to below):
address treasury; uint256 treasuryAmount; // Avoids stack too deep { uint16 treasuryFee; (treasury, treasuryFee) = _treasuryData(); treasuryAmount = (amount * treasuryFee) / BPS_MAX; }
Remediation: Change the formula to:
if (newTreasuryFee > BPS_MAX / 2) revert Errors.InitParamsInvalid();
bytes4 firstBytes = bytes4(bytes(handle)); which means only first 4 bytes are considered which is "aaaa" in both cases string memory followNFTSymbol = string( abi.encodePacked(firstBytes, Constants.FOLLOW_NFT_SYMBOL_SUFFIX) );
Remediation:
Remediation: Remove MIT license and add AGPL-3.0-only. Modify LensMultiState.sol#L1 to below:
// SPDX-License-Identifier: AGPL-3.0-only
Remediation: Move all state changing functions to a contract
#0 - Zer0dot
2022-03-22T21:16:01Z
With respect to collecting from deleted profiles, we really leave this up to the UIs. The only "break" that occurs from deleted profiles and collecting is when attempting to collect from the mirror of a deleted profile, in which case user interfaces have the option to direct the transaction directly towards collecting the mirrored publication.
State changing functions in the library are a remediation to code size concerns, the MIT license is a leftover from the modified Pausable
contract, good catch! I believe the rest to be invalid.
In _createComment function of LensHub.sol#L881, use argument ++_profileById[vars.profileId].pubCount in call to PublishingLogic.createComment and remove the Line LensHub.sol#L887 as _profileById[vars.profileId].pubCount++; is no more required now
In mint function of CollectNFT.sol#L51, there is no need to store incremented value of _tokenIdCounter in local variable. Instead remove CollectNFT.sol#L51 and modify CollectNFT.sol#L52 to _mint(to, ++_tokenIdCounter);
In mint function of FollowNFT.sol#L68, there is no need to store incremented value of _tokenIdCounter in local variable. Instead remove FollowNFT.sol#L68 and modify FollowNFT.sol#L69 to _mint(to, ++_tokenIdCounter);
In collect module contract like LimitedFeeCollectModule.sol, both _processCollectWithReferral and _processCollect can be removed from all the collect module and placed into a single library which all collect modules can utilize
#0 - Zer0dot
2022-03-25T18:05:11Z