mirror of
https://github.com/lens-protocol/core.git
synced 2026-01-14 16:37:58 -05:00
Merge branch 'feat/foundry' into feat/follow-nfts
This commit is contained in:
92
TestsList.md
92
TestsList.md
@@ -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
17
scripts/getProxyAdmin.sh
Normal 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}"
|
||||
@@ -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));
|
||||
|
||||
@@ -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({
|
||||
|
||||
5
test/foundry/Constants.sol
Normal file
5
test/foundry/Constants.sol
Normal 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;
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
73
test/foundry/GovernanceFunctions.t.sol
Normal file
73
test/foundry/GovernanceFunctions.t.sol
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
182
test/foundry/SetFollowModule.t.sol
Normal file
182
test/foundry/SetFollowModule.t.sol
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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: ''
|
||||
});
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
35
test/foundry/helpers/ForkManagement.sol
Normal file
35
test/foundry/helpers/ForkManagement.sol
Normal 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'));
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user