mirror of
https://github.com/lens-protocol/core.git
synced 2026-01-11 23:27:53 -05:00
508 lines
18 KiB
Solidity
508 lines
18 KiB
Solidity
// SPDX-License-Identifier: UNLICENSED
|
|
pragma solidity ^0.8.10;
|
|
|
|
import 'test/base/BaseTest.t.sol';
|
|
import {TokenGatedReferenceModule, GateParams} from 'contracts/modules/reference/TokenGatedReferenceModule.sol';
|
|
import {Types} from 'contracts/libraries/constants/Types.sol';
|
|
import {ArrayHelpers} from 'test/helpers/ArrayHelpers.sol';
|
|
import {MockCurrency} from 'test/mocks/MockCurrency.sol';
|
|
import {MockNFT} from 'test/mocks/MockNFT.sol';
|
|
|
|
contract TokenGatedReferenceModuleBase is BaseTest {
|
|
using stdJson for string;
|
|
TokenGatedReferenceModule tokenGatedReferenceModule;
|
|
|
|
MockNFT nft;
|
|
MockCurrency currency;
|
|
uint256 profileId;
|
|
|
|
event TokenGatedReferencePublicationCreated(
|
|
uint256 indexed profileId,
|
|
uint256 indexed pubId,
|
|
address tokenAddress,
|
|
uint256 minThreshold
|
|
);
|
|
|
|
function testTokenGatedReferenceModuleBase() public {
|
|
// Prevents being counted in Foundry Coverage
|
|
}
|
|
|
|
function setUp() public override {
|
|
super.setUp();
|
|
|
|
tokenGatedReferenceModule = TokenGatedReferenceModule(loadOrDeploy_TokenGatedReferenceModule());
|
|
|
|
currency = new MockCurrency();
|
|
nft = new MockNFT();
|
|
profileId = _createProfile(defaultAccount.owner);
|
|
}
|
|
}
|
|
|
|
/////////
|
|
// Publication Creation with TokenGatedReferenceModule
|
|
//
|
|
contract TokenGatedReferenceModule_Publication is TokenGatedReferenceModuleBase {
|
|
// Negatives
|
|
function testCannotPostWithZeroTokenAddress() public {
|
|
vm.expectRevert(Errors.InitParamsInvalid.selector);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.initializeReferenceModule(
|
|
1,
|
|
2,
|
|
address(3),
|
|
abi.encode(GateParams({tokenAddress: address(0), minThreshold: 1}))
|
|
);
|
|
}
|
|
|
|
function testCannotPostWithZeroMinThreshold() public {
|
|
vm.expectRevert(Errors.InitParamsInvalid.selector);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.initializeReferenceModule(
|
|
1,
|
|
2,
|
|
address(3),
|
|
abi.encode(GateParams({tokenAddress: address(currency), minThreshold: 0}))
|
|
);
|
|
}
|
|
|
|
function testCannotCallInitializeFromNonHub(address from) public {
|
|
vm.assume(from != address(hub));
|
|
vm.prank(from);
|
|
vm.expectRevert(Errors.NotHub.selector);
|
|
tokenGatedReferenceModule.initializeReferenceModule(
|
|
profileId,
|
|
1,
|
|
defaultAccount.owner,
|
|
abi.encode(GateParams({tokenAddress: address(currency), minThreshold: 1}))
|
|
);
|
|
}
|
|
|
|
function testCannotProcessCommentFromNonHub(address from) public {
|
|
vm.assume(from != address(hub));
|
|
vm.prank(from);
|
|
vm.expectRevert(Errors.NotHub.selector);
|
|
tokenGatedReferenceModule.processComment(
|
|
Types.ProcessCommentParams({
|
|
profileId: profileId,
|
|
pubId: 2,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: profileId,
|
|
pointedPubId: 1,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testCannotProcessQuoteFromNonHub(address from) public {
|
|
vm.assume(from != address(hub));
|
|
vm.prank(from);
|
|
vm.expectRevert(Errors.NotHub.selector);
|
|
tokenGatedReferenceModule.processQuote(
|
|
Types.ProcessQuoteParams({
|
|
profileId: profileId,
|
|
pubId: 2,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: profileId,
|
|
pointedPubId: 1,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testCannotProcessMirrorFromNonHub(address from) public {
|
|
vm.assume(from != address(hub));
|
|
vm.prank(from);
|
|
vm.expectRevert(Errors.NotHub.selector);
|
|
tokenGatedReferenceModule.processMirror(
|
|
Types.ProcessMirrorParams({
|
|
profileId: profileId,
|
|
pubId: 2,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: profileId,
|
|
pointedPubId: 1,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
// Scenarios
|
|
function testCanInitializeTokenGatedReferenceModule(uint256 profileId, uint256 pubId, uint256 minThreshold) public {
|
|
vm.assume(profileId != 0);
|
|
vm.assume(pubId != 0);
|
|
vm.assume(minThreshold != 0);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.initializeReferenceModule(
|
|
profileId,
|
|
pubId,
|
|
address(0),
|
|
abi.encode(GateParams({tokenAddress: address(currency), minThreshold: minThreshold}))
|
|
);
|
|
}
|
|
|
|
function testCreatePublicationWithTokenGatedReferenceModule_EmitsExpectedEvents(
|
|
uint256 profileId,
|
|
uint256 pubId,
|
|
uint256 minThreshold
|
|
) public {
|
|
vm.assume(profileId != 0);
|
|
vm.assume(pubId != 0);
|
|
vm.assume(minThreshold != 0);
|
|
|
|
vm.expectEmit(true, true, true, true, address(tokenGatedReferenceModule));
|
|
emit TokenGatedReferencePublicationCreated(profileId, pubId, address(currency), minThreshold);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.initializeReferenceModule(
|
|
profileId,
|
|
pubId,
|
|
address(0),
|
|
abi.encode(GateParams({tokenAddress: address(currency), minThreshold: minThreshold}))
|
|
);
|
|
}
|
|
}
|
|
|
|
/////////
|
|
// ERC20-Gated Reference
|
|
//
|
|
contract TokenGatedReferenceModule_ERC20_Gated is TokenGatedReferenceModuleBase {
|
|
function _initialize(uint256 publisherProfileId, uint256 publisherPubId, uint256 minThreshold) internal {
|
|
vm.assume(publisherProfileId != 0);
|
|
vm.assume(publisherPubId != 0);
|
|
vm.assume(minThreshold != 0);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.initializeReferenceModule(
|
|
publisherProfileId,
|
|
publisherPubId,
|
|
address(0),
|
|
abi.encode(GateParams({tokenAddress: address(currency), minThreshold: minThreshold}))
|
|
);
|
|
}
|
|
|
|
// Negatives
|
|
function testCannotProcessComment_IfNotEnoughBalance(
|
|
uint256 publisherProfileId,
|
|
uint256 publisherPubId,
|
|
uint256 minThreshold
|
|
) public {
|
|
assertEq(currency.balanceOf(address(defaultAccount.owner)), 0);
|
|
|
|
vm.assume(publisherProfileId != profileId);
|
|
_initialize(publisherProfileId, publisherPubId, minThreshold);
|
|
|
|
vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processComment(
|
|
Types.ProcessCommentParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testCannotProcessMirror_IfNotEnoughBalance(
|
|
uint256 publisherProfileId,
|
|
uint256 publisherPubId,
|
|
uint256 minThreshold
|
|
) public {
|
|
assertEq(currency.balanceOf(address(defaultAccount.owner)), 0);
|
|
|
|
vm.assume(publisherProfileId != profileId);
|
|
_initialize(publisherProfileId, publisherPubId, minThreshold);
|
|
|
|
vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processMirror(
|
|
Types.ProcessMirrorParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testCannotProcessQuote_IfNotEnoughBalance(
|
|
uint256 publisherProfileId,
|
|
uint256 publisherPubId,
|
|
uint256 minThreshold
|
|
) public {
|
|
assertEq(currency.balanceOf(address(defaultAccount.owner)), 0);
|
|
|
|
vm.assume(publisherProfileId != profileId);
|
|
_initialize(publisherProfileId, publisherPubId, minThreshold);
|
|
|
|
vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processQuote(
|
|
Types.ProcessQuoteParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
// Scenarios
|
|
function testProcessComment_HoldingEnoughTokens(
|
|
uint256 publisherProfileId,
|
|
uint256 publisherPubId,
|
|
uint256 minThreshold
|
|
) public {
|
|
currency.mint(defaultAccount.owner, minThreshold);
|
|
assertTrue(currency.balanceOf(defaultAccount.owner) >= minThreshold);
|
|
|
|
_initialize(publisherProfileId, publisherPubId, minThreshold);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processComment(
|
|
Types.ProcessCommentParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testProcessMirror_HoldingEnoughTokens(
|
|
uint256 publisherProfileId,
|
|
uint256 publisherPubId,
|
|
uint256 minThreshold
|
|
) public {
|
|
currency.mint(defaultAccount.owner, minThreshold);
|
|
assertTrue(currency.balanceOf(defaultAccount.owner) >= minThreshold);
|
|
|
|
_initialize(publisherProfileId, publisherPubId, minThreshold);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processMirror(
|
|
Types.ProcessMirrorParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testProcessQuote_HoldingEnoughTokens(
|
|
uint256 publisherProfileId,
|
|
uint256 publisherPubId,
|
|
uint256 minThreshold
|
|
) public {
|
|
currency.mint(defaultAccount.owner, minThreshold);
|
|
assertTrue(currency.balanceOf(defaultAccount.owner) >= minThreshold);
|
|
|
|
_initialize(publisherProfileId, publisherPubId, minThreshold);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processQuote(
|
|
Types.ProcessQuoteParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
}
|
|
|
|
/////////
|
|
// ERC721-Gated Reference
|
|
//
|
|
contract TokenGatedReferenceModule_ERC721_Gated is TokenGatedReferenceModuleBase {
|
|
uint256 constant minThreshold = 1;
|
|
|
|
function _initialize(uint256 publisherProfileId, uint256 publisherPubId) internal {
|
|
vm.assume(publisherProfileId != 0);
|
|
vm.assume(publisherPubId != 0);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.initializeReferenceModule(
|
|
publisherProfileId,
|
|
publisherPubId,
|
|
address(0),
|
|
abi.encode(GateParams({tokenAddress: address(nft), minThreshold: minThreshold}))
|
|
);
|
|
}
|
|
|
|
// Negatives
|
|
function testCannotProcessComment_IfNotEnoughBalance(uint256 publisherProfileId, uint256 publisherPubId) public {
|
|
assertEq(nft.balanceOf(address(defaultAccount.owner)), 0);
|
|
|
|
vm.assume(publisherProfileId != profileId);
|
|
_initialize(publisherProfileId, publisherPubId);
|
|
|
|
vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processComment(
|
|
Types.ProcessCommentParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testCannotProcessMirror_IfNotEnoughBalance(uint256 publisherProfileId, uint256 publisherPubId) public {
|
|
assertEq(nft.balanceOf(address(defaultAccount.owner)), 0);
|
|
|
|
vm.assume(publisherProfileId != profileId);
|
|
_initialize(publisherProfileId, publisherPubId);
|
|
|
|
vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processMirror(
|
|
Types.ProcessMirrorParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testCannotProcessQuote_IfNotEnoughBalance(uint256 publisherProfileId, uint256 publisherPubId) public {
|
|
assertEq(nft.balanceOf(address(defaultAccount.owner)), 0);
|
|
|
|
vm.assume(publisherProfileId != profileId);
|
|
_initialize(publisherProfileId, publisherPubId);
|
|
|
|
vm.expectRevert(TokenGatedReferenceModule.NotEnoughBalance.selector);
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processQuote(
|
|
Types.ProcessQuoteParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
// Scenarios
|
|
function testProcessComment_HoldingEnoughTokens(uint256 publisherProfileId, uint256 publisherPubId) public {
|
|
nft.mint({to: defaultAccount.owner, nftId: 1});
|
|
assertTrue(nft.balanceOf(defaultAccount.owner) >= minThreshold);
|
|
|
|
_initialize(publisherProfileId, publisherPubId);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processComment(
|
|
Types.ProcessCommentParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testProcessMirror_HoldingEnoughTokens(uint256 publisherProfileId, uint256 publisherPubId) public {
|
|
nft.mint({to: defaultAccount.owner, nftId: 1});
|
|
assertTrue(nft.balanceOf(defaultAccount.owner) >= minThreshold);
|
|
|
|
_initialize(publisherProfileId, publisherPubId);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processMirror(
|
|
Types.ProcessMirrorParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
|
|
function testProcessQuote_HoldingEnoughTokens(uint256 publisherProfileId, uint256 publisherPubId) public {
|
|
nft.mint({to: defaultAccount.owner, nftId: 1});
|
|
assertTrue(nft.balanceOf(defaultAccount.owner) >= minThreshold);
|
|
|
|
_initialize(publisherProfileId, publisherPubId);
|
|
|
|
vm.prank(address(hub));
|
|
tokenGatedReferenceModule.processQuote(
|
|
Types.ProcessQuoteParams({
|
|
profileId: profileId,
|
|
pubId: 1,
|
|
transactionExecutor: defaultAccount.owner,
|
|
pointedProfileId: publisherProfileId,
|
|
pointedPubId: publisherPubId,
|
|
referrerProfileIds: _emptyUint256Array(),
|
|
referrerPubIds: _emptyUint256Array(),
|
|
referrerPubTypes: _emptyPubTypesArray(),
|
|
data: ''
|
|
})
|
|
);
|
|
}
|
|
}
|