mirror of
https://github.com/lens-protocol/core.git
synced 2026-04-22 03:02:03 -04:00
Merge pull request #25 from lens-protocol/T-1393/test-misc-profile-metadata-uri-8-tests
T 1393/test misc profile metadata uri 8 tests
This commit is contained in:
16
TestsList.md
16
TestsList.md
@@ -492,18 +492,18 @@ Scenarios
|
||||
Profile Metadata URI
|
||||
Generic
|
||||
Negatives
|
||||
[ ] User two should fail to set profile metadata URI for a profile that is not theirs while they are not the dispatcher
|
||||
[X] User two should fail to set profile metadata URI for a profile that is not theirs while they are not the dispatcher
|
||||
Scenarios
|
||||
[ ] User should set user two as dispatcher, user two should set profile metadata URI for user one's profile, fetched data should be accurate
|
||||
[ ] Setting profile metadata should emit the correct event
|
||||
[ ] Setting profile metadata via dispatcher should emit the correct event
|
||||
[X] User should set user two as dispatcher, user two should set profile metadata URI for user one's profile, fetched data should be accurate
|
||||
[X] Setting profile metadata should emit the correct event
|
||||
[X] Setting profile metadata via dispatcher should emit the correct event
|
||||
Meta-tx
|
||||
Negatives
|
||||
[ ] TestWallet should fail to set profile metadata URI with sig with signature deadline mismatch
|
||||
[ ] TestWallet should fail to set profile metadata URI with sig with invalid deadline
|
||||
[ ] TestWallet should fail to set profile metadata URI with sig with invalid nonce
|
||||
[X] TestWallet should fail to set profile metadata URI with sig with signature deadline mismatch
|
||||
[X] TestWallet should fail to set profile metadata URI with sig with invalid deadline
|
||||
[X] TestWallet should fail to set profile metadata URI with sig with invalid nonce
|
||||
Scenarios
|
||||
[ ] TestWallet should set profile metadata URI with sig, fetched data should be accurate and correct event should be emitted
|
||||
[X] TestWallet should set profile metadata URI with sig, fetched data should be accurate and correct event should be emitted
|
||||
|
||||
Mock Profile Creation Proxy
|
||||
Negatives
|
||||
|
||||
@@ -70,7 +70,7 @@ library ProfileLib {
|
||||
|
||||
/**
|
||||
* @notice Sets the profile image URI for a given profile.
|
||||
*
|
||||
*
|
||||
* @param profileId The profile ID.
|
||||
* @param imageURI The image URI to set.
|
||||
|
||||
@@ -267,6 +267,7 @@ library ProfileLib {
|
||||
sstore(slot, or(calldataload(cdOffset), shl(1, length)))
|
||||
}
|
||||
}
|
||||
emit Events.ProfileMetadataSet(profileId, metadataURI, block.timestamp);
|
||||
}
|
||||
|
||||
function _setFollowModule(
|
||||
|
||||
169
test/foundry/MetaTxNegatives.t.sol
Normal file
169
test/foundry/MetaTxNegatives.t.sol
Normal file
@@ -0,0 +1,169 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.13;
|
||||
|
||||
import './base/BaseTest.t.sol';
|
||||
|
||||
abstract contract MetaTxNegatives is BaseTest {
|
||||
uint256 private constant NO_DEADLINE = type(uint256).max;
|
||||
uint256 private _defaultMetaTxSignerPk;
|
||||
address private _defaultMetaTxSigner;
|
||||
uint256 private _defaultMetaTxSignerNonce;
|
||||
|
||||
function setUp() public virtual override {
|
||||
_defaultMetaTxSignerPk = _getDefaultMetaTxSignerPk();
|
||||
_defaultMetaTxSigner = vm.addr(_defaultMetaTxSignerPk);
|
||||
_defaultMetaTxSignerNonce = _getMetaTxNonce(_defaultMetaTxSigner);
|
||||
}
|
||||
|
||||
// Functions to mandatorily override.
|
||||
|
||||
function _executeMetaTx(
|
||||
uint256 signerPk,
|
||||
uint256 nonce,
|
||||
uint256 deadline
|
||||
) internal virtual;
|
||||
|
||||
function _getDefaultMetaTxSignerPk() internal virtual returns (uint256);
|
||||
|
||||
// Functions to override ONLY if the contract where to execute the MetaTx is not the LensHub.
|
||||
|
||||
function _getMetaTxNonce(address signer) internal virtual returns (uint256) {
|
||||
return _getSigNonce(signer);
|
||||
}
|
||||
|
||||
function _getDomainName() internal virtual returns (bytes memory) {
|
||||
return bytes('Lens Protocol Profiles');
|
||||
}
|
||||
|
||||
function _getRevisionNumber() internal virtual returns (bytes memory) {
|
||||
return bytes('1');
|
||||
}
|
||||
|
||||
function _getVerifyingContract() internal virtual returns (address) {
|
||||
return hubProxyAddr;
|
||||
}
|
||||
|
||||
// Functions for MetaTx Negative test cases.
|
||||
|
||||
function testCannotExecuteMetaTxWhenSignatureHasExpired() public {
|
||||
domainSeparator = _getValidDomainSeparator();
|
||||
uint256 expiredTimestamp = block.timestamp;
|
||||
uint256 mockTimestamp = expiredTimestamp + 69;
|
||||
vm.warp(mockTimestamp);
|
||||
vm.expectRevert(Errors.SignatureExpired.selector);
|
||||
_executeMetaTx({
|
||||
signerPk: _defaultMetaTxSignerPk,
|
||||
nonce: _defaultMetaTxSignerNonce,
|
||||
deadline: expiredTimestamp
|
||||
});
|
||||
}
|
||||
|
||||
function testCannotExecuteMetaTxWhenSignatureNonceIsInvalid() public {
|
||||
domainSeparator = _getValidDomainSeparator();
|
||||
vm.expectRevert(Errors.SignatureInvalid.selector);
|
||||
_executeMetaTx({
|
||||
signerPk: _defaultMetaTxSignerPk,
|
||||
nonce: _defaultMetaTxSignerNonce + 69,
|
||||
deadline: NO_DEADLINE
|
||||
});
|
||||
}
|
||||
|
||||
function testCannotExecuteMetaTxWhenSignatureSignerIsInvalid() public {
|
||||
domainSeparator = _getValidDomainSeparator();
|
||||
vm.expectRevert(Errors.SignatureInvalid.selector);
|
||||
_executeMetaTx({
|
||||
signerPk: 1234569696969,
|
||||
nonce: _defaultMetaTxSignerNonce,
|
||||
deadline: NO_DEADLINE
|
||||
});
|
||||
}
|
||||
|
||||
function testCannotExecuteMetaTxWhenSignatureDomainWasGeneratedWithWrongRevisionNumber()
|
||||
public
|
||||
{
|
||||
domainSeparator = keccak256(
|
||||
abi.encode(
|
||||
EIP712_DOMAIN_TYPEHASH,
|
||||
keccak256(_getDomainName()),
|
||||
keccak256('69696969696969696969696969969696'),
|
||||
block.chainid,
|
||||
_getVerifyingContract()
|
||||
)
|
||||
);
|
||||
vm.expectRevert(Errors.SignatureInvalid.selector);
|
||||
_executeMetaTx({
|
||||
signerPk: _defaultMetaTxSignerPk,
|
||||
nonce: _defaultMetaTxSignerNonce,
|
||||
deadline: NO_DEADLINE
|
||||
});
|
||||
}
|
||||
|
||||
function testCannotExecuteMetaTxWhenSignatureDomainWasGeneratedWithWrongChainId() public {
|
||||
domainSeparator = keccak256(
|
||||
abi.encode(
|
||||
EIP712_DOMAIN_TYPEHASH,
|
||||
keccak256(_getDomainName()),
|
||||
keccak256(_getRevisionNumber()),
|
||||
type(uint256).max,
|
||||
_getVerifyingContract()
|
||||
)
|
||||
);
|
||||
vm.expectRevert(Errors.SignatureInvalid.selector);
|
||||
_executeMetaTx({
|
||||
signerPk: _defaultMetaTxSignerPk,
|
||||
nonce: _defaultMetaTxSignerNonce,
|
||||
deadline: NO_DEADLINE
|
||||
});
|
||||
}
|
||||
|
||||
function testCannotExecuteMetaTxWhenSignatureDomainWasGeneratedWithWrongVerifyingContract()
|
||||
public
|
||||
{
|
||||
domainSeparator = keccak256(
|
||||
abi.encode(
|
||||
EIP712_DOMAIN_TYPEHASH,
|
||||
keccak256(_getDomainName()),
|
||||
keccak256(_getRevisionNumber()),
|
||||
block.chainid,
|
||||
address(0x691234569696969)
|
||||
)
|
||||
);
|
||||
vm.expectRevert(Errors.SignatureInvalid.selector);
|
||||
_executeMetaTx({
|
||||
signerPk: _defaultMetaTxSignerPk,
|
||||
nonce: _defaultMetaTxSignerNonce,
|
||||
deadline: NO_DEADLINE
|
||||
});
|
||||
}
|
||||
|
||||
function testCannotExecuteMetaTxWhenSignatureDomainWasGeneratedWithWrongName() public {
|
||||
domainSeparator = keccak256(
|
||||
abi.encode(
|
||||
EIP712_DOMAIN_TYPEHASH,
|
||||
keccak256('This should be an invalid name :)'),
|
||||
keccak256(_getRevisionNumber()),
|
||||
block.chainid,
|
||||
_getVerifyingContract()
|
||||
)
|
||||
);
|
||||
vm.expectRevert(Errors.SignatureInvalid.selector);
|
||||
_executeMetaTx({
|
||||
signerPk: _defaultMetaTxSignerPk,
|
||||
nonce: _defaultMetaTxSignerNonce,
|
||||
deadline: NO_DEADLINE
|
||||
});
|
||||
}
|
||||
|
||||
function _getValidDomainSeparator() internal virtual returns (bytes32) {
|
||||
return
|
||||
keccak256(
|
||||
abi.encode(
|
||||
EIP712_DOMAIN_TYPEHASH,
|
||||
keccak256(_getDomainName()),
|
||||
keccak256(_getRevisionNumber()),
|
||||
block.chainid,
|
||||
_getVerifyingContract()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -36,11 +36,6 @@ contract MiscTest is BaseTest {
|
||||
hub.setFollowNFTURI(newProfileId, MOCK_URI);
|
||||
}
|
||||
|
||||
function testSetProfileMetadataURINotExecutorFails() public {
|
||||
vm.expectRevert(Errors.ExecutorInvalid.selector);
|
||||
hub.setProfileMetadataURI(newProfileId, MOCK_URI);
|
||||
}
|
||||
|
||||
// Positives
|
||||
function testExecutorSetDefaultProfile() public {
|
||||
assertEq(hub.getDefaultProfile(profileOwner), 0);
|
||||
@@ -72,16 +67,6 @@ contract MiscTest is BaseTest {
|
||||
assertEq(hub.getFollowNFTURI(newProfileId), 'test');
|
||||
}
|
||||
|
||||
function testExecutorSetProfileMetadataURI() public {
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), '');
|
||||
vm.prank(profileOwner);
|
||||
hub.setDelegatedExecutorApproval(otherSigner, true);
|
||||
|
||||
vm.prank(otherSigner);
|
||||
hub.setProfileMetadataURI(newProfileId, MOCK_URI);
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
|
||||
}
|
||||
|
||||
// Meta-tx
|
||||
// Negatives
|
||||
function testSetDefaultProfileWithSigInvalidSignerFails() public {
|
||||
@@ -200,48 +185,6 @@ contract MiscTest is BaseTest {
|
||||
);
|
||||
}
|
||||
|
||||
function testSetProfileMetadataURIWithSigInvalidSignerFails() public {
|
||||
uint256 nonce = 0;
|
||||
uint256 deadline = type(uint256).max;
|
||||
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
|
||||
newProfileId,
|
||||
MOCK_URI,
|
||||
nonce,
|
||||
deadline
|
||||
);
|
||||
|
||||
vm.expectRevert(Errors.SignatureInvalid.selector);
|
||||
hub.setProfileMetadataURIWithSig(
|
||||
DataTypes.SetProfileMetadataURIWithSigData({
|
||||
delegatedSigner: address(0),
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI,
|
||||
sig: _getSigStruct(otherSignerKey, digest, deadline)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function testSetProfileMetadataURIWithSigNotExecutorFails() public {
|
||||
uint256 nonce = 0;
|
||||
uint256 deadline = type(uint256).max;
|
||||
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
|
||||
newProfileId,
|
||||
MOCK_URI,
|
||||
nonce,
|
||||
deadline
|
||||
);
|
||||
|
||||
vm.expectRevert(Errors.ExecutorInvalid.selector);
|
||||
hub.setProfileMetadataURIWithSig(
|
||||
DataTypes.SetProfileMetadataURIWithSigData({
|
||||
delegatedSigner: otherSigner,
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI,
|
||||
sig: _getSigStruct(otherSignerKey, digest, deadline)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// Postivies
|
||||
function testSetDefaultProfileWithSig() public {
|
||||
uint256 nonce = 0;
|
||||
@@ -363,51 +306,4 @@ contract MiscTest is BaseTest {
|
||||
);
|
||||
assertEq(hub.getFollowNFTURI(newProfileId), 'test');
|
||||
}
|
||||
|
||||
function testSetProfileMetadataURIWithSig() public {
|
||||
uint256 nonce = 0;
|
||||
uint256 deadline = type(uint256).max;
|
||||
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
|
||||
newProfileId,
|
||||
MOCK_URI,
|
||||
nonce,
|
||||
deadline
|
||||
);
|
||||
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), '');
|
||||
hub.setProfileMetadataURIWithSig(
|
||||
DataTypes.SetProfileMetadataURIWithSigData({
|
||||
delegatedSigner: address(0),
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI,
|
||||
sig: _getSigStruct(profileOwnerKey, digest, deadline)
|
||||
})
|
||||
);
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
|
||||
}
|
||||
|
||||
function testExecutorSetProfileMetadataURIWithSig() public {
|
||||
vm.prank(profileOwner);
|
||||
hub.setDelegatedExecutorApproval(otherSigner, true);
|
||||
|
||||
uint256 nonce = 0;
|
||||
uint256 deadline = type(uint256).max;
|
||||
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
|
||||
newProfileId,
|
||||
MOCK_URI,
|
||||
nonce,
|
||||
deadline
|
||||
);
|
||||
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), '');
|
||||
hub.setProfileMetadataURIWithSig(
|
||||
DataTypes.SetProfileMetadataURIWithSigData({
|
||||
delegatedSigner: otherSigner,
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI,
|
||||
sig: _getSigStruct(otherSignerKey, digest, deadline)
|
||||
})
|
||||
);
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
|
||||
}
|
||||
}
|
||||
|
||||
137
test/foundry/ProfileMetadataURI.t.sol
Normal file
137
test/foundry/ProfileMetadataURI.t.sol
Normal file
@@ -0,0 +1,137 @@
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
pragma solidity ^0.8.13;
|
||||
|
||||
import './base/BaseTest.t.sol';
|
||||
import './MetaTxNegatives.t.sol';
|
||||
import {Events} from 'contracts/libraries/Events.sol';
|
||||
|
||||
contract ProfileMetadataURITest is BaseTest {
|
||||
function _setProfileMetadataURI(
|
||||
uint256 pk,
|
||||
uint256 profileId,
|
||||
string memory metadataURI
|
||||
) internal virtual {
|
||||
vm.prank(vm.addr(pk));
|
||||
hub.setProfileMetadataURI(profileId, metadataURI);
|
||||
}
|
||||
|
||||
// Negatives
|
||||
function testCannotSetProfileMetadataURINotExecutor() public {
|
||||
vm.expectRevert(Errors.ExecutorInvalid.selector);
|
||||
_setProfileMetadataURI({
|
||||
pk: alienSignerKey,
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI
|
||||
});
|
||||
}
|
||||
|
||||
// Positives
|
||||
function testExecutorSetProfileMetadataURI() public {
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), '');
|
||||
vm.prank(profileOwner);
|
||||
hub.setDelegatedExecutorApproval(otherSigner, true);
|
||||
|
||||
_setProfileMetadataURI({
|
||||
pk: otherSignerKey,
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI
|
||||
});
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
|
||||
}
|
||||
|
||||
function testSetProfileMetadataURI() public {
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), '');
|
||||
|
||||
_setProfileMetadataURI({
|
||||
pk: profileOwnerKey,
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI
|
||||
});
|
||||
assertEq(hub.getProfileMetadataURI(newProfileId), MOCK_URI);
|
||||
}
|
||||
|
||||
// Events
|
||||
function expectProfileMetadataSetEvent() public {
|
||||
vm.expectEmit(true, true, true, true, address(hub));
|
||||
emit Events.ProfileMetadataSet({
|
||||
profileId: newProfileId,
|
||||
metadata: MOCK_URI,
|
||||
timestamp: block.timestamp
|
||||
});
|
||||
}
|
||||
|
||||
function testSetProfileMetadataURI_EmitsProperEvent() public {
|
||||
expectProfileMetadataSetEvent();
|
||||
testSetProfileMetadataURI();
|
||||
}
|
||||
|
||||
function testExecutorSetProfileMetadataURI_EmitsProperEvent() public {
|
||||
expectProfileMetadataSetEvent();
|
||||
testExecutorSetProfileMetadataURI();
|
||||
}
|
||||
}
|
||||
|
||||
contract ProfileMetadataURITest_MetaTx is ProfileMetadataURITest, MetaTxNegatives {
|
||||
mapping(address => uint256) cachedNonceByAddress;
|
||||
|
||||
function setUp() public override(MetaTxNegatives, TestSetup) {
|
||||
TestSetup.setUp();
|
||||
MetaTxNegatives.setUp();
|
||||
|
||||
cachedNonceByAddress[alienSigner] = _getSigNonce(alienSigner);
|
||||
cachedNonceByAddress[otherSigner] = _getSigNonce(otherSigner);
|
||||
cachedNonceByAddress[profileOwner] = _getSigNonce(profileOwner);
|
||||
}
|
||||
|
||||
function _setProfileMetadataURI(
|
||||
uint256 pk,
|
||||
uint256 profileId,
|
||||
string memory metadataURI
|
||||
) internal virtual override {
|
||||
address signer = vm.addr(pk);
|
||||
uint256 nonce = cachedNonceByAddress[signer];
|
||||
uint256 deadline = type(uint256).max;
|
||||
|
||||
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
|
||||
newProfileId,
|
||||
MOCK_URI,
|
||||
nonce,
|
||||
deadline
|
||||
);
|
||||
|
||||
hub.setProfileMetadataURIWithSig(
|
||||
DataTypes.SetProfileMetadataURIWithSigData({
|
||||
delegatedSigner: signer == profileOwner ? address(0) : signer,
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI,
|
||||
sig: _getSigStruct(pk, digest, deadline)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function _executeMetaTx(
|
||||
uint256 signerPk,
|
||||
uint256 nonce,
|
||||
uint256 deadline
|
||||
) internal virtual override {
|
||||
bytes32 digest = _getSetProfileMetadataURITypedDataHash(
|
||||
newProfileId,
|
||||
MOCK_URI,
|
||||
nonce,
|
||||
deadline
|
||||
);
|
||||
|
||||
hub.setProfileMetadataURIWithSig(
|
||||
DataTypes.SetProfileMetadataURIWithSigData({
|
||||
delegatedSigner: address(0),
|
||||
profileId: newProfileId,
|
||||
metadataURI: MOCK_URI,
|
||||
sig: _getSigStruct(signerPk, digest, deadline)
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function _getDefaultMetaTxSignerPk() internal virtual override returns (uint256) {
|
||||
return profileOwnerKey;
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,10 @@ contract TestSetup is Test, ForkManagement {
|
||||
|
||||
uint256 constant otherSignerKey = 0x737562;
|
||||
uint256 constant profileOwnerKey = 0x04546b;
|
||||
uint256 constant alienSignerKey = 0x123456;
|
||||
address immutable profileOwner = vm.addr(profileOwnerKey);
|
||||
address immutable otherSigner = vm.addr(otherSignerKey);
|
||||
address immutable alienSigner = vm.addr(alienSignerKey);
|
||||
address immutable me = address(this);
|
||||
|
||||
bytes32 domainSeparator;
|
||||
|
||||
Reference in New Issue
Block a user