Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code improvements and fixes #72

Draft
wants to merge 39 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
20139fd
misc: TODO solved - isImmutable storage replaced by _contentURISnapsh…
donosonaumczuk Jan 7, 2025
8eab952
fix: Missing rule selector validation on primitives added
donosonaumczuk Jan 9, 2025
6f7274f
misc: compiler bump to 0.8.28 - pragma bump to ^0.8.26 - preparing fo…
donosonaumczuk Jan 9, 2025
f3e80a0
misc: Custom Errors added on every revert case
donosonaumczuk Jan 9, 2025
f4f8751
misc: add fuzzing, via_ir and zkSync compilation to foundry.toml
vicnaum Jan 8, 2025
f435b95
misc: commented out all lines that caused stack-too-deep
vicnaum Jan 9, 2025
5873156
misc: Namespaces and Graph compile without IR
vicnaum Jan 9, 2025
706a0aa
misc: Rule Based Feed and Group made to compile without IR
vicnaum Jan 10, 2025
0ba5dd1
misc: RuleBasePrimitive made to compile without IR
vicnaum Jan 10, 2025
c5a740a
misc: Feed made to compile without IR
vicnaum Jan 10, 2025
af083d7
misc: MigrationFeed made to compile without IR
vicnaum Jan 10, 2025
0aad9f2
misc: LensFactory made to compile without IR
vicnaum Jan 10, 2025
cc4fe7e
misc: LensFactory tests made to compile without IR
vicnaum Jan 10, 2025
a157a84
Merge pull request #73 from lens-protocol/code-changes-compile-withou…
donosonaumczuk Jan 10, 2025
cef1882
misc: Namespace code updated to give better revert reasons for non-ex…
vicnaum Jan 11, 2025
8198261
test: coverage skipper added to deploy script
vicnaum Jan 11, 2025
e6ed308
test: coverage scripts added
vicnaum Jan 11, 2025
0da8a99
misc: added checks for address(0) to GraphCore
vicnaum Jan 14, 2025
20e2200
fix: MigrationGraph fixed
vicnaum Jan 14, 2025
283d303
fix: MigrationFeed extradata saving fix
vicnaum Jan 14, 2025
f4b42d5
misc: Better error throwing during enable/disable rule selectors
donosonaumczuk Jan 14, 2025
738c509
misc: SkipTokenGate refactored to a more generic SkipGate permission
donosonaumczuk Jan 14, 2025
dfd8e4b
fix: Added missing _processEntityRulesChanges override on Feed and Graph
donosonaumczuk Jan 14, 2025
a936313
misc: getUsernameTokenId modifier from view to pure
donosonaumczuk Jan 14, 2025
df046e9
misc: add TippingPostAction to deployment script
vicnaum Jan 15, 2025
fdbd1c7
fix: Post Rules events emitters added
vicnaum Jan 16, 2025
1a5ce2a
fix: Follow Rules events emitters added
vicnaum Jan 16, 2025
dd7919c
fix: editPost fixed (core call missing)
vicnaum Jan 16, 2025
b862efd
misc: MigrationFeed changed to have forceChecks always
vicnaum Jan 16, 2025
404b461
fix: Rule processing main for-loop logic fixed - Call with empty para…
donosonaumczuk Jan 16, 2025
3984082
misc: bool return from call renamed to callSucceeded for better code …
donosonaumczuk Jan 16, 2025
036baf8
misc: IAccessControl incomplete natspec comment completed
donosonaumczuk Jan 16, 2025
a7dce24
fix: Access Control verification function now calls with address(this…
donosonaumczuk Jan 16, 2025
3ce2ff1
misc: Diff error constants and validations moved up on RoleBasedAcces…
donosonaumczuk Jan 16, 2025
b1652f7
misc: proxy__ prefix added to BeaconProxy functions
donosonaumczuk Jan 17, 2025
95176ad
fix: make all the rule-related hooks abstract and required to override
vicnaum Jan 17, 2025
7395e05
feat: handledcall and handledsafecall added to CallLib
donosonaumczuk Jan 17, 2025
a0bb896
fix: properly retrieve selector from ProxyAdmin call's calldata
donosonaumczuk Jan 17, 2025
96c48f6
fix: Use handled flavour for safecall and call when needed
donosonaumczuk Jan 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,5 @@ dist
deployment-zk/*
!deployment-zk/lensSepoliaTestnet/
cache_forge/solidity-files-cache.json

lcov.info
5 changes: 3 additions & 2 deletions contracts/actions/account/TippingAccountAction.sol
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {BaseAccountAction} from "contracts/actions/account/base/BaseAccountAction.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {KeyValue} from "contracts/core/types/Types.sol";
import {MetadataBased} from "contracts/core/base/MetadataBased.sol";
import {Errors} from "contracts/core/types/Errors.sol";

contract TippingAccountAction is BaseAccountAction, MetadataBased {
using SafeERC20 for IERC20;
Expand Down Expand Up @@ -40,7 +41,7 @@ contract TippingAccountAction is BaseAccountAction, MetadataBased {
erc20Token = abi.decode(params[i].value, (address));
}
}
require(tipAmount > 0);
require(tipAmount > 0, Errors.InvalidParameter());
IERC20(erc20Token).safeTransferFrom(originalMsgSender, account, tipAmount);
return "";
}
Expand Down
5 changes: 3 additions & 2 deletions contracts/actions/account/base/BaseAccountAction.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {KeyValue} from "contracts/core/types/Types.sol";
import {BaseAction} from "contracts/actions/base/BaseAction.sol";
import {IAccountAction} from "contracts/extensions/actions/ActionHub.sol";
import {Errors} from "contracts/core/types/Errors.sol";

abstract contract BaseAccountAction is BaseAction, IAccountAction {
constructor(address actionHub) BaseAction(actionHub) {}
Expand Down Expand Up @@ -55,6 +56,6 @@ abstract contract BaseAccountAction is BaseAction, IAccountAction {
bool, /* isDisabled */
KeyValue[] calldata /* params */
) internal virtual returns (bytes memory) {
revert();
revert Errors.NotImplemented();
}
}
9 changes: 5 additions & 4 deletions contracts/actions/base/BaseAction.sol
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {UNIVERSAL_ACTION_MAGIC_VALUE} from "contracts/extensions/actions/ActionHub.sol";
import {Errors} from "contracts/core/types/Errors.sol";

abstract contract BaseAction {
address immutable ACTION_HUB;
Expand All @@ -11,7 +12,7 @@ abstract contract BaseAction {
bytes32 constant STORAGE__ACTION_CONFIGURED = 0x852bead036b7ef35b8026346140cc688bafe817a6c3491812e6d994b1bcda6d9;

modifier onlyActionHub() {
require(msg.sender == ACTION_HUB);
require(msg.sender == ACTION_HUB, Errors.InvalidMsgSender());
_;
}

Expand All @@ -24,8 +25,8 @@ abstract contract BaseAction {
assembly {
configured := sload(STORAGE__ACTION_CONFIGURED)
}
require(!configured);
require(originalMsgSender == address(0));
require(!configured, Errors.RedundantStateChange());
require(originalMsgSender == address(0), Errors.InvalidParameter());
assembly {
sstore(STORAGE__ACTION_CONFIGURED, 1)
}
Expand Down
5 changes: 3 additions & 2 deletions contracts/actions/post/TippingPostAction.sol
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {BasePostAction} from "contracts/actions/post/base/BasePostAction.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {KeyValue} from "contracts/core/types/Types.sol";
import {IFeed} from "contracts/core/interfaces/IFeed.sol";
import {MetadataBased} from "contracts/core/base/MetadataBased.sol";
import {Errors} from "contracts/core/types/Errors.sol";

contract TippingPostAction is BasePostAction, MetadataBased {
using SafeERC20 for IERC20;
Expand Down Expand Up @@ -41,7 +42,7 @@ contract TippingPostAction is BasePostAction, MetadataBased {
erc20Token = abi.decode(params[i].value, (address));
}
}
require(tipAmount > 0);
require(tipAmount > 0, Errors.InvalidParameter());
address account = IFeed(feed).getPostAuthor(postId);
IERC20(erc20Token).safeTransferFrom(originalMsgSender, account, tipAmount);
return abi.encode(account);
Expand Down
5 changes: 3 additions & 2 deletions contracts/actions/post/base/BasePostAction.sol
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {KeyValue} from "contracts/core/types/Types.sol";
import {BaseAction} from "contracts/actions/base/BaseAction.sol";
import {IPostAction} from "contracts/extensions/actions/ActionHub.sol";
import {Errors} from "contracts/core/types/Errors.sol";

abstract contract BasePostAction is BaseAction, IPostAction {
constructor(address actionHub) BaseAction(actionHub) {}
Expand Down Expand Up @@ -58,6 +59,6 @@ abstract contract BasePostAction is BaseAction, IPostAction {
bool, /* isDisabled */
KeyValue[] calldata /* params */
) internal virtual returns (bytes memory) {
revert();
revert Errors.NotImplemented();
}
}
2 changes: 1 addition & 1 deletion contracts/actions/post/collect/IERC7572.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
// As appears in https://eips.ethereum.org/EIPS/eip-7572

pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

/**
* This specification standardizes contractURI() to return contract-level metadata. This is useful for dapps and
Expand Down
2 changes: 1 addition & 1 deletion contracts/actions/post/collect/ISimpleCollectAction.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {IPostAction} from "contracts/extensions/actions/ActionHub.sol";

Expand Down
15 changes: 7 additions & 8 deletions contracts/actions/post/collect/LensCollectedPost.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import "contracts/core/base/LensERC721.sol";
import {IERC7572} from "contracts/actions/post/collect/IERC7572.sol";
import {IFeed} from "contracts/core/interfaces/IFeed.sol";
import {ITokenURIProvider} from "contracts/core/interfaces/ITokenURIProvider.sol";
import {Errors} from "contracts/core/types/Errors.sol";

/**
* @notice A contract that represents a Lens Collected Post.
Expand All @@ -24,16 +25,14 @@ contract LensCollectedPost is LensERC721, IERC7572 {
string internal _contractURI;
address internal immutable _feed;
uint256 internal immutable _postId;
bool internal immutable _isImmutable; // TODO: This can be replaced with bytes(_contentURISnapshot).length
address internal immutable _collectAction;

constructor(address feed, uint256 postId, bool isImmutable) {
LensERC721._initialize("Lens Collected Post", "LCP", ITokenURIProvider(address(0)));
string memory contentURI = IFeed(feed).getPost(postId).contentURI;
require(bytes(contentURI).length > 0, "Post content URI is empty");
require(bytes(contentURI).length > 0, Errors.InvalidParameter());
_feed = feed;
_postId = postId;
_isImmutable = isImmutable;
_contractURI = contentURI;
_collectAction = msg.sender;
if (isImmutable) {
Expand All @@ -43,7 +42,7 @@ contract LensCollectedPost is LensERC721, IERC7572 {
}

function mint(address to, uint256 tokenId) external {
require(msg.sender == _collectAction, "Only CollectAction can mint");
require(msg.sender == _collectAction, Errors.InvalidMsgSender());
_mint(to, tokenId);
}

Expand All @@ -54,12 +53,12 @@ contract LensCollectedPost is LensERC721, IERC7572 {
}

function tokenURI(uint256 /*tokenId*/ ) public view override returns (string memory) {
if (_isImmutable) {
if (bytes(_contentURISnapshot).length > 0) {
return _contentURISnapshot;
} else {
string memory contentURI = IFeed(_feed).getPost(_postId).contentURI;
// TODO: If content was deleted - should we fail or return empty string?
require(bytes(contentURI).length > 0);
require(bytes(contentURI).length > 0, Errors.DoesNotExist());
return contentURI;
}
}
Expand All @@ -69,6 +68,6 @@ contract LensCollectedPost is LensERC721, IERC7572 {
// Disabling integrated LensERC721 tokenURIProvider
// TODO: Is this approach more favorable than deploying the LensCollectedPostTokenURIProvider over and over?
function _beforeTokenURIProviderSet(ITokenURIProvider /* tokenURIProvider */ ) internal pure override {
revert();
revert Errors.NotImplemented();
}
}
35 changes: 17 additions & 18 deletions contracts/actions/post/collect/SimpleCollectAction.sol
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {ISimpleCollectAction, CollectActionData} from "contracts/actions/post/collect/ISimpleCollectAction.sol";
import {IFeed} from "contracts/core/interfaces/IFeed.sol";
import {IGraph} from "contracts/core/interfaces/IGraph.sol";

import {LensCollectedPost} from "contracts/actions/post/collect/LensCollectedPost.sol";
import {BasePostAction} from "contracts/actions/post/base/BasePostAction.sol";

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {MetadataBased} from "contracts/core/base/MetadataBased.sol";
import {KeyValue} from "contracts/core/types/Types.sol";
import {Errors} from "contracts/core/types/Errors.sol";

contract SimpleCollectAction is ISimpleCollectAction, BasePostAction, MetadataBased {
using SafeERC20 for IERC20;
Expand Down Expand Up @@ -107,7 +106,7 @@ contract SimpleCollectAction is ISimpleCollectAction, BasePostAction, MetadataBa
// Editing existing collect action config
if (storedData.isImmutable) {
// TODO: Should we have two different bools? isImmutableConfig & isImmutableContentURI?
revert("Cannot edit immutable collect");
revert Errors.Immutable();
} else {
storedData.amount = configData.amount;
storedData.collectLimit = configData.collectLimit;
Expand Down Expand Up @@ -152,9 +151,9 @@ contract SimpleCollectAction is ISimpleCollectAction, BasePostAction, MetadataBa
_validateSenderIsAuthor(originalMsgSender, feed, postId);
CollectActionData storage storedData = $collectDataStorage().collectData[feed][postId];
// We don't check for existence of collect before disabling, because it might be useful to disable it initially
// require(storedData.collectionAddress != address(0), "Collect not configured for this post");
require(!storedData.isImmutable, "Cannot modify immutable collect");
require(storedData.isDisabled != isDisabled, "Already in desired state");
// require(storedData.collectionAddress != address(0), Errors.DoesNotExist());
require(!storedData.isImmutable, Errors.Immutable());
require(storedData.isDisabled != isDisabled, Errors.RedundantStateChange());
storedData.isDisabled = isDisabled;
return abi.encode(isDisabled);
}
Expand All @@ -165,18 +164,18 @@ contract SimpleCollectAction is ISimpleCollectAction, BasePostAction, MetadataBa

function _validateSenderIsAuthor(address sender, address feed, uint256 postId) internal virtual {
if (sender != IFeed(feed).getPostAuthor(postId)) {
revert("Sender is not the author");
revert Errors.InvalidMsgSender();
}
}

function _validateConfigureParams(CollectActionConfigureParams memory configData) internal virtual {
if (configData.amount == 0) {
require(configData.token == address(0), "Invalid token");
require(configData.token == address(0), Errors.InvalidParameter());
} else {
require(configData.token != address(0), "Invalid token");
require(configData.token != address(0), Errors.InvalidParameter());
}
if (configData.endTimestamp != 0 && configData.endTimestamp < block.timestamp) {
revert("Invalid params");
revert Errors.InvalidParameter();
}
if (configData.followerOnlyGraph != address(0)) {
// Check if the Graph supports isFollowing() interface with two random addresses
Expand Down Expand Up @@ -209,24 +208,24 @@ contract SimpleCollectAction is ISimpleCollectAction, BasePostAction, MetadataBa
) internal virtual {
CollectActionData storage data = $collectDataStorage().collectData[feed][postId];

require(data.collectionAddress != address(0), "Collect not configured for this post");
require(data.collectionAddress != address(0), Errors.DoesNotExist());

if (data.endTimestamp != 0 && block.timestamp > data.endTimestamp) {
revert("Collect expired");
revert Errors.Expired();
}

if (data.collectLimit != 0 && data.currentCollects + 1 > data.collectLimit) {
revert("Collect limit exceeded");
revert Errors.LimitReached();
}

if (expectedParams.amount != data.amount || expectedParams.token != data.token) {
revert("Invalid expected amount and/or token");
revert Errors.InvalidParameter();
}

if (data.followerOnlyGraph != address(0)) {
require(
IGraph(data.followerOnlyGraph).isFollowing(originalMsgSender, IFeed(feed).getPostAuthor(postId)),
"Not following"
Errors.NotFollowing()
);
}

Expand All @@ -236,12 +235,12 @@ contract SimpleCollectAction is ISimpleCollectAction, BasePostAction, MetadataBa
require(
keccak256(bytes(contentURI))
== keccak256(bytes(LensCollectedPost(data.collectionAddress).tokenURI(data.currentCollects))),
"Invalid content URI"
Errors.InvalidParameter()
);
}

if (data.isDisabled) {
revert("Collect is disabled");
revert Errors.Disabled();
}
}

Expand Down
2 changes: 1 addition & 1 deletion contracts/core/access/AccessControlled.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.0;
pragma solidity ^0.8.26;

import {IAccessControl} from "contracts/core/interfaces/IAccessControl.sol";
import {AccessControlLib} from "contracts/core/libraries/AccessControlLib.sol";
Expand Down
6 changes: 4 additions & 2 deletions contracts/core/access/Ownable.sol
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: UNLICENSED
// Copyright (C) 2024 Lens Labs. All Rights Reserved.
pragma solidity ^0.8.12;
pragma solidity ^0.8.26;

import {Errors} from "contracts/core/types/Errors.sol";

abstract contract Ownable {
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
Expand All @@ -19,7 +21,7 @@ abstract contract Ownable {
}

modifier onlyOwner() {
require(msg.sender == $ownableStorage().owner);
require(msg.sender == $ownableStorage().owner, Errors.InvalidMsgSender());
_;
}

Expand Down
Loading
Loading