mirror of
https://github.com/lens-protocol/core.git
synced 2026-04-22 03:02:03 -04:00
Merge pull request #77 from lens-protocol/test/act
misc: Act tests added
This commit is contained in:
@@ -20,10 +20,6 @@ library ActionLib {
|
||||
byProfile: publicationActionParams.publicationActedProfileId
|
||||
});
|
||||
|
||||
if (publicationActionParams.publicationActedId == 0) {
|
||||
revert Errors.PublicationDoesNotExist();
|
||||
}
|
||||
|
||||
Types.Publication storage _actedOnPublication = StorageLib.getPublication(
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId
|
||||
@@ -32,12 +28,9 @@ library ActionLib {
|
||||
address actionModuleAddress = publicationActionParams.actionModuleAddress;
|
||||
uint256 actionModuleId = StorageLib.actionModuleWhitelistData()[actionModuleAddress].id;
|
||||
|
||||
if (actionModuleId == 0) {
|
||||
revert Errors.ActionNotAllowed();
|
||||
}
|
||||
|
||||
if (!_isActionAllowed(_actedOnPublication, actionModuleId)) {
|
||||
if (!_isActionEnabled(_actedOnPublication, actionModuleId)) {
|
||||
// This will also revert for:
|
||||
// - Non-existent action modules
|
||||
// - Non-existent publications
|
||||
// - Legacy V1 publications
|
||||
// Because the storage will be empty.
|
||||
@@ -69,8 +62,14 @@ library ActionLib {
|
||||
return actionModuleReturnData;
|
||||
}
|
||||
|
||||
function _isActionAllowed(Types.Publication storage _publication, uint256 actionId) private view returns (bool) {
|
||||
uint256 actionIdBitmapMask = 1 << (actionId - 1);
|
||||
return actionIdBitmapMask & _publication.actionModulesBitmap != 0;
|
||||
function _isActionEnabled(
|
||||
Types.Publication storage _publication,
|
||||
uint256 actionModuleId
|
||||
) private view returns (bool) {
|
||||
if (actionModuleId == 0) {
|
||||
return false;
|
||||
}
|
||||
uint256 actionModuleIdBitmapMask = 1 << (actionModuleId - 1);
|
||||
return actionModuleIdBitmapMask & _publication.actionModulesBitmap != 0;
|
||||
}
|
||||
}
|
||||
|
||||
Submodule lib/forge-std updated: b971f66b84...73d44ec7d1
208
test/ActTest.t.sol
Normal file
208
test/ActTest.t.sol
Normal file
@@ -0,0 +1,208 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.13;
|
||||
|
||||
import 'test/base/BaseTest.t.sol';
|
||||
import 'test/MetaTxNegatives.t.sol';
|
||||
import {ILensHub} from 'contracts/interfaces/ILensHub.sol';
|
||||
import {Types} from 'contracts/libraries/constants/Types.sol';
|
||||
import {Events} from 'contracts/libraries/constants/Events.sol';
|
||||
|
||||
contract ActTest is BaseTest {
|
||||
TestAccount actor;
|
||||
Types.PublicationActionParams defaultPubActionParams;
|
||||
|
||||
function setUp() public virtual override {
|
||||
super.setUp();
|
||||
actor = _loadAccountAs('ACTOR');
|
||||
defaultPubActionParams = _getDefaultPublicationActionParams();
|
||||
defaultPubActionParams.actorProfileId = actor.profileId;
|
||||
}
|
||||
|
||||
// Negatives
|
||||
function testCannotAct_ifNonExistingPublication(uint256 nonexistentPubId) public {
|
||||
vm.assume(nonexistentPubId != defaultPub.pubId);
|
||||
defaultPubActionParams.publicationActedId = nonexistentPubId;
|
||||
|
||||
vm.expectRevert(Errors.ActionNotAllowed.selector);
|
||||
|
||||
_act(actor.ownerPk, defaultPubActionParams);
|
||||
}
|
||||
|
||||
function testCannotAct_ifActionModuleNotEnabledForPublication(address notEnabledActionModule) public {
|
||||
vm.assume(notEnabledActionModule != address(mockActionModule));
|
||||
|
||||
defaultPubActionParams.actionModuleAddress = notEnabledActionModule;
|
||||
|
||||
vm.expectRevert(Errors.ActionNotAllowed.selector);
|
||||
|
||||
_act(actor.ownerPk, defaultPubActionParams);
|
||||
}
|
||||
|
||||
function testCannotAct_ifProtocolIsPaused() public {
|
||||
vm.prank(governance);
|
||||
hub.setState(Types.ProtocolState.Paused);
|
||||
|
||||
vm.expectRevert(Errors.Paused.selector);
|
||||
_act(actor.ownerPk, defaultPubActionParams);
|
||||
}
|
||||
|
||||
function testCannotAct_onMirrors() public {
|
||||
Types.MirrorParams memory mirrorParams = _getDefaultMirrorParams();
|
||||
vm.prank(defaultAccount.owner);
|
||||
uint256 mirrorPubId = hub.mirror(mirrorParams);
|
||||
|
||||
defaultPubActionParams.publicationActedId = mirrorPubId;
|
||||
|
||||
vm.expectRevert(Errors.ActionNotAllowed.selector);
|
||||
_act(actor.ownerPk, defaultPubActionParams);
|
||||
}
|
||||
|
||||
// Scenarios
|
||||
|
||||
function testAct() public {
|
||||
vm.expectEmit(true, true, true, true, address(hub));
|
||||
emit Events.Acted(defaultPubActionParams, abi.encode(true), block.timestamp);
|
||||
|
||||
Types.ProcessActionParams memory processActionParams = Types.ProcessActionParams({
|
||||
publicationActedProfileId: defaultPubActionParams.publicationActedProfileId,
|
||||
publicationActedId: defaultPubActionParams.publicationActedId,
|
||||
actorProfileId: defaultPubActionParams.actorProfileId,
|
||||
actorProfileOwner: actor.owner,
|
||||
transactionExecutor: actor.owner,
|
||||
referrerProfileIds: defaultPubActionParams.referrerProfileIds,
|
||||
referrerPubIds: defaultPubActionParams.referrerPubIds,
|
||||
referrerPubTypes: _emptyPubTypesArray(),
|
||||
actionModuleData: defaultPubActionParams.actionModuleData
|
||||
});
|
||||
|
||||
vm.expectCall(
|
||||
address(mockActionModule),
|
||||
abi.encodeWithSelector(mockActionModule.processPublicationAction.selector, (processActionParams))
|
||||
);
|
||||
|
||||
_act(actor.ownerPk, defaultPubActionParams);
|
||||
}
|
||||
|
||||
function testAct_onComment() public {
|
||||
Types.CommentParams memory commentParams = _getDefaultCommentParams();
|
||||
vm.prank(defaultAccount.owner);
|
||||
uint256 commentPubId = hub.comment(commentParams);
|
||||
|
||||
defaultPubActionParams.publicationActedId = commentPubId;
|
||||
testAct();
|
||||
}
|
||||
|
||||
function testAct_onQuote() public {
|
||||
Types.QuoteParams memory quoteParams = _getDefaultQuoteParams();
|
||||
vm.prank(defaultAccount.owner);
|
||||
uint256 quotePubId = hub.quote(quoteParams);
|
||||
|
||||
defaultPubActionParams.publicationActedId = quotePubId;
|
||||
testAct();
|
||||
}
|
||||
|
||||
function testCanAct_evenIfActionWasUnwhitelisted() public {
|
||||
vm.prank(governance);
|
||||
hub.whitelistActionModule(defaultPubActionParams.actionModuleAddress, false);
|
||||
|
||||
testAct();
|
||||
}
|
||||
|
||||
function testCanAct_evenIfPublishingPaused() public {
|
||||
vm.prank(governance);
|
||||
hub.setState(Types.ProtocolState.PublishingPaused);
|
||||
|
||||
testAct();
|
||||
}
|
||||
|
||||
function _act(
|
||||
uint256 pk,
|
||||
Types.PublicationActionParams memory publicationActionParams
|
||||
) internal virtual returns (bytes memory) {
|
||||
vm.prank(vm.addr(pk));
|
||||
return hub.act(publicationActionParams);
|
||||
}
|
||||
|
||||
function _refreshCachedNonces() internal virtual {
|
||||
// Nothing to do there.
|
||||
}
|
||||
}
|
||||
|
||||
contract ActMetaTxTest is ActTest, MetaTxNegatives {
|
||||
mapping(address => uint256) cachedNonceByAddress;
|
||||
|
||||
function testActionMetaTxTest() public {
|
||||
// Prevents being counted in Foundry Coverage
|
||||
}
|
||||
|
||||
function setUp() public override(ActTest, MetaTxNegatives) {
|
||||
ActTest.setUp();
|
||||
MetaTxNegatives.setUp();
|
||||
|
||||
cachedNonceByAddress[actor.owner] = hub.nonces(actor.owner);
|
||||
}
|
||||
|
||||
function _act(
|
||||
uint256 pk,
|
||||
Types.PublicationActionParams memory publicationActionParams
|
||||
) internal override returns (bytes memory) {
|
||||
address signer = vm.addr(pk);
|
||||
return
|
||||
hub.actWithSig({
|
||||
publicationActionParams: publicationActionParams,
|
||||
signature: _getSigStruct({
|
||||
pKey: pk,
|
||||
digest: _calculateActWithSigDigest(
|
||||
publicationActionParams,
|
||||
cachedNonceByAddress[signer],
|
||||
type(uint256).max
|
||||
),
|
||||
deadline: type(uint256).max
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function _executeMetaTx(uint256 signerPk, uint256 nonce, uint256 deadline) internal virtual override {
|
||||
hub.actWithSig({
|
||||
publicationActionParams: defaultPubActionParams,
|
||||
signature: _getSigStruct({
|
||||
signer: vm.addr(_getDefaultMetaTxSignerPk()),
|
||||
pKey: signerPk,
|
||||
digest: _calculateActWithSigDigest(defaultPubActionParams, nonce, deadline),
|
||||
deadline: deadline
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function _getDefaultMetaTxSignerPk() internal virtual override returns (uint256) {
|
||||
return actor.ownerPk;
|
||||
}
|
||||
|
||||
function _calculateActWithSigDigest(
|
||||
Types.PublicationActionParams memory publicationActionParams,
|
||||
uint256 nonce,
|
||||
uint256 deadline
|
||||
) internal view returns (bytes32) {
|
||||
return
|
||||
_calculateDigest(
|
||||
keccak256(
|
||||
abi.encode(
|
||||
Typehash.ACT,
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId,
|
||||
publicationActionParams.actorProfileId,
|
||||
publicationActionParams.referrerProfileIds,
|
||||
publicationActionParams.referrerPubIds,
|
||||
publicationActionParams.actionModuleAddress,
|
||||
keccak256(publicationActionParams.actionModuleData),
|
||||
nonce,
|
||||
deadline
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function _refreshCachedNonces() internal override {
|
||||
cachedNonceByAddress[actor.owner] = hub.nonces(actor.owner);
|
||||
}
|
||||
}
|
||||
@@ -374,4 +374,17 @@ contract TestSetup is Test, ForkManagement, ArrayHelpers {
|
||||
referenceModuleInitData: ''
|
||||
});
|
||||
}
|
||||
|
||||
function _getDefaultPublicationActionParams() internal view returns (Types.PublicationActionParams memory) {
|
||||
return
|
||||
Types.PublicationActionParams({
|
||||
publicationActedProfileId: defaultPub.profileId,
|
||||
publicationActedId: defaultPub.pubId,
|
||||
actorProfileId: defaultAccount.profileId,
|
||||
referrerProfileIds: _emptyUint256Array(),
|
||||
referrerPubIds: _emptyUint256Array(),
|
||||
actionModuleAddress: address(mockActionModule),
|
||||
actionModuleData: abi.encode(true)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user