Merge branch 'feat/foundry' into feat/follow-nfts

This commit is contained in:
donosonaumczuk
2022-12-12 09:31:59 -03:00
17 changed files with 1376 additions and 489 deletions

View File

@@ -50,10 +50,10 @@ Scenarios
Governance Functions
Negatives
[ ] User should not be able to call governance functions
[X] User should not be able to call governance functions
Scenarios
[ ] Governance should successfully whitelist and unwhitelist modules
[ ] Governance should successfully change the governance address
[X] Governance should successfully whitelist and unwhitelist modules
[X] Governance should successfully change the governance address
Multi-State Hub
Common
@@ -75,41 +75,41 @@ Scenarios
// Replaced dispatcher with DelegatedExecutor for the following two tests:
[X] Governance should pause the hub, setting dispatcher should fail, then governance unpauses the hub and setting dispatcher should work
[X] Governance should pause the hub, setting dispatcher with sig should fail, then governance unpauses the hub and setting dispatcher with sig should work
[ ] Governance should pause the hub, setting profile URI should fail, then governance unpauses the hub and setting profile URI should work
[ ] Governance should pause the hub, setting profile URI with sig should fail, then governance unpauses the hub and setting profile URI should work
[ ] Governance should pause the hub, setting follow NFT URI should fail, then governance unpauses the hub and setting follow NFT URI should work
[ ] Governance should pause the hub, setting follow NFT URI with sig should fail, then governance unpauses the hub and setting follow NFT URI should work
[ ] Governance should pause the hub, posting should fail, then governance unpauses the hub and posting should work
[ ] Governance should pause the hub, posting with sig should fail, then governance unpauses the hub and posting with sig should work
[ ] Governance should pause the hub, commenting should fail, then governance unpauses the hub and commenting should work
[ ] Governance should pause the hub, commenting with sig should fail, then governance unpauses the hub and commenting with sig should work
[ ] Governance should pause the hub, mirroring should fail, then governance unpauses the hub and mirroring should work
[ ] Governance should pause the hub, mirroring with sig should fail, then governance unpauses the hub and mirroring with sig should work
[ ] Governance should pause the hub, burning should fail, then governance unpauses the hub and burning should work
[ ] Governance should pause the hub, following should fail, then governance unpauses the hub and following should work
[ ] Governance should pause the hub, following with sig should fail, then governance unpauses the hub and following with sig should work
[ ] Governance should pause the hub, collecting should fail, then governance unpauses the hub and collecting should work
[ ] Governance should pause the hub, collecting with sig should fail, then governance unpauses the hub and collecting with sig should work
[X] Governance should pause the hub, setting profile URI should fail, then governance unpauses the hub and setting profile URI should work
[X] Governance should pause the hub, setting profile URI with sig should fail, then governance unpauses the hub and setting profile URI should work
[X] Governance should pause the hub, setting follow NFT URI should fail, then governance unpauses the hub and setting follow NFT URI should work
[X] Governance should pause the hub, setting follow NFT URI with sig should fail, then governance unpauses the hub and setting follow NFT URI should work
[X] Governance should pause the hub, posting should fail, then governance unpauses the hub and posting should work
[X] Governance should pause the hub, posting with sig should fail, then governance unpauses the hub and posting with sig should work
[X] Governance should pause the hub, commenting should fail, then governance unpauses the hub and commenting should work
[X] Governance should pause the hub, commenting with sig should fail, then governance unpauses the hub and commenting with sig should work
[X] Governance should pause the hub, mirroring should fail, then governance unpauses the hub and mirroring should work
[X] Governance should pause the hub, mirroring with sig should fail, then governance unpauses the hub and mirroring with sig should work
[X] Governance should pause the hub, burning should fail, then governance unpauses the hub and burning should work
[X] Governance should pause the hub, following should fail, then governance unpauses the hub and following should work
[X] Governance should pause the hub, following with sig should fail, then governance unpauses the hub and following with sig should work
[X] Governance should pause the hub, collecting should fail, then governance unpauses the hub and collecting should work
[X] Governance should pause the hub, collecting with sig should fail, then governance unpauses the hub and collecting with sig should work
PublishingPaused State
Scenarios
[ ] Governance should pause publishing, profile creation should work
[ ] Governance should pause publishing, setting follow module should work
[ ] Governance should pause publishing, setting follow module with sig should work
[ ] Governance should pause publishing, setting dispatcher should work
[ ] Governance should pause publishing, setting dispatcher with sig should work
[ ] Governance should pause publishing, setting profile URI should work
[ ] Governance should pause publishing, setting profile URI with sig should work
[ ] Governance should pause publishing, posting should fail, then governance unpauses the hub and posting should work
[ ] Governance should pause publishing, posting with sig should fail, then governance unpauses the hub and posting with sig should work
[ ] Governance should pause publishing, commenting should fail, then governance unpauses the hub and commenting should work
[ ] Governance should pause publishing, commenting with sig should fail, then governance unpauses the hub and commenting with sig should work
[ ] Governance should pause publishing, mirroring should fail, then governance unpauses the hub and mirroring should work
[ ] Governance should pause publishing, mirroring with sig should fail, then governance unpauses the hub and mirroring with sig should work
[ ] Governance should pause publishing, burning should work
[ ] Governance should pause publishing, following should work
[ ] Governance should pause publishing, following with sig should work
[ ] Governance should pause publishing, collecting should work
[ ] Governance should pause publishing, collecting with sig should work
[X] Governance should pause publishing, profile creation should work
[X] Governance should pause publishing, setting follow module should work
[X] Governance should pause publishing, setting follow module with sig should work
[X] Governance should pause publishing, setting dispatcher should work
[X] Governance should pause publishing, setting dispatcher with sig should work
[X] Governance should pause publishing, setting profile URI should work
[X] Governance should pause publishing, setting profile URI with sig should work
[X] Governance should pause publishing, posting should fail, then governance unpauses the hub and posting should work
[X] Governance should pause publishing, posting with sig should fail, then governance unpauses the hub and posting with sig should work
[X] Governance should pause publishing, commenting should fail, then governance unpauses the hub and commenting should work
[X] Governance should pause publishing, commenting with sig should fail, then governance unpauses the hub and commenting with sig should work
[X] Governance should pause publishing, mirroring should fail, then governance unpauses the hub and mirroring should work
[X] Governance should pause publishing, mirroring with sig should fail, then governance unpauses the hub and mirroring with sig should work
[X] Governance should pause publishing, burning should work
[X] Governance should pause publishing, following should work
[X] Governance should pause publishing, following with sig should work
[X] Governance should pause publishing, collecting should work
[X] Governance should pause publishing, collecting with sig should work
Publishing Comments
Generic
@@ -274,20 +274,20 @@ Scenarios
Setting Follow Module
Generic
Negatives
[ ] UserTwo should fail to set the follow module for the profile owned by User
[ ] User should fail to set a follow module that is not whitelisted
[ ] User should fail to set a follow module with invalid follow module data format
[X] UserTwo should fail to set the follow module for the profile owned by User
[X] User should fail to set a follow module that is not whitelisted
[X] User should fail to set a follow module with invalid follow module data format
Scenarios
[ ] User should set a whitelisted follow module, fetching the profile follow module should return the correct address, user then sets it to the zero address and fetching returns the zero address
[X] User should set a whitelisted follow module, fetching the profile follow module should return the correct address, user then sets it to the zero address and fetching returns the zero address
Meta-tx
Negatives
[ ] TestWallet should fail to set a follow module with sig with signature deadline mismatch
[ ] TestWallet should fail to set a follow module with sig with invalid deadline
[ ] TestWallet should fail to set a follow module with sig with invalid nonce
[ ] TestWallet should fail to set a follow module with sig with an unwhitelisted follow module
[ ] TestWallet should sign attempt to set follow module with sig, then cancel with empty permitForAll, then fail to set follow module with sig
[X] TestWallet should fail to set a follow module with sig with signature deadline mismatch
[X] TestWallet should fail to set a follow module with sig with invalid deadline
[X] TestWallet should fail to set a follow module with sig with invalid nonce
[X] TestWallet should fail to set a follow module with sig with an unwhitelisted follow module
[X] TestWallet should sign attempt to set follow module with sig, then cancel with empty permitForAll, then fail to set follow module with sig
Scenarios
[ ] TestWallet should set a whitelisted follow module with sig, fetching the profile follow module should return the correct address
[X] TestWallet should set a whitelisted follow module with sig, fetching the profile follow module should return the correct address
Collect NFT
Negatives

17
scripts/getProxyAdmin.sh Normal file
View File

@@ -0,0 +1,17 @@
source .env
if [[ $1 == "" ]]
then
echo "Usage:"
echo " bash getProxyAdmin.sh [address]"
echo " Where [address] is the TransparentUpgradeableProxy address"
exit 1
fi
# TransparentUpgradeableProxy implementation slot
adminSlot="0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103"
rawOldImplAddress=$(cast storage $1 $adminSlot --rpc-url $POLYGON_RPC_URL)
echo "Admin of $1 TransparentUpgradeableProxy is:"
echo "0x${rawOldImplAddress:26}"

View File

@@ -16,7 +16,7 @@ contract CollectTest is BaseTest {
// negatives
function testCollectNonexistantPublicationFails() public {
vm.expectRevert(Errors.PublicationDoesNotExist.selector);
hub.collect(me, firstProfileId, 2, '');
hub.collect(me, newProfileId, 2, '');
}
function testCollectZeroPublicationFails() public {
@@ -27,28 +27,24 @@ contract CollectTest is BaseTest {
function testCollectNotExecutorFails() public {
vm.prank(otherSigner);
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.collect(me, firstProfileId, 1, '');
hub.collect(me, newProfileId, 1, '');
}
// positives
function testCollect() public {
assertEq(hub.getCollectNFT(firstProfileId, 1), address(0));
assertEq(hub.getCollectNFT(newProfileId, 1), address(0));
uint256 nftId = hub.collect(me, firstProfileId, 1, '');
CollectNFT nft = CollectNFT(hub.getCollectNFT(firstProfileId, 1));
uint256 nftId = hub.collect(me, newProfileId, 1, '');
CollectNFT nft = CollectNFT(hub.getCollectNFT(newProfileId, 1));
assertEq(nftId, 1);
assertEq(nft.ownerOf(1), me);
string memory expectedName = string(
abi.encodePacked(
firstProfileId.toString(),
COLLECT_NFT_NAME_INFIX,
uint256(1).toString()
)
abi.encodePacked(newProfileId.toString(), COLLECT_NFT_NAME_INFIX, uint256(1).toString())
);
string memory expectedSymbol = string(
abi.encodePacked(
firstProfileId.toString(),
newProfileId.toString(),
COLLECT_NFT_SYMBOL_INFIX,
uint256(1).toString()
)
@@ -62,9 +58,9 @@ contract CollectTest is BaseTest {
hub.setDelegatedExecutorApproval(otherSigner, true);
vm.prank(otherSigner);
uint256 nftId = hub.collect(me, firstProfileId, 1, '');
uint256 nftId = hub.collect(me, newProfileId, 1, '');
CollectNFT nft = CollectNFT(hub.getCollectNFT(firstProfileId, 1));
CollectNFT nft = CollectNFT(hub.getCollectNFT(newProfileId, 1));
assertEq(nftId, 1);
assertEq(nft.ownerOf(1), me);
}
@@ -73,13 +69,13 @@ contract CollectTest is BaseTest {
vm.prank(profileOwner);
hub.mirror(mockMirrorData);
uint256 nftId = hub.collect(me, firstProfileId, 2, '');
uint256 nftId = hub.collect(me, newProfileId, 2, '');
// Ensure the mirror doesn't have an associated collect NFT.
assertEq(hub.getCollectNFT(firstProfileId, 2), address(0));
assertEq(hub.getCollectNFT(newProfileId, 2), address(0));
// Ensure the original publication does have an associated collect NFT.
CollectNFT nft = CollectNFT(hub.getCollectNFT(firstProfileId, 1));
CollectNFT nft = CollectNFT(hub.getCollectNFT(newProfileId, 1));
assertEq(nftId, 1);
assertEq(nft.ownerOf(1), me);
}
@@ -91,13 +87,13 @@ contract CollectTest is BaseTest {
hub.setDelegatedExecutorApproval(otherSigner, true);
vm.prank(otherSigner);
uint256 nftId = hub.collect(me, firstProfileId, 2, '');
uint256 nftId = hub.collect(me, newProfileId, 2, '');
// Ensure the mirror doesn't have an associated collect NFT.
assertEq(hub.getCollectNFT(firstProfileId, 2), address(0));
assertEq(hub.getCollectNFT(newProfileId, 2), address(0));
// Ensure the original publication does have an associated collect NFT.
CollectNFT nft = CollectNFT(hub.getCollectNFT(firstProfileId, 1));
CollectNFT nft = CollectNFT(hub.getCollectNFT(newProfileId, 1));
assertEq(nftId, 1);
assertEq(nft.ownerOf(1), me);
}
@@ -107,13 +103,13 @@ contract CollectTest is BaseTest {
function testCollectWithSigInvalidSignerFails() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getCollectTypedDataHash(firstProfileId, 1, '', nonce, deadline);
bytes32 digest = _getCollectTypedDataHash(newProfileId, 1, '', nonce, deadline);
vm.expectRevert(Errors.SignatureInvalid.selector);
hub.collectWithSig(
_buildCollectWithSigData({
delegatedSigner: address(0),
collector: profileOwner,
profileId: firstProfileId,
profileId: newProfileId,
pubId: 1,
data: '',
sig: _getSigStruct(otherSignerKey, digest, deadline)
@@ -124,13 +120,13 @@ contract CollectTest is BaseTest {
function testCollectWithSigNotExecutorFails() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getCollectTypedDataHash(firstProfileId, 1, '', nonce, deadline);
bytes32 digest = _getCollectTypedDataHash(newProfileId, 1, '', nonce, deadline);
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.collectWithSig(
_buildCollectWithSigData({
delegatedSigner: otherSigner,
collector: profileOwner,
profileId: firstProfileId,
profileId: newProfileId,
pubId: 1,
data: '',
sig: _getSigStruct(otherSignerKey, digest, deadline)
@@ -142,30 +138,26 @@ contract CollectTest is BaseTest {
function testCollectWithSig() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getCollectTypedDataHash(firstProfileId, 1, '', nonce, deadline);
bytes32 digest = _getCollectTypedDataHash(newProfileId, 1, '', nonce, deadline);
uint256 nftId = hub.collectWithSig(
_buildCollectWithSigData({
delegatedSigner: address(0),
collector: otherSigner,
profileId: firstProfileId,
profileId: newProfileId,
pubId: 1,
data: '',
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
CollectNFT nft = CollectNFT(hub.getCollectNFT(firstProfileId, 1));
CollectNFT nft = CollectNFT(hub.getCollectNFT(newProfileId, 1));
string memory expectedName = string(
abi.encodePacked(
firstProfileId.toString(),
COLLECT_NFT_NAME_INFIX,
uint256(1).toString()
)
abi.encodePacked(newProfileId.toString(), COLLECT_NFT_NAME_INFIX, uint256(1).toString())
);
string memory expectedSymbol = string(
abi.encodePacked(
firstProfileId.toString(),
newProfileId.toString(),
COLLECT_NFT_SYMBOL_INFIX,
uint256(1).toString()
)
@@ -180,7 +172,7 @@ contract CollectTest is BaseTest {
function testCollectWithSigMirror() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getCollectTypedDataHash(firstProfileId, 2, '', nonce, deadline);
bytes32 digest = _getCollectTypedDataHash(newProfileId, 2, '', nonce, deadline);
vm.prank(profileOwner);
hub.mirror(mockMirrorData);
@@ -189,7 +181,7 @@ contract CollectTest is BaseTest {
_buildCollectWithSigData({
delegatedSigner: address(0),
collector: otherSigner,
profileId: firstProfileId,
profileId: newProfileId,
pubId: 2,
data: '',
sig: _getSigStruct(otherSignerKey, digest, deadline)
@@ -197,7 +189,7 @@ contract CollectTest is BaseTest {
);
// Ensure the mirror doesn't have an associated collect NFT.
assertEq(hub.getCollectNFT(firstProfileId, 2), address(0));
assertEq(hub.getCollectNFT(newProfileId, 2), address(0));
// Ensure the original publication does have an associated collect NFT.
CollectNFT nft = CollectNFT(hub.getCollectNFT(1, 1));
@@ -211,19 +203,19 @@ contract CollectTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getCollectTypedDataHash(firstProfileId, 1, '', nonce, deadline);
bytes32 digest = _getCollectTypedDataHash(newProfileId, 1, '', nonce, deadline);
uint256 nftId = hub.collectWithSig(
_buildCollectWithSigData({
delegatedSigner: profileOwner,
collector: otherSigner,
profileId: firstProfileId,
profileId: newProfileId,
pubId: 1,
data: '',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
CollectNFT nft = CollectNFT(hub.getCollectNFT(firstProfileId, 1));
CollectNFT nft = CollectNFT(hub.getCollectNFT(newProfileId, 1));
assertEq(nftId, 1);
assertEq(nft.ownerOf(1), otherSigner);
}
@@ -234,7 +226,7 @@ contract CollectTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getCollectTypedDataHash(firstProfileId, 2, '', nonce, deadline);
bytes32 digest = _getCollectTypedDataHash(newProfileId, 2, '', nonce, deadline);
vm.prank(profileOwner);
hub.mirror(mockMirrorData);
@@ -243,7 +235,7 @@ contract CollectTest is BaseTest {
_buildCollectWithSigData({
delegatedSigner: profileOwner,
collector: otherSigner,
profileId: firstProfileId,
profileId: newProfileId,
pubId: 2,
data: '',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
@@ -251,7 +243,7 @@ contract CollectTest is BaseTest {
);
// Ensure the mirror doesn't have an associated collect NFT.
assertEq(hub.getCollectNFT(firstProfileId, 2), address(0));
assertEq(hub.getCollectNFT(newProfileId, 2), address(0));
// Ensure the original publication does have an associated collect NFT.
CollectNFT nft = CollectNFT(hub.getCollectNFT(1, 1));

View File

@@ -5,16 +5,6 @@ import './base/BaseTest.t.sol';
import './helpers/SignatureHelpers.sol';
import './helpers/CollectingHelpers.sol';
contract SigSetup {
uint256 nonce;
uint256 deadline;
function setUp() public virtual {
nonce = 0;
deadline = type(uint256).max;
}
}
// TODO add check for _initialize() called for fork tests - check name and symbol set
contract CollectingTest_Base is BaseTest, SignatureHelpers, CollectingHelpers, SigSetup {
@@ -143,8 +133,7 @@ contract CollectingTest_Generic is CollectingTest_Base {
uint256 startNftId = _checkCollectNFTBefore();
// delegate power to executor
vm.prank(profileOwner);
_setDelegatedExecutorApproval(otherSigner, true);
_setDelegatedExecutorApproval(profileOwner, otherSigner, true);
// collect from executor
vm.startPrank(otherSigner);
@@ -158,10 +147,9 @@ contract CollectingTest_Generic is CollectingTest_Base {
uint256 startNftId = _checkCollectNFTBefore();
// mirror, then delegate power to executor
vm.startPrank(profileOwner);
vm.prank(profileOwner);
hub.mirror(mockMirrorData);
_setDelegatedExecutorApproval(otherSigner, true);
vm.stopPrank();
_setDelegatedExecutorApproval(profileOwner, otherSigner, true);
// collect from executor
vm.startPrank(otherSigner);
@@ -217,7 +205,7 @@ contract CollectingTest_WithSig is CollectingTest_Base {
function testCannotCollectIfNonceWasIncrementedWithAnotherAction() public {
assertEq(_getSigNonce(profileOwner), nonce, 'Wrong nonce before posting');
uint256 expectedCollectId = _getCollectCount(firstProfileId, mockCollectData.pubId) + 1;
uint256 expectedCollectId = _getCollectCount(newProfileId, mockCollectData.pubId) + 1;
uint256 nftId = _mockCollectWithSig({
delegatedSigner: address(0),
@@ -263,8 +251,7 @@ contract CollectingTest_WithSig is CollectingTest_Base {
uint256 startNftId = _checkCollectNFTBefore();
// delegate power to executor
vm.prank(profileOwner);
_setDelegatedExecutorApproval(otherSigner, true);
_setDelegatedExecutorApproval(profileOwner, otherSigner, true);
// collect from executor
uint256 nftId = _mockCollectWithSig({
@@ -279,10 +266,9 @@ contract CollectingTest_WithSig is CollectingTest_Base {
uint256 startNftId = _checkCollectNFTBefore();
// mirror, then delegate power to executor
vm.startPrank(profileOwner);
vm.prank(profileOwner);
hub.mirror(mockMirrorData);
_setDelegatedExecutorApproval(otherSigner, true);
vm.stopPrank();
_setDelegatedExecutorApproval(profileOwner, otherSigner, true);
// collect from executor
uint256 nftId = _mockCollectWithSig({

View File

@@ -0,0 +1,5 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
uint256 constant FIRST_PROFILE_ID = 1;
uint256 constant FIRST_PUB_ID = 1;

View File

@@ -3,33 +3,34 @@ pragma solidity ^0.8.13;
import './base/BaseTest.t.sol';
import {Strings} from '@openzeppelin/contracts/utils/Strings.sol';
import './helpers/SignatureHelpers.sol';
contract FollowTest is BaseTest {
contract FollowTest is BaseTest, SignatureHelpers {
using Strings for uint256;
// Negatives
function testFollowNotExecutorFails() public {
vm.prank(otherSigner);
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.follow(me, _toUint256Array(firstProfileId), _toBytesArray(''));
_follow({msgSender: otherSigner, onBehalfOf: me, profileId: newProfileId, data: ''});
}
// Positives
function testFollow() public {
assertEq(hub.getFollowNFT(firstProfileId), address(0));
assertEq(hub.getFollowNFT(newProfileId), address(0));
uint256[] memory nftIds = hub.follow(
me,
_toUint256Array(firstProfileId),
_toBytesArray('')
);
uint256[] memory nftIds = _follow({
msgSender: me,
onBehalfOf: me,
profileId: newProfileId,
data: ''
});
FollowNFT nft = FollowNFT(hub.getFollowNFT(firstProfileId));
FollowNFT nft = FollowNFT(hub.getFollowNFT(newProfileId));
string memory expectedName = string(
abi.encodePacked(firstProfileId.toString(), FOLLOW_NFT_NAME_SUFFIX)
abi.encodePacked(newProfileId.toString(), FOLLOW_NFT_NAME_SUFFIX)
);
string memory expectedSymbol = string(
abi.encodePacked(firstProfileId.toString(), FOLLOW_NFT_SYMBOL_SUFFIX)
abi.encodePacked(newProfileId.toString(), FOLLOW_NFT_SYMBOL_SUFFIX)
);
assertEq(nft.name(), expectedName);
assertEq(nft.symbol(), expectedSymbol);
@@ -41,14 +42,14 @@ contract FollowTest is BaseTest {
function testExecutorFollow() public {
hub.setDelegatedExecutorApproval(otherSigner, true);
vm.prank(otherSigner);
uint256[] memory nftIds = hub.follow(
me,
_toUint256Array(firstProfileId),
_toBytesArray('')
);
uint256[] memory nftIds = _follow({
msgSender: otherSigner,
onBehalfOf: me,
profileId: newProfileId,
data: ''
});
FollowNFT nft = FollowNFT(hub.getFollowNFT(firstProfileId));
FollowNFT nft = FollowNFT(hub.getFollowNFT(newProfileId));
assertEq(nftIds.length, 1);
assertEq(nftIds[0], 1);
assertEq(nft.ownerOf(1), me);
@@ -58,7 +59,7 @@ contract FollowTest is BaseTest {
// Negatives
function testFollowWithSigInvalidSignerFails() public {
uint256[] memory profileIds = new uint256[](1);
profileIds[0] = firstProfileId;
profileIds[0] = newProfileId;
bytes[] memory datas = new bytes[](1);
datas[0] = '';
uint256 nonce = 0;
@@ -66,7 +67,7 @@ contract FollowTest is BaseTest {
bytes32 digest = _getFollowTypedDataHash(profileIds, datas, nonce, deadline);
vm.expectRevert(Errors.SignatureInvalid.selector);
hub.followWithSig(
_followWithSig(
_buildFollowWithSigData({
delegatedSigner: address(0),
follower: profileOwner,
@@ -79,7 +80,7 @@ contract FollowTest is BaseTest {
function testFollowWithSigNotExecutorFails() public {
uint256[] memory profileIds = new uint256[](1);
profileIds[0] = firstProfileId;
profileIds[0] = newProfileId;
bytes[] memory datas = new bytes[](1);
datas[0] = '';
uint256 nonce = 0;
@@ -87,7 +88,7 @@ contract FollowTest is BaseTest {
bytes32 digest = _getFollowTypedDataHash(profileIds, datas, nonce, deadline);
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.followWithSig(
_followWithSig(
_buildFollowWithSigData({
delegatedSigner: otherSigner,
follower: profileOwner,
@@ -100,17 +101,17 @@ contract FollowTest is BaseTest {
// Positives
function testFollowWithSig() public {
assertEq(hub.getFollowNFT(firstProfileId), address(0));
assertEq(hub.getFollowNFT(newProfileId), address(0));
uint256[] memory profileIds = new uint256[](1);
profileIds[0] = firstProfileId;
profileIds[0] = newProfileId;
bytes[] memory datas = new bytes[](1);
datas[0] = '';
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getFollowTypedDataHash(profileIds, datas, nonce, deadline);
uint256[] memory nftIds = hub.followWithSig(
uint256[] memory nftIds = _followWithSig(
_buildFollowWithSigData({
delegatedSigner: address(0),
follower: otherSigner,
@@ -120,12 +121,12 @@ contract FollowTest is BaseTest {
})
);
FollowNFT nft = FollowNFT(hub.getFollowNFT(firstProfileId));
FollowNFT nft = FollowNFT(hub.getFollowNFT(newProfileId));
string memory expectedName = string(
abi.encodePacked(firstProfileId.toString(), FOLLOW_NFT_NAME_SUFFIX)
abi.encodePacked(newProfileId.toString(), FOLLOW_NFT_NAME_SUFFIX)
);
string memory expectedSymbol = string(
abi.encodePacked(firstProfileId.toString(), FOLLOW_NFT_SYMBOL_SUFFIX)
abi.encodePacked(newProfileId.toString(), FOLLOW_NFT_SYMBOL_SUFFIX)
);
assertEq(nft.name(), expectedName);
assertEq(nft.symbol(), expectedSymbol);
@@ -139,14 +140,14 @@ contract FollowTest is BaseTest {
hub.setDelegatedExecutorApproval(profileOwner, true);
uint256[] memory profileIds = new uint256[](1);
profileIds[0] = firstProfileId;
profileIds[0] = newProfileId;
bytes[] memory datas = new bytes[](1);
datas[0] = '';
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getFollowTypedDataHash(profileIds, datas, nonce, deadline);
uint256[] memory nftIds = hub.followWithSig(
uint256[] memory nftIds = _followWithSig(
_buildFollowWithSigData({
delegatedSigner: profileOwner,
follower: otherSigner,
@@ -156,20 +157,9 @@ contract FollowTest is BaseTest {
})
);
FollowNFT nft = FollowNFT(hub.getFollowNFT(firstProfileId));
FollowNFT nft = FollowNFT(hub.getFollowNFT(newProfileId));
assertEq(nftIds.length, 1);
assertEq(nftIds[0], 1);
assertEq(nft.ownerOf(1), otherSigner);
}
// Private functions
function _buildFollowWithSigData(
address delegatedSigner,
address follower,
uint256[] memory profileIds,
bytes[] memory datas,
DataTypes.EIP712Signature memory sig
) private pure returns (DataTypes.FollowWithSigData memory) {
return DataTypes.FollowWithSigData(delegatedSigner, follower, profileIds, datas, sig);
}
}

View File

@@ -0,0 +1,73 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import './base/BaseTest.t.sol';
contract GovernanceFunctionsTest is BaseTest {
function setUp() public virtual override {
TestSetup.setUp();
}
// NEGATIVES
function testUserCannotCallGovernanceFunctions() public {
vm.startPrank(profileOwner);
vm.expectRevert(Errors.NotGovernance.selector);
hub.setGovernance(profileOwner);
vm.expectRevert(Errors.NotGovernance.selector);
hub.whitelistFollowModule(profileOwner, true);
vm.expectRevert(Errors.NotGovernance.selector);
hub.whitelistReferenceModule(profileOwner, true);
vm.expectRevert(Errors.NotGovernance.selector);
hub.whitelistCollectModule(profileOwner, true);
vm.stopPrank();
}
// SCENARIOS
function testGovernanceCanWhitelistAndUnwhitelistModules() public {
vm.startPrank(governance);
// Whitelist
assertEq(hub.isFollowModuleWhitelisted(profileOwner), false);
hub.whitelistFollowModule(profileOwner, true);
assertEq(hub.isFollowModuleWhitelisted(profileOwner), true);
assertEq(hub.isReferenceModuleWhitelisted(profileOwner), false);
hub.whitelistReferenceModule(profileOwner, true);
assertEq(hub.isReferenceModuleWhitelisted(profileOwner), true);
assertEq(hub.isCollectModuleWhitelisted(profileOwner), false);
hub.whitelistCollectModule(profileOwner, true);
assertEq(hub.isCollectModuleWhitelisted(profileOwner), true);
// Unwhitelist
hub.whitelistFollowModule(profileOwner, false);
assertEq(hub.isFollowModuleWhitelisted(profileOwner), false);
hub.whitelistReferenceModule(profileOwner, false);
assertEq(hub.isReferenceModuleWhitelisted(profileOwner), false);
hub.whitelistCollectModule(profileOwner, false);
assertEq(hub.isCollectModuleWhitelisted(profileOwner), false);
vm.stopPrank();
}
function testGovernanceCanChangeGovernanceAddress() public {
vm.startPrank(governance);
assertEq(hub.getGovernance(), governance);
hub.setGovernance(profileOwner);
assertEq(hub.getGovernance(), profileOwner);
vm.stopPrank();
}
}

View File

@@ -6,140 +6,75 @@ import '../../contracts/mocks/MockFollowModule.sol';
contract MiscTest is BaseTest {
// Negatives
function testSetFollowModuleNotExecutorFails() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setFollowModule(firstProfileId, address(0), '');
}
function testSetDefaultProfileNotExecutorFails() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setDefaultProfile(profileOwner, firstProfileId);
hub.setDefaultProfile(profileOwner, newProfileId);
}
function testSetProfileImageURINotExecutorFails() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setProfileImageURI(firstProfileId, mockURI);
hub.setProfileImageURI(newProfileId, MOCK_URI);
}
function testSetFollowNFTURINotExecutorFails() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setFollowNFTURI(firstProfileId, mockURI);
hub.setFollowNFTURI(newProfileId, MOCK_URI);
}
function testSetProfileMetadataURINotExecutorFails() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setProfileMetadataURI(firstProfileId, mockURI);
hub.setProfileMetadataURI(newProfileId, MOCK_URI);
}
// Positives
function testExecutorSetFollowModule() public {
assertEq(hub.getFollowModule(firstProfileId), address(0));
vm.prank(profileOwner);
hub.setDelegatedExecutorApproval(otherSigner, true);
address mockFollowModule = address(new MockFollowModule());
vm.prank(governance);
hub.whitelistFollowModule(mockFollowModule, true);
vm.prank(otherSigner);
hub.setFollowModule(firstProfileId, mockFollowModule, abi.encode(1));
assertEq(hub.getFollowModule(firstProfileId), mockFollowModule);
}
function testExecutorSetDefaultProfile() public {
assertEq(hub.getDefaultProfile(profileOwner), 0);
vm.prank(profileOwner);
hub.setDelegatedExecutorApproval(otherSigner, true);
vm.prank(otherSigner);
hub.setDefaultProfile(profileOwner, firstProfileId);
assertEq(hub.getDefaultProfile(profileOwner), firstProfileId);
hub.setDefaultProfile(profileOwner, newProfileId);
assertEq(hub.getDefaultProfile(profileOwner), newProfileId);
}
function testExecutorSetProfileImageURI() public {
assertEq(hub.getProfileImageURI(firstProfileId), mockURI);
assertEq(hub.getProfileImageURI(newProfileId), MOCK_URI);
vm.prank(profileOwner);
hub.setDelegatedExecutorApproval(otherSigner, true);
vm.prank(otherSigner);
hub.setProfileImageURI(firstProfileId, 'test');
assertEq(hub.getProfileImageURI(firstProfileId), 'test');
hub.setProfileImageURI(newProfileId, 'test');
assertEq(hub.getProfileImageURI(newProfileId), 'test');
}
function testExecutorSetFollowNFTURI() public {
assertEq(hub.getFollowNFTURI(firstProfileId), mockURI);
assertEq(hub.getFollowNFTURI(newProfileId), MOCK_URI);
vm.prank(profileOwner);
hub.setDelegatedExecutorApproval(otherSigner, true);
vm.prank(otherSigner);
hub.setFollowNFTURI(firstProfileId, 'test');
assertEq(hub.getFollowNFTURI(firstProfileId), 'test');
hub.setFollowNFTURI(newProfileId, 'test');
assertEq(hub.getFollowNFTURI(newProfileId), 'test');
}
function testExecutorSetProfileMetadataURI() public {
assertEq(hub.getProfileMetadataURI(firstProfileId), '');
assertEq(hub.getProfileMetadataURI(newProfileId), '');
vm.prank(profileOwner);
hub.setDelegatedExecutorApproval(otherSigner, true);
vm.prank(otherSigner);
hub.setProfileMetadataURI(firstProfileId, mockURI);
assertEq(hub.getProfileMetadataURI(firstProfileId), mockURI);
hub.setProfileMetadataURI(newProfileId, MOCK_URI);
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
}
// Meta-tx
// Negatives
function testSetFollowModuleWithSigInvalidSignerFails() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowModuleTypedDataHash(
firstProfileId,
address(0),
'',
nonce,
deadline
);
vm.expectRevert(Errors.SignatureInvalid.selector);
hub.setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
followModule: address(0),
followModuleInitData: '',
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
}
function testSetFollowModuleWithSigNotExecutorFails() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowModuleTypedDataHash(
firstProfileId,
address(0),
'',
nonce,
deadline
);
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
followModule: address(0),
followModuleInitData: '',
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
}
function testSetDefaultProfileWithSigInvalidSignerFails() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetDefaultProfileTypedDataHash(
profileOwner,
firstProfileId,
newProfileId,
nonce,
deadline
);
@@ -149,7 +84,7 @@ contract MiscTest is BaseTest {
DataTypes.SetDefaultProfileWithSigData({
delegatedSigner: address(0),
wallet: profileOwner,
profileId: firstProfileId,
profileId: newProfileId,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
@@ -160,7 +95,7 @@ contract MiscTest is BaseTest {
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetDefaultProfileTypedDataHash(
profileOwner,
firstProfileId,
newProfileId,
nonce,
deadline
);
@@ -170,7 +105,7 @@ contract MiscTest is BaseTest {
DataTypes.SetDefaultProfileWithSigData({
delegatedSigner: otherSigner,
wallet: profileOwner,
profileId: firstProfileId,
profileId: newProfileId,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
@@ -180,8 +115,8 @@ contract MiscTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileImageURITypedDataHash(
firstProfileId,
mockURI,
newProfileId,
MOCK_URI,
nonce,
deadline
);
@@ -190,8 +125,8 @@ contract MiscTest is BaseTest {
hub.setProfileImageURIWithSig(
DataTypes.SetProfileImageURIWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
imageURI: mockURI,
profileId: newProfileId,
imageURI: MOCK_URI,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
@@ -201,8 +136,8 @@ contract MiscTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileImageURITypedDataHash(
firstProfileId,
mockURI,
newProfileId,
MOCK_URI,
nonce,
deadline
);
@@ -211,8 +146,8 @@ contract MiscTest is BaseTest {
hub.setProfileImageURIWithSig(
DataTypes.SetProfileImageURIWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
imageURI: mockURI,
profileId: newProfileId,
imageURI: MOCK_URI,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
@@ -221,14 +156,14 @@ contract MiscTest is BaseTest {
function testSetFollowNFTURIWithSigInvalidSignerFails() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowNFTURITypedDatahash(firstProfileId, mockURI, nonce, deadline);
bytes32 digest = _getSetFollowNFTURITypedDataHash(newProfileId, MOCK_URI, nonce, deadline);
vm.expectRevert(Errors.SignatureInvalid.selector);
hub.setFollowNFTURIWithSig(
DataTypes.SetFollowNFTURIWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
followNFTURI: mockURI,
profileId: newProfileId,
followNFTURI: MOCK_URI,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
@@ -237,14 +172,14 @@ contract MiscTest is BaseTest {
function testSetFollowNFTURIWithSigNotExecutorFails() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowNFTURITypedDatahash(firstProfileId, mockURI, nonce, deadline);
bytes32 digest = _getSetFollowNFTURITypedDataHash(newProfileId, MOCK_URI, nonce, deadline);
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setFollowNFTURIWithSig(
DataTypes.SetFollowNFTURIWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
followNFTURI: mockURI,
profileId: newProfileId,
followNFTURI: MOCK_URI,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
@@ -254,8 +189,8 @@ contract MiscTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
firstProfileId,
mockURI,
newProfileId,
MOCK_URI,
nonce,
deadline
);
@@ -264,8 +199,8 @@ contract MiscTest is BaseTest {
hub.setProfileMetadataURIWithSig(
DataTypes.SetProfileMetadataURIWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
metadataURI: mockURI,
profileId: newProfileId,
metadataURI: MOCK_URI,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
@@ -275,8 +210,8 @@ contract MiscTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
firstProfileId,
mockURI,
newProfileId,
MOCK_URI,
nonce,
deadline
);
@@ -285,80 +220,20 @@ contract MiscTest is BaseTest {
hub.setProfileMetadataURIWithSig(
DataTypes.SetProfileMetadataURIWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
metadataURI: mockURI,
profileId: newProfileId,
metadataURI: MOCK_URI,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
}
// Postivies
function testSetFollowModuleWithSig() public {
address mockFollowModule = address(new MockFollowModule());
vm.prank(governance);
hub.whitelistFollowModule(mockFollowModule, true);
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowModuleTypedDataHash(
firstProfileId,
mockFollowModule,
abi.encode(1),
nonce,
deadline
);
assertEq(hub.getFollowModule(firstProfileId), address(0));
hub.setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
followModule: mockFollowModule,
followModuleInitData: abi.encode(1),
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
assertEq(hub.getFollowModule(firstProfileId), mockFollowModule);
}
function testExecutorSetFollowModuleWithSig() public {
vm.prank(profileOwner);
hub.setDelegatedExecutorApproval(otherSigner, true);
address mockFollowModule = address(new MockFollowModule());
vm.prank(governance);
hub.whitelistFollowModule(mockFollowModule, true);
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowModuleTypedDataHash(
firstProfileId,
mockFollowModule,
abi.encode(1),
nonce,
deadline
);
assertEq(hub.getFollowModule(firstProfileId), address(0));
hub.setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
followModule: mockFollowModule,
followModuleInitData: abi.encode(1),
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
assertEq(hub.getFollowModule(firstProfileId), mockFollowModule);
}
function testSetDefaultProfileWithSig() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetDefaultProfileTypedDataHash(
profileOwner,
firstProfileId,
newProfileId,
nonce,
deadline
);
@@ -368,11 +243,11 @@ contract MiscTest is BaseTest {
DataTypes.SetDefaultProfileWithSigData({
delegatedSigner: address(0),
wallet: profileOwner,
profileId: firstProfileId,
profileId: newProfileId,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
assertEq(hub.getDefaultProfile(profileOwner), firstProfileId);
assertEq(hub.getDefaultProfile(profileOwner), newProfileId);
}
function testExecutorSetDefaultProfileWithSig() public {
@@ -383,7 +258,7 @@ contract MiscTest is BaseTest {
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetDefaultProfileTypedDataHash(
profileOwner,
firstProfileId,
newProfileId,
nonce,
deadline
);
@@ -393,33 +268,28 @@ contract MiscTest is BaseTest {
DataTypes.SetDefaultProfileWithSigData({
delegatedSigner: otherSigner,
wallet: profileOwner,
profileId: firstProfileId,
profileId: newProfileId,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
assertEq(hub.getDefaultProfile(profileOwner), firstProfileId);
assertEq(hub.getDefaultProfile(profileOwner), newProfileId);
}
function testSetProfileImageURIWithSig() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileImageURITypedDataHash(
firstProfileId,
'test',
nonce,
deadline
);
bytes32 digest = _getSetProfileImageURITypedDataHash(newProfileId, 'test', nonce, deadline);
assertEq(hub.getProfileImageURI(firstProfileId), mockURI);
assertEq(hub.getProfileImageURI(newProfileId), MOCK_URI);
hub.setProfileImageURIWithSig(
DataTypes.SetProfileImageURIWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
profileId: newProfileId,
imageURI: 'test',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
assertEq(hub.getProfileImageURI(firstProfileId), 'test');
assertEq(hub.getProfileImageURI(newProfileId), 'test');
}
function testExecutorSetProfileImageURIWithSig() public {
@@ -428,40 +298,35 @@ contract MiscTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileImageURITypedDataHash(
firstProfileId,
'test',
nonce,
deadline
);
bytes32 digest = _getSetProfileImageURITypedDataHash(newProfileId, 'test', nonce, deadline);
assertEq(hub.getProfileImageURI(firstProfileId), mockURI);
assertEq(hub.getProfileImageURI(newProfileId), MOCK_URI);
hub.setProfileImageURIWithSig(
DataTypes.SetProfileImageURIWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
profileId: newProfileId,
imageURI: 'test',
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
assertEq(hub.getProfileImageURI(firstProfileId), 'test');
assertEq(hub.getProfileImageURI(newProfileId), 'test');
}
function testSetFollowNFTURIWithSig() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowNFTURITypedDatahash(firstProfileId, 'test', nonce, deadline);
bytes32 digest = _getSetFollowNFTURITypedDataHash(newProfileId, 'test', nonce, deadline);
assertEq(hub.getFollowNFTURI(firstProfileId), mockURI);
assertEq(hub.getFollowNFTURI(newProfileId), MOCK_URI);
hub.setFollowNFTURIWithSig(
DataTypes.SetFollowNFTURIWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
profileId: newProfileId,
followNFTURI: 'test',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
assertEq(hub.getFollowNFTURI(firstProfileId), 'test');
assertEq(hub.getFollowNFTURI(newProfileId), 'test');
}
function testExecutorSetFollowNFTURIWithSig() public {
@@ -470,40 +335,40 @@ contract MiscTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetFollowNFTURITypedDatahash(firstProfileId, 'test', nonce, deadline);
bytes32 digest = _getSetFollowNFTURITypedDataHash(newProfileId, 'test', nonce, deadline);
assertEq(hub.getFollowNFTURI(firstProfileId), mockURI);
assertEq(hub.getFollowNFTURI(newProfileId), MOCK_URI);
hub.setFollowNFTURIWithSig(
DataTypes.SetFollowNFTURIWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
profileId: newProfileId,
followNFTURI: 'test',
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
assertEq(hub.getFollowNFTURI(firstProfileId), 'test');
assertEq(hub.getFollowNFTURI(newProfileId), 'test');
}
function testSetProfileMetadataURIWithSig() public {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
firstProfileId,
mockURI,
newProfileId,
MOCK_URI,
nonce,
deadline
);
assertEq(hub.getProfileMetadataURI(firstProfileId), '');
assertEq(hub.getProfileMetadataURI(newProfileId), '');
hub.setProfileMetadataURIWithSig(
DataTypes.SetProfileMetadataURIWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
metadataURI: mockURI,
profileId: newProfileId,
metadataURI: MOCK_URI,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
assertEq(hub.getProfileMetadataURI(firstProfileId), mockURI);
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
}
function testExecutorSetProfileMetadataURIWithSig() public {
@@ -513,21 +378,21 @@ contract MiscTest is BaseTest {
uint256 nonce = 0;
uint256 deadline = type(uint256).max;
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
firstProfileId,
mockURI,
newProfileId,
MOCK_URI,
nonce,
deadline
);
assertEq(hub.getProfileMetadataURI(firstProfileId), '');
assertEq(hub.getProfileMetadataURI(newProfileId), '');
hub.setProfileMetadataURIWithSig(
DataTypes.SetProfileMetadataURIWithSigData({
delegatedSigner: otherSigner,
profileId: firstProfileId,
metadataURI: mockURI,
profileId: newProfileId,
metadataURI: MOCK_URI,
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
assertEq(hub.getProfileMetadataURI(firstProfileId), mockURI);
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
}
}

View File

@@ -2,7 +2,7 @@
pragma solidity ^0.8.13;
import './base/BaseTest.t.sol';
import {SigSetup} from './helpers/SignatureHelpers.sol';
import './helpers/SignatureHelpers.sol';
contract MultiStateHubTest_Common is BaseTest {
// Negatives
@@ -109,15 +109,21 @@ contract MultiStateHubTest_Common is BaseTest {
}
contract MultiStateHubTest_PausedState_Direct is BaseTest {
uint256 postId;
function setUp() public virtual override {
super.setUp();
vm.prank(profileOwner);
postId = _post(mockPostData);
vm.prank(governance);
_setState(DataTypes.ProtocolState.Paused);
}
// TODO: Consider extracting these mock actions functions somewhere because they're used in several places
function _mockSetFollowModule() internal virtual {
_setFollowModule(profileOwner, firstProfileId, address(0), '');
_setFollowModule(profileOwner, newProfileId, address(0), '');
}
function _mockSetDelegatedExecutorApproval() internal virtual {
@@ -126,18 +132,63 @@ contract MultiStateHubTest_PausedState_Direct is BaseTest {
_setDelegatedExecutorApproval(profileOwner, executor, approved);
}
function _mockSetProfileImageURI() internal virtual {
_setProfileImageURI(profileOwner, newProfileId, MOCK_URI);
}
function _mockSetFollowNFTURI() internal virtual {
_setFollowNFTURI(profileOwner, newProfileId, MOCK_URI);
}
function _mockPost() internal virtual {
vm.prank(profileOwner);
_post(mockPostData);
}
function _mockComment() internal virtual {
mockCommentData.pubIdPointed = postId;
vm.prank(profileOwner);
_comment(mockCommentData);
}
function _mockMirror() internal virtual {
mockMirrorData.pubIdPointed = postId;
vm.prank(profileOwner);
_mirror(mockMirrorData);
}
function _mockBurn() internal virtual {
_burn(profileOwner, newProfileId);
}
function _mockFollow() internal virtual {
_follow({msgSender: me, onBehalfOf: me, profileId: newProfileId, data: ''});
}
// TODO: The following two functions were copy-pasted from CollectingTest.t.sol
// TODO: Consider extracting them somewhere else to be used by both of tests
function _mockCollect() internal virtual {
vm.prank(profileOwner);
_collect(
mockCollectData.collector,
mockCollectData.profileId,
mockCollectData.pubId,
mockCollectData.data
);
}
// Negatives
function testCantTransferProfileWhilePaused() public virtual {
function testCannotTransferProfileWhilePaused() public virtual {
vm.expectRevert(Errors.Paused.selector);
_transferProfile({
msgSender: profileOwner,
from: profileOwner,
to: address(111),
tokenId: firstProfileId
tokenId: newProfileId
});
}
function testCantCreateProfileWhilePaused() public virtual {
function testCannotCreateProfileWhilePaused() public virtual {
vm.expectRevert(Errors.Paused.selector);
_createProfile(address(this));
@@ -147,7 +198,7 @@ contract MultiStateHubTest_PausedState_Direct is BaseTest {
_createProfile(address(this));
}
function testCantSetFollowModuleWhilePaused() public {
function testCannotSetFollowModuleWhilePaused() public {
vm.expectRevert(Errors.Paused.selector);
_mockSetFollowModule();
@@ -155,10 +206,9 @@ contract MultiStateHubTest_PausedState_Direct is BaseTest {
_setState(DataTypes.ProtocolState.Unpaused);
_mockSetFollowModule();
// TODO: Consider if we should check if the follow module was set (or its enough to do that in Follow module tests)
}
function testCantSetDelegatedExecutorWhilePaused() public {
function testCannotSetDelegatedExecutorWhilePaused() public {
vm.expectRevert(Errors.Paused.selector);
_mockSetDelegatedExecutorApproval();
@@ -166,12 +216,94 @@ contract MultiStateHubTest_PausedState_Direct is BaseTest {
_setState(DataTypes.ProtocolState.Unpaused);
_mockSetDelegatedExecutorApproval();
// TODO: Consider if we should check if the delegated executor was set (or its enough to do that in DE tests)
// assertEq(hub.isDelegatedExecutorApproved(profileOwner, executor), approved);
}
function testCannotSetProfileImageURIWhilePaused() public {
vm.expectRevert(Errors.Paused.selector);
_mockSetProfileImageURI();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockSetProfileImageURI();
}
function testCannotSetFollowNFTURIWhilePaused() public {
vm.expectRevert(Errors.Paused.selector);
_mockSetFollowNFTURI();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockSetFollowNFTURI();
}
function testCannotPostWhilePaused() public {
vm.expectRevert(Errors.PublishingPaused.selector);
_mockPost();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockPost();
}
function testCannotCommentWhilePaused() public {
vm.expectRevert(Errors.PublishingPaused.selector);
_mockComment();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockComment();
}
function testCannotMirrorWhilePaused() public {
vm.expectRevert(Errors.PublishingPaused.selector);
_mockMirror();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockMirror();
}
function testCannotBurnWhilePaused() public {
vm.expectRevert(Errors.Paused.selector);
_mockBurn();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockBurn();
}
function testCannotFollowWhilePaused() public {
vm.expectRevert(Errors.Paused.selector);
_mockFollow();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockFollow();
}
function testCannotCollectWhilePaused() public {
vm.expectRevert(Errors.Paused.selector);
_mockCollect();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockCollect();
}
}
contract MultiStateHubTest_PausedState_WithSig is MultiStateHubTest_PausedState_Direct, SigSetup {
contract MultiStateHubTest_PausedState_WithSig is
MultiStateHubTest_PausedState_Direct,
SignatureHelpers,
SigSetup
{
function setUp() public override(MultiStateHubTest_PausedState_Direct, SigSetup) {
MultiStateHubTest_PausedState_Direct.setUp();
SigSetup.setUp();
@@ -179,23 +311,22 @@ contract MultiStateHubTest_PausedState_WithSig is MultiStateHubTest_PausedState_
function _mockSetFollowModule() internal override {
bytes32 digest = _getSetFollowModuleTypedDataHash(
firstProfileId,
newProfileId,
address(0),
'',
nonce,
deadline
);
return
_setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: address(0),
profileId: firstProfileId,
followModule: address(0),
followModuleInitData: '',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
_setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: address(0),
profileId: newProfileId,
followModule: address(0),
followModuleInitData: '',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
// Positives
@@ -220,8 +351,439 @@ contract MultiStateHubTest_PausedState_WithSig is MultiStateHubTest_PausedState_
);
}
// Methods that cannot be called with sig
function testCantTransferProfileWhilePaused() public override {}
function _mockSetProfileImageURI() internal override {
bytes32 digest = _getSetProfileImageURITypedDataHash(
newProfileId,
MOCK_URI,
nonce,
deadline
);
function testCantCreateProfileWhilePaused() public override {}
_setProfileImageURIWithSig(
DataTypes.SetProfileImageURIWithSigData({
delegatedSigner: address(0),
profileId: newProfileId,
imageURI: MOCK_URI,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockSetFollowNFTURI() internal override {
bytes32 digest = _getSetFollowNFTURITypedDataHash(newProfileId, MOCK_URI, nonce, deadline);
_setFollowNFTURIWithSig(
DataTypes.SetFollowNFTURIWithSigData({
delegatedSigner: address(0),
profileId: newProfileId,
followNFTURI: MOCK_URI,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockPost() internal override {
bytes32 digest = _getPostTypedDataHash(mockPostData, nonce, deadline);
_postWithSig(
_buildPostWithSigData({
delegatedSigner: address(0),
postData: mockPostData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockComment() internal override {
mockCommentData.pubIdPointed = postId;
bytes32 digest = _getCommentTypedDataHash(mockCommentData, nonce, deadline);
_commentWithSig(
_buildCommentWithSigData({
delegatedSigner: address(0),
commentData: mockCommentData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockMirror() internal override {
mockMirrorData.pubIdPointed = postId;
bytes32 digest = _getMirrorTypedDataHash(mockMirrorData, nonce, deadline);
_mirrorWithSig(
_buildMirrorWithSigData({
delegatedSigner: address(0),
mirrorData: mockMirrorData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockBurn() internal override {
bytes32 digest = _getBurnTypedDataHash(newProfileId, nonce, deadline);
_burnWithSig({
profileId: newProfileId,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
});
}
function _mockFollow() internal override {
bytes32 digest = _getFollowTypedDataHash(
_toUint256Array(newProfileId),
_toBytesArray(''),
nonce,
deadline
);
uint256[] memory nftIds = _followWithSig(
_buildFollowWithSigData({
delegatedSigner: address(0),
follower: otherSigner,
profileIds: _toUint256Array(newProfileId),
datas: _toBytesArray(''),
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
}
function _mockCollect() internal override {
bytes32 digest = _getCollectTypedDataHash(
mockCollectData.profileId,
mockCollectData.pubId,
mockCollectData.data,
nonce,
deadline
);
_collectWithSig(
_buildCollectWithSigData({
delegatedSigner: address(0),
collectData: mockCollectData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
// Methods that cannot be called with sig
function testCannotTransferProfileWhilePaused() public override {}
function testCannotCreateProfileWhilePaused() public override {}
}
contract MultiStateHubTest_PublishingPausedState_Direct is BaseTest {
uint256 postId;
function setUp() public virtual override {
super.setUp();
vm.prank(profileOwner);
postId = _post(mockPostData);
vm.prank(governance);
_setState(DataTypes.ProtocolState.PublishingPaused);
}
// TODO: Consider extracting these mock actions functions somewhere because they're used in several places
function _mockSetFollowModule() internal virtual {
_setFollowModule(profileOwner, newProfileId, address(0), '');
}
function _mockSetDelegatedExecutorApproval() internal virtual {
address executor = otherSigner;
bool approved = true;
_setDelegatedExecutorApproval(profileOwner, executor, approved);
}
function _mockSetProfileImageURI() internal virtual {
_setProfileImageURI(profileOwner, newProfileId, MOCK_URI);
}
function _mockSetFollowNFTURI() internal virtual {
_setFollowNFTURI(profileOwner, newProfileId, MOCK_URI);
}
function _mockPost() internal virtual {
vm.prank(profileOwner);
_post(mockPostData);
}
function _mockComment() internal virtual {
mockCommentData.pubIdPointed = postId;
vm.prank(profileOwner);
_comment(mockCommentData);
}
function _mockMirror() internal virtual {
mockMirrorData.pubIdPointed = postId;
vm.prank(profileOwner);
_mirror(mockMirrorData);
}
function _mockBurn() internal virtual {
_burn(profileOwner, newProfileId);
}
function _mockFollow() internal virtual {
_follow({msgSender: me, onBehalfOf: me, profileId: newProfileId, data: ''});
}
// TODO: The following two functions were copy-pasted from CollectingTest.t.sol
// TODO: Consider extracting them somewhere else to be used by both of tests
function _mockCollect() internal virtual {
vm.prank(profileOwner);
_collect(
mockCollectData.collector,
mockCollectData.profileId,
mockCollectData.pubId,
mockCollectData.data
);
}
// Negatives
function testCanTransferProfileWhilePublishingPaused() public virtual {
_transferProfile({
msgSender: profileOwner,
from: profileOwner,
to: address(111),
tokenId: newProfileId
});
}
function testCanCreateProfileWhilePublishingPaused() public virtual {
_createProfile(address(this));
}
function testCanSetFollowModuleWhilePublishingPaused() public {
_mockSetFollowModule();
}
function testCanSetDelegatedExecutorWhilePublishingPaused() public {
_mockSetDelegatedExecutorApproval();
}
function testCanSetProfileImageURIWhilePublishingPaused() public {
_mockSetProfileImageURI();
}
function testCanSetFollowNFTURIWhilePublishingPaused() public {
_mockSetFollowNFTURI();
}
function testCanBurnWhilePublishingPaused() public {
_mockBurn();
}
function testCanFollowWhilePublishingPaused() public {
_mockFollow();
}
function testCanCollectWhilePublishingPaused() public {
_mockCollect();
}
function testCannotPostWhilePublishingPaused() public {
vm.expectRevert(Errors.PublishingPaused.selector);
_mockPost();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockPost();
}
function testCannotCommentWhilePublishingPaused() public {
vm.expectRevert(Errors.PublishingPaused.selector);
_mockComment();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockComment();
}
function testCannotMirrorWhilePublishingPaused() public {
vm.expectRevert(Errors.PublishingPaused.selector);
_mockMirror();
vm.prank(governance);
_setState(DataTypes.ProtocolState.Unpaused);
_mockMirror();
}
}
contract MultiStateHubTest_PublishingPausedState_WithSig is
MultiStateHubTest_PublishingPausedState_Direct,
SignatureHelpers,
SigSetup
{
// TODO: Consider refactoring this contract somehow cause it's all just pure copy-paste of the PausedState_WithSig
function setUp() public override(MultiStateHubTest_PublishingPausedState_Direct, SigSetup) {
MultiStateHubTest_PublishingPausedState_Direct.setUp();
SigSetup.setUp();
}
function _mockSetFollowModule() internal override {
bytes32 digest = _getSetFollowModuleTypedDataHash(
newProfileId,
address(0),
'',
nonce,
deadline
);
_setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: address(0),
profileId: newProfileId,
followModule: address(0),
followModuleInitData: '',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
// Positives
function _mockSetDelegatedExecutorApproval() internal override {
address onBehalfOf = profileOwner;
address executor = otherSigner;
bytes32 digest = _getSetDelegatedExecutorApprovalTypedDataHash({
onBehalfOf: onBehalfOf,
executor: executor,
approved: true,
nonce: nonce,
deadline: deadline
});
hub.setDelegatedExecutorApprovalWithSig(
_buildSetDelegatedExecutorApprovalWithSigData({
onBehalfOf: onBehalfOf,
executor: executor,
approved: true,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockSetProfileImageURI() internal override {
bytes32 digest = _getSetProfileImageURITypedDataHash(
newProfileId,
MOCK_URI,
nonce,
deadline
);
_setProfileImageURIWithSig(
DataTypes.SetProfileImageURIWithSigData({
delegatedSigner: address(0),
profileId: newProfileId,
imageURI: MOCK_URI,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockSetFollowNFTURI() internal override {
bytes32 digest = _getSetFollowNFTURITypedDataHash(newProfileId, MOCK_URI, nonce, deadline);
_setFollowNFTURIWithSig(
DataTypes.SetFollowNFTURIWithSigData({
delegatedSigner: address(0),
profileId: newProfileId,
followNFTURI: MOCK_URI,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockPost() internal override {
bytes32 digest = _getPostTypedDataHash(mockPostData, nonce, deadline);
_postWithSig(
_buildPostWithSigData({
delegatedSigner: address(0),
postData: mockPostData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockComment() internal override {
mockCommentData.pubIdPointed = postId;
bytes32 digest = _getCommentTypedDataHash(mockCommentData, nonce, deadline);
_commentWithSig(
_buildCommentWithSigData({
delegatedSigner: address(0),
commentData: mockCommentData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockMirror() internal override {
mockMirrorData.pubIdPointed = postId;
bytes32 digest = _getMirrorTypedDataHash(mockMirrorData, nonce, deadline);
_mirrorWithSig(
_buildMirrorWithSigData({
delegatedSigner: address(0),
mirrorData: mockMirrorData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function _mockBurn() internal override {
bytes32 digest = _getBurnTypedDataHash(newProfileId, nonce, deadline);
_burnWithSig({
profileId: newProfileId,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
});
}
function _mockFollow() internal override {
bytes32 digest = _getFollowTypedDataHash(
_toUint256Array(newProfileId),
_toBytesArray(''),
nonce,
deadline
);
uint256[] memory nftIds = _followWithSig(
_buildFollowWithSigData({
delegatedSigner: address(0),
follower: otherSigner,
profileIds: _toUint256Array(newProfileId),
datas: _toBytesArray(''),
sig: _getSigStruct(otherSignerKey, digest, deadline)
})
);
}
function _mockCollect() internal override {
bytes32 digest = _getCollectTypedDataHash(
mockCollectData.profileId,
mockCollectData.pubId,
mockCollectData.data,
nonce,
deadline
);
_collectWithSig(
_buildCollectWithSigData({
delegatedSigner: address(0),
collectData: mockCollectData,
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
// Methods that cannot be called with sig
function testCanTransferProfileWhilePublishingPaused() public override {}
function testCanCreateProfileWhilePublishingPaused() public override {}
}

View File

@@ -4,7 +4,6 @@ pragma solidity ^0.8.13;
import './base/BaseTest.t.sol';
import './helpers/SignatureHelpers.sol';
import {PublishingHelpers} from './helpers/PublishingHelpers.sol';
import {SigSetup} from './helpers/SignatureHelpers.sol';
contract PublishingTest_Post is BaseTest, SignatureHelpers, PublishingHelpers, SigSetup {
function replicateInitData() internal virtual {}
@@ -113,7 +112,7 @@ contract PublishingTest_Post is BaseTest, SignatureHelpers, PublishingHelpers, S
function testCannotPublishIfNonceWasIncrementedWithAnotherAction() public {
assertEq(_getSigNonce(profileOwner), nonce, 'Wrong nonce before posting');
uint256 expectedPubId = _getPubCount(firstProfileId) + 1;
uint256 expectedPubId = _getPubCount(newProfileId) + 1;
uint256 pubId = _publishWithSig({
delegatedSigner: address(0),
@@ -142,14 +141,14 @@ contract PublishingTest_Post is BaseTest, SignatureHelpers, PublishingHelpers, S
// positives
function testPublish() public {
uint256 expectedPubId = _getPubCount(firstProfileId) + 1;
uint256 expectedPubId = _getPubCount(newProfileId) + 1;
vm.prank(profileOwner);
uint256 pubId = _publish();
assertEq(pubId, expectedPubId);
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, pubId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, pubId);
_verifyPublication(pub, _expectedPubFromInitData());
}
@@ -158,19 +157,19 @@ contract PublishingTest_Post is BaseTest, SignatureHelpers, PublishingHelpers, S
mockPostData.referenceModuleInitData = abi.encode(1);
replicateInitData();
uint256 expectedPubId = _getPubCount(firstProfileId) + 1;
uint256 expectedPubId = _getPubCount(newProfileId) + 1;
vm.prank(profileOwner);
uint256 pubId = _publish();
assertEq(pubId, expectedPubId);
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, pubId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, pubId);
_verifyPublication(pub, _expectedPubFromInitData());
}
function testPublishWithSig() public {
uint256 expectedPubId = _getPubCount(firstProfileId) + 1;
uint256 expectedPubId = _getPubCount(newProfileId) + 1;
uint256 pubId = _publishWithSig({
delegatedSigner: address(0),
@@ -178,36 +177,34 @@ contract PublishingTest_Post is BaseTest, SignatureHelpers, PublishingHelpers, S
});
assertEq(pubId, expectedPubId);
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, pubId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, pubId);
_verifyPublication(pub, _expectedPubFromInitData());
}
function testExecutorPublish() public {
vm.prank(profileOwner);
_setDelegatedExecutorApproval(otherSigner, true);
_setDelegatedExecutorApproval(profileOwner, otherSigner, true);
uint256 expectedPubId = _getPubCount(firstProfileId) + 1;
uint256 expectedPubId = _getPubCount(newProfileId) + 1;
vm.prank(otherSigner);
uint256 pubId = _publish();
assertEq(pubId, expectedPubId);
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, pubId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, pubId);
_verifyPublication(pub, _expectedPubFromInitData());
}
function testExecutorPublishWithSig() public {
vm.prank(profileOwner);
_setDelegatedExecutorApproval(otherSigner, true);
_setDelegatedExecutorApproval(profileOwner, otherSigner, true);
uint256 expectedPubId = _getPubCount(firstProfileId) + 1;
uint256 expectedPubId = _getPubCount(newProfileId) + 1;
uint256 pubId = _publishWithSig({
delegatedSigner: otherSigner,
signerPrivKey: otherSignerKey
});
assertEq(pubId, expectedPubId);
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, pubId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, pubId);
_verifyPublication(pub, _expectedPubFromInitData());
}
}
@@ -264,7 +261,7 @@ contract PublishingTest_Comment is PublishingTest_Post {
// negatives
function testCannotCommentOnNonExistentPublication() public {
uint256 nonExistentPubId = _getPubCount(firstProfileId) + 10;
uint256 nonExistentPubId = _getPubCount(newProfileId) + 10;
replicateInitData();
mockCommentData.pubIdPointed = nonExistentPubId;
@@ -275,7 +272,7 @@ contract PublishingTest_Comment is PublishingTest_Post {
}
function testCannotCommentWithSigOnNonExistentPublication() public {
uint256 nonExistentPubId = _getPubCount(firstProfileId) + 10;
uint256 nonExistentPubId = _getPubCount(newProfileId) + 10;
replicateInitData();
mockCommentData.pubIdPointed = nonExistentPubId;
@@ -285,7 +282,7 @@ contract PublishingTest_Comment is PublishingTest_Post {
}
function testCannotCommentOnTheSamePublicationBeingCreated() public {
uint256 nextPubId = _getPubCount(firstProfileId) + 1;
uint256 nextPubId = _getPubCount(newProfileId) + 1;
replicateInitData();
mockCommentData.pubIdPointed = nextPubId;
@@ -296,7 +293,7 @@ contract PublishingTest_Comment is PublishingTest_Post {
}
function testCannotCommentWithSigOnTheSamePublicationBeingCreated() public {
uint256 nextPubId = _getPubCount(firstProfileId) + 1;
uint256 nextPubId = _getPubCount(newProfileId) + 1;
replicateInitData();
mockCommentData.pubIdPointed = nextPubId;
@@ -316,7 +313,7 @@ contract PublishingTest_Comment is PublishingTest_Post {
vm.prank(profileOwner);
uint256 commentPubId = _publish();
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, commentPubId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, commentPubId);
_verifyPublication(pub, _expectedPubFromInitData());
}
}
@@ -376,7 +373,7 @@ contract PublishingTest_Mirror is PublishingTest_Post {
// negatives
function testCannotMirrorNonExistentPublication() public {
uint256 nonExistentPubId = _getPubCount(firstProfileId) + 10;
uint256 nonExistentPubId = _getPubCount(newProfileId) + 10;
replicateInitData();
mockMirrorData.pubIdPointed = nonExistentPubId;
@@ -387,7 +384,7 @@ contract PublishingTest_Mirror is PublishingTest_Post {
}
function testCannotMirrorWithSigNonExistentPublication() public {
uint256 nonExistentPubId = _getPubCount(firstProfileId) + 10;
uint256 nonExistentPubId = _getPubCount(newProfileId) + 10;
replicateInitData();
mockMirrorData.pubIdPointed = nonExistentPubId;
@@ -406,7 +403,7 @@ contract PublishingTest_Mirror is PublishingTest_Post {
vm.prank(profileOwner);
uint256 secondMirrorId = _publish();
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, secondMirrorId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, secondMirrorId);
mockMirrorData.pubIdPointed = postId; // We're expecting a mirror to point at the original post ID
_verifyPublication(pub, _expectedPubFromInitData(mockMirrorData));
}
@@ -422,7 +419,7 @@ contract PublishingTest_Mirror is PublishingTest_Post {
signerPrivKey: profileOwnerKey
});
DataTypes.PublicationStruct memory pub = _getPub(firstProfileId, secondMirrorId);
DataTypes.PublicationStruct memory pub = _getPub(newProfileId, secondMirrorId);
mockMirrorData.pubIdPointed = postId; // We're expecting a mirror to point at the original post ID
_verifyPublication(pub, _expectedPubFromInitData(mockMirrorData));
}

View File

@@ -0,0 +1,182 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import './base/BaseTest.t.sol';
import '../../contracts/mocks/MockFollowModule.sol';
import './helpers/SignatureHelpers.sol';
// TODO: Refactor out all `hub.` calls (if we decide to go this route)
contract SetFollowModuleTest is BaseTest, SignatureHelpers, SigSetup {
address mockFollowModule;
function setUp() public virtual override(SigSetup, TestSetup) {
TestSetup.setUp();
SigSetup.setUp();
mockFollowModule = address(new MockFollowModule());
vm.prank(governance);
hub.whitelistFollowModule(mockFollowModule, true);
}
function _setFollowModulehWithSig(address delegatedSigner, uint256 signerPrivKey)
internal
virtual
{
_setFollowModulehWithSig(delegatedSigner, signerPrivKey, deadline, deadline);
}
function _setFollowModulehWithSig(
address delegatedSigner,
uint256 signerPrivKey,
uint256 digestDeadline,
uint256 sigDeadline
) internal virtual {
bytes32 digest = _getSetFollowModuleTypedDataHash(
newProfileId,
mockFollowModule,
abi.encode(1),
nonce,
digestDeadline
);
hub.setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: delegatedSigner,
profileId: newProfileId,
followModule: mockFollowModule,
followModuleInitData: abi.encode(1),
sig: _getSigStruct(signerPrivKey, digest, sigDeadline)
})
);
}
// Negatives
function testCannotSetFollowModuleNotExecutor() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
hub.setFollowModule(newProfileId, address(0), '');
}
function testCannotSetFollowModuleNotWhitelisted() public {
vm.expectRevert(Errors.FollowModuleNotWhitelisted.selector);
vm.prank(profileOwner);
hub.setFollowModule(newProfileId, address(1), '');
}
function testCannotSetFollowModuleWithWrongInitData() public {
vm.expectRevert(bytes(''));
vm.prank(profileOwner);
hub.setFollowModule(newProfileId, mockFollowModule, '');
}
// Positives
function testSetFollowModule() public {
vm.prank(profileOwner);
hub.setFollowModule(newProfileId, mockFollowModule, abi.encode(1));
assertEq(hub.getFollowModule(newProfileId), mockFollowModule);
vm.prank(profileOwner);
hub.setFollowModule(newProfileId, address(0), '');
assertEq(hub.getFollowModule(newProfileId), address(0));
}
function testExecutorSetFollowModule() public {
assertEq(hub.getFollowModule(newProfileId), address(0));
vm.prank(profileOwner);
hub.setDelegatedExecutorApproval(otherSigner, true);
address mockFollowModule = address(new MockFollowModule());
vm.prank(governance);
hub.whitelistFollowModule(mockFollowModule, true);
vm.prank(otherSigner);
hub.setFollowModule(newProfileId, mockFollowModule, abi.encode(1));
assertEq(hub.getFollowModule(newProfileId), mockFollowModule);
}
// Meta-tx
// Negatives
function testCannotSetFollowModuleNotWhitelistedWithSig() public {
vm.expectRevert(Errors.FollowModuleNotWhitelisted.selector);
bytes32 digest = _getSetFollowModuleTypedDataHash(
newProfileId,
address(1),
'',
nonce,
deadline
);
hub.setFollowModuleWithSig(
DataTypes.SetFollowModuleWithSigData({
delegatedSigner: address(0),
profileId: newProfileId,
followModule: address(1),
followModuleInitData: '',
sig: _getSigStruct(profileOwnerKey, digest, deadline)
})
);
}
function testCannotPublishWithSigInvalidSigner() public {
vm.expectRevert(Errors.SignatureInvalid.selector);
_setFollowModulehWithSig({delegatedSigner: address(0), signerPrivKey: otherSignerKey});
}
function testCannotPublishWithSigInvalidNonce() public {
nonce = _getSigNonce(otherSigner) + 1;
vm.expectRevert(Errors.SignatureInvalid.selector);
_setFollowModulehWithSig({delegatedSigner: address(0), signerPrivKey: otherSignerKey});
}
function testCannotPublishWithSigInvalidDeadline() public {
vm.expectRevert(Errors.SignatureInvalid.selector);
_setFollowModulehWithSig({
delegatedSigner: address(0),
signerPrivKey: profileOwnerKey,
digestDeadline: type(uint256).max,
sigDeadline: block.timestamp + 10
});
}
function testCannotPublishIfNonceWasIncrementedWithAnotherAction() public {
assertEq(_getSigNonce(profileOwner), nonce, 'Wrong nonce before posting');
_setFollowModulehWithSig({delegatedSigner: address(0), signerPrivKey: profileOwnerKey});
assertTrue(_getSigNonce(profileOwner) != nonce, 'Wrong nonce after posting');
vm.expectRevert(Errors.SignatureInvalid.selector);
_setFollowModulehWithSig({delegatedSigner: address(0), signerPrivKey: profileOwnerKey});
}
function testCannotPublishWithSigExpiredDeadline() public {
deadline = 10;
vm.warp(20);
vm.expectRevert(Errors.SignatureExpired.selector);
_setFollowModulehWithSig({delegatedSigner: address(0), signerPrivKey: otherSignerKey});
}
function testCannotPublishWithSigNotExecutor() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
_setFollowModulehWithSig({delegatedSigner: otherSigner, signerPrivKey: otherSignerKey});
}
function testSetFollowModuleWithSigNotExecutorFails() public {
vm.expectRevert(Errors.ExecutorInvalid.selector);
_setFollowModulehWithSig({delegatedSigner: otherSigner, signerPrivKey: otherSignerKey});
}
// Postivies
function testPublishWithSig() public {
assertEq(hub.getFollowModule(newProfileId), address(0));
_setFollowModulehWithSig({delegatedSigner: address(0), signerPrivKey: profileOwnerKey});
assertEq(hub.getFollowModule(newProfileId), mockFollowModule);
}
function testExecutorPublishWithSig() public {
_setDelegatedExecutorApproval(profileOwner, otherSigner, true);
assertEq(hub.getFollowModule(newProfileId), address(0));
_setFollowModulehWithSig({delegatedSigner: otherSigner, signerPrivKey: otherSignerKey});
assertEq(hub.getFollowModule(newProfileId), mockFollowModule);
}
}

View File

@@ -93,7 +93,7 @@ contract BaseTest is TestSetup {
return _calculateDigest(structHash);
}
function _getSetFollowNFTURITypedDatahash(
function _getSetFollowNFTURITypedDataHash(
uint256 profileId,
string memory followNFTURI,
uint256 nonce,
@@ -111,6 +111,17 @@ contract BaseTest is TestSetup {
return _calculateDigest(structHash);
}
function _getBurnTypedDataHash(
uint256 profileId,
uint256 nonce,
uint256 deadline
) internal view returns (bytes32) {
bytes32 structHash = keccak256(
abi.encode(BURN_WITH_SIG_TYPEHASH, profileId, nonce, deadline)
);
return _calculateDigest(structHash);
}
function _getPostTypedDataHash(
uint256 profileId,
string memory contentURI,
@@ -385,24 +396,21 @@ contract BaseTest is TestSetup {
return hub.collectWithSig(collectWithSigData);
}
function _setDelegatedExecutorApproval(address executor, bool approved) internal {
hub.setDelegatedExecutorApproval(executor, approved);
function _follow(
address msgSender,
address onBehalfOf,
uint256 profileId,
bytes memory data
) internal returns (uint256[] memory) {
vm.prank(msgSender);
return hub.follow(onBehalfOf, _toUint256Array(profileId), _toBytesArray(data));
}
function _getPub(uint256 profileId, uint256 pubId)
function _followWithSig(DataTypes.FollowWithSigData memory vars)
internal
view
returns (DataTypes.PublicationStruct memory)
returns (uint256[] memory)
{
return hub.getPub(profileId, pubId);
}
function _getSigNonce(address signer) internal view returns (uint256) {
return hub.sigNonces(signer);
}
function _getPubCount(uint256 profileId) internal view returns (uint256) {
return hub.getPubCount(profileId);
return hub.followWithSig(vars);
}
function _createProfile(address newProfileOwner) internal returns (uint256) {
@@ -461,7 +469,60 @@ contract BaseTest is TestSetup {
function _setFollowModuleWithSig(DataTypes.SetFollowModuleWithSigData memory vars) internal {
hub.setFollowModuleWithSig(vars);
}
function _setProfileImageURI(
address msgSender,
uint256 profileId,
string memory imageURI
) internal {
vm.prank(msgSender);
hub.setProfileImageURI(profileId, imageURI);
}
function _setProfileImageURIWithSig(DataTypes.SetProfileImageURIWithSigData memory vars)
internal
{
hub.setProfileImageURIWithSig(vars);
}
function _setFollowNFTURI(
address msgSender,
uint256 profileId,
string memory followNFTURI
) internal {
vm.prank(msgSender);
hub.setFollowNFTURI(profileId, followNFTURI);
}
function _setFollowNFTURIWithSig(DataTypes.SetFollowNFTURIWithSigData memory vars) internal {
hub.setFollowNFTURIWithSig(vars);
}
function _burn(address msgSender, uint256 profileId) internal {
vm.prank(msgSender);
hub.burn(profileId);
}
function _burnWithSig(uint256 profileId, DataTypes.EIP712Signature memory sig) internal {
hub.burnWithSig(profileId, sig);
}
function _getPub(uint256 profileId, uint256 pubId)
internal
view
returns (DataTypes.PublicationStruct memory)
{
return hub.getPub(profileId, pubId);
}
function _getSigNonce(address signer) internal view returns (uint256) {
return hub.sigNonces(signer);
}
function _getPubCount(uint256 profileId) internal view returns (uint256) {
return hub.getPubCount(profileId);
}
function _getCollectCount(uint256 profileId, uint256 pubId) internal view returns (uint256) {
address collectNft = hub.getCollectNFT(profileId, pubId);
if (collectNft == address(0)) {

View File

@@ -4,34 +4,50 @@ pragma solidity ^0.8.13;
import 'forge-std/Test.sol';
// Deployments
import '../../../contracts/core/LensHub.sol';
import '../../../contracts/core/FollowNFT.sol';
import '../../../contracts/core/CollectNFT.sol';
import '../../../contracts/upgradeability/TransparentUpgradeableProxy.sol';
import '../../../contracts/libraries/DataTypes.sol';
import '../../../contracts/libraries/Constants.sol';
import '../../../contracts/libraries/Errors.sol';
import '../../../contracts/libraries/GeneralLib.sol';
import '../../../contracts/libraries/ProfileTokenURILogic.sol';
import '../../../contracts/mocks/MockCollectModule.sol';
import '../../../contracts/mocks/MockReferenceModule.sol';
import {ILensHub} from 'contracts/interfaces/ILensHub.sol';
import {LensHub} from 'contracts/core/LensHub.sol';
import {FollowNFT} from 'contracts/core/FollowNFT.sol';
import {CollectNFT} from 'contracts/core/CollectNFT.sol';
import {ModuleGlobals} from 'contracts/core/modules/ModuleGlobals.sol';
import {TransparentUpgradeableProxy} from 'contracts/upgradeability/TransparentUpgradeableProxy.sol';
import {DataTypes} from 'contracts/libraries/DataTypes.sol';
import 'contracts/libraries/Constants.sol';
import {Errors} from 'contracts/libraries/Errors.sol';
import {GeneralLib} from 'contracts/libraries/GeneralLib.sol';
import {ProfileTokenURILogic} from 'contracts/libraries/ProfileTokenURILogic.sol';
import {MockCollectModule} from 'contracts/mocks/MockCollectModule.sol';
import {MockReferenceModule} from 'contracts/mocks/MockReferenceModule.sol';
import '../helpers/ForkManagement.sol';
import '../constants.sol';
contract TestSetup is Test {
uint256 constant firstProfileId = 1;
address constant deployer = address(1);
// UserOne is the test address, replaced with "me."
address constant governance = address(2);
contract TestSetup is Test, ForkManagement {
using stdJson for string;
string forkEnv;
bool fork;
string network;
string json;
uint256 forkBlockNumber;
uint256 newProfileId;
address deployer;
address governance;
address treasury;
string constant MOCK_URI = 'ipfs://QmUXfQWe43RKx31VzA2BnbwhSMW8WuaJvszFWChD59m76U';
string constant mockHandle = 'handle.lens';
string constant mockURI = 'ipfs://QmUXfQWe43RKx31VzA2BnbwhSMW8WuaJvszFWChD59m76U';
uint256 constant profileOwnerKey = 0x04546b;
uint256 constant otherSignerKey = 0x737562;
uint256 constant profileOwnerKey = 0x04546b;
address immutable profileOwner = vm.addr(profileOwnerKey);
address immutable otherSigner = vm.addr(otherSignerKey);
address immutable me = address(this);
address profileOwner = vm.addr(profileOwnerKey);
address otherSigner = vm.addr(otherSignerKey);
address me = address(this);
bytes32 domainSeparator;
uint16 TREASURY_FEE_BPS;
uint16 constant TREASURY_FEE_MAX_BPS = 10000;
address hubProxyAddr;
CollectNFT collectNFT;
FollowNFT followNFT;
LensHub hubImpl;
@@ -39,6 +55,7 @@ contract TestSetup is Test {
LensHub hub;
MockCollectModule mockCollectModule;
MockReferenceModule mockReferenceModule;
ModuleGlobals moduleGlobals;
DataTypes.CreateProfileData mockCreateProfileData;
@@ -47,14 +64,112 @@ contract TestSetup is Test {
DataTypes.MirrorData mockMirrorData;
DataTypes.CollectData mockCollectData;
function setUp() public virtual {
// Start deployments.
function isEnvSet(string memory key) internal returns (bool) {
try vm.envString(key) {
return true;
} catch {
return false;
}
}
constructor() {
// TODO: Replace with envOr when it's released
forkEnv = isEnvSet('TESTING_FORK') ? vm.envString('TESTING_FORK') : '';
if (bytes(forkEnv).length > 0) {
fork = true;
console.log('\n\n Testing using %s fork', forkEnv);
json = loadJson();
network = getNetwork(json, forkEnv);
if (isEnvSet('FORK_BLOCK')) {
forkBlockNumber = vm.envUint('FORK_BLOCK');
vm.createSelectFork(network, forkBlockNumber);
console.log('Fork Block number (FIXED BLOCK):', forkBlockNumber);
} else {
vm.createSelectFork(network);
forkBlockNumber = block.number;
console.log('Fork Block number:', forkBlockNumber);
}
checkNetworkParams(json, forkEnv);
loadBaseAddresses(forkEnv);
} else {
deployBaseContracts();
}
///////////////////////////////////////// Start governance actions.
vm.startPrank(governance);
if (hub.getState() != DataTypes.ProtocolState.Unpaused)
hub.setState(DataTypes.ProtocolState.Unpaused);
// Whitelist the test contract as a profile creator
hub.whitelistProfileCreator(me, true);
vm.stopPrank();
///////////////////////////////////////// End governance actions.
}
// TODO: Replace with forge-std/StdJson.sol::keyExists(...) when/if this PR is approved:
// https://github.com/foundry-rs/forge-std/pull/226
function keyExists(string memory key) internal returns (bool) {
return json.parseRaw(key).length > 0;
}
function loadBaseAddresses(string memory targetEnv) internal virtual {
bytes32 PROXY_IMPLEMENTATION_STORAGE_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
console.log('targetEnv:', targetEnv);
hubProxyAddr = json.readAddress(string(abi.encodePacked('.', targetEnv, '.LensHubProxy')));
console.log('hubProxyAddr:', hubProxyAddr);
hub = LensHub(hubProxyAddr);
console.log('Hub:', address(hub));
address followNFTAddr = hub.getFollowNFTImpl();
address collectNFTAddr = hub.getCollectNFTImpl();
address hubImplAddr = address(
uint160(uint256(vm.load(hubProxyAddr, PROXY_IMPLEMENTATION_STORAGE_SLOT)))
);
console.log('Found hubImplAddr:', hubImplAddr);
hubImpl = LensHub(hubImplAddr);
followNFT = FollowNFT(followNFTAddr);
collectNFT = CollectNFT(collectNFTAddr);
hubAsProxy = TransparentUpgradeableProxy(payable(address(hub)));
moduleGlobals = ModuleGlobals(
json.readAddress(string(abi.encodePacked('.', targetEnv, '.ModuleGlobals')))
);
newProfileId = uint256(vm.load(hubProxyAddr, bytes32(uint256(22)))) + 1;
console.log('newProfileId:', newProfileId);
deployer = address(1);
governance = hub.getGovernance();
treasury = moduleGlobals.getTreasury();
TREASURY_FEE_BPS = moduleGlobals.getTreasuryFee();
}
function deployBaseContracts() internal {
newProfileId = FIRST_PROFILE_ID;
deployer = address(1);
governance = address(2);
TREASURY_FEE_BPS = 50;
///////////////////////////////////////// Start deployments.
vm.startPrank(deployer);
// Precompute needed addresss.
address followNFTAddr = computeCreateAddress(deployer, 1);
address collectNFTAddr = computeCreateAddress(deployer, 2);
address hubProxyAddr = computeCreateAddress(deployer, 3);
hubProxyAddr = computeCreateAddress(deployer, 3);
// Deploy implementation contracts.
hubImpl = new LensHub(followNFTAddr, collectNFTAddr);
@@ -77,27 +192,23 @@ contract TestSetup is Test {
// Deploy the MockReferenceModule.
mockReferenceModule = new MockReferenceModule();
// End deployments.
vm.stopPrank();
///////////////////////////////////////// End deployments.
// Start governance actions.
vm.startPrank(governance);
// Set the state to unpaused.
hub.setState(DataTypes.ProtocolState.Unpaused);
// Whitelist the FreeCollectModule.
hub.whitelistCollectModule(address(mockCollectModule), true);
// Whitelist the MockReferenceModule.
hub.whitelistReferenceModule(address(mockReferenceModule), true);
// Whitelist the test contract as a profile creator
hub.whitelistProfileCreator(me, true);
// End governance actions.
vm.stopPrank();
}
function setUp() public virtual {
// Compute the domain separator.
domainSeparator = keccak256(
abi.encode(
@@ -112,16 +223,16 @@ contract TestSetup is Test {
// precompute basic profile creaton data.
mockCreateProfileData = DataTypes.CreateProfileData({
to: profileOwner,
imageURI: mockURI,
imageURI: MOCK_URI,
followModule: address(0),
followModuleInitData: '',
followNFTURI: mockURI
followNFTURI: MOCK_URI
});
// Precompute basic post data.
mockPostData = DataTypes.PostData({
profileId: firstProfileId,
contentURI: mockURI,
profileId: newProfileId,
contentURI: MOCK_URI,
collectModule: address(mockCollectModule),
collectModuleInitData: abi.encode(1),
referenceModule: address(0),
@@ -130,10 +241,10 @@ contract TestSetup is Test {
// Precompute basic comment data.
mockCommentData = DataTypes.CommentData({
profileId: firstProfileId,
contentURI: mockURI,
profileIdPointed: firstProfileId,
pubIdPointed: 1,
profileId: newProfileId,
contentURI: MOCK_URI,
profileIdPointed: newProfileId,
pubIdPointed: FIRST_PUB_ID,
referenceModuleData: '',
collectModule: address(mockCollectModule),
collectModuleInitData: abi.encode(1),
@@ -143,9 +254,9 @@ contract TestSetup is Test {
// Precompute basic mirror data.
mockMirrorData = DataTypes.MirrorData({
profileId: firstProfileId,
profileIdPointed: firstProfileId,
pubIdPointed: 1,
profileId: newProfileId,
profileIdPointed: newProfileId,
pubIdPointed: FIRST_PUB_ID,
referenceModuleData: '',
referenceModule: address(0),
referenceModuleInitData: ''
@@ -154,8 +265,8 @@ contract TestSetup is Test {
// Precompute basic collect data.
mockCollectData = DataTypes.CollectData({
collector: profileOwner,
profileId: firstProfileId,
pubId: 1,
profileId: newProfileId,
pubId: FIRST_PUB_ID,
data: ''
});

View File

@@ -149,10 +149,10 @@ contract UpgradeForkTest is BaseTest {
// precompute basic profile creaton data.
mockCreateProfileData = DataTypes.CreateProfileData({
to: me,
imageURI: mockURI,
imageURI: MOCK_URI,
followModule: address(0),
followModuleInitData: abi.encode(1),
followNFTURI: mockURI
followNFTURI: MOCK_URI
});
OldCreateProfileData memory oldCreateProfileData = OldCreateProfileData(
@@ -374,16 +374,16 @@ contract UpgradeForkTest is BaseTest {
// precompute basic profile creaton data.
mockCreateProfileData = DataTypes.CreateProfileData({
to: me,
imageURI: mockURI,
imageURI: MOCK_URI,
followModule: address(0),
followModuleInitData: abi.encode(1),
followNFTURI: mockURI
followNFTURI: MOCK_URI
});
// Precompute basic post data.
mockPostData = DataTypes.PostData({
profileId: 0,
contentURI: mockURI,
contentURI: MOCK_URI,
collectModule: address(0),
collectModuleInitData: abi.encode(1),
referenceModule: address(0),
@@ -393,8 +393,8 @@ contract UpgradeForkTest is BaseTest {
// Precompute basic comment data.
mockCommentData = DataTypes.CommentData({
profileId: 0,
contentURI: mockURI,
profileIdPointed: firstProfileId,
contentURI: MOCK_URI,
profileIdPointed: newProfileId,
pubIdPointed: 1,
referenceModuleData: '',
collectModule: address(0),
@@ -406,7 +406,7 @@ contract UpgradeForkTest is BaseTest {
// Precompute basic mirror data.
mockMirrorData = DataTypes.MirrorData({
profileId: 0,
profileIdPointed: firstProfileId,
profileIdPointed: newProfileId,
pubIdPointed: 1,
referenceModuleData: '',
referenceModule: address(0),

View File

@@ -6,8 +6,6 @@ import 'forge-std/Test.sol';
import 'contracts/libraries/DataTypes.sol';
contract CollectingHelpers is TestSetup {
using Strings for uint256;
CollectNFT _collectNftAfter;
function _checkCollectNFTBefore() internal returns (uint256) {
@@ -41,24 +39,24 @@ contract CollectingHelpers is TestSetup {
assertEq(_collectNftAfter.symbol(), _expectedSymbol());
}
function _expectedName() internal view virtual returns (string memory) {
function _expectedName() internal virtual returns (string memory) {
return
string(
abi.encodePacked(
mockCollectData.profileId.toString(),
vm.toString(mockCollectData.profileId),
COLLECT_NFT_NAME_INFIX,
uint256(mockCollectData.pubId).toString()
vm.toString(mockCollectData.pubId)
)
);
}
function _expectedSymbol() internal view virtual returns (string memory) {
function _expectedSymbol() internal virtual returns (string memory) {
return
string(
abi.encodePacked(
mockCollectData.profileId.toString(),
vm.toString(mockCollectData.profileId),
COLLECT_NFT_SYMBOL_INFIX,
uint256(mockCollectData.pubId).toString()
vm.toString(mockCollectData.pubId)
)
);
}

View File

@@ -0,0 +1,35 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import 'forge-std/Script.sol';
contract ForkManagement is Script {
using stdJson for string;
function loadJson() internal returns (string memory) {
string memory root = vm.projectRoot();
string memory path = string.concat(root, '/addresses.json');
string memory json = vm.readFile(path);
return json;
}
function checkNetworkParams(string memory json, string memory targetEnv)
internal
returns (string memory network, uint256 chainId)
{
network = json.readString(string.concat('.', targetEnv, '.network'));
chainId = json.readUint(string.concat('.', targetEnv, '.chainId'));
console.log('\nTarget environment:', targetEnv);
console.log('Network:', network);
if (block.chainid != chainId) revert('Wrong chainId');
console.log('ChainId:', chainId);
}
function getNetwork(string memory json, string memory targetEnv)
internal
returns (string memory)
{
return json.readString(string.concat('.', targetEnv, '.network'));
}
}

View File

@@ -1,3 +1,6 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
import '../../../contracts/libraries/DataTypes.sol';
contract SigSetup {
@@ -159,4 +162,14 @@ contract SignatureHelpers {
sig: sig
});
}
function _buildFollowWithSigData(
address delegatedSigner,
address follower,
uint256[] memory profileIds,
bytes[] memory datas,
DataTypes.EIP712Signature memory sig
) internal pure returns (DataTypes.FollowWithSigData memory) {
return DataTypes.FollowWithSigData(delegatedSigner, follower, profileIds, datas, sig);
}
}