mirror of
https://github.com/lens-protocol/core.git
synced 2026-01-08 21:58:06 -05:00
misc: Removed deprecated functions from PublicActProxy and moved metaTx code into a separate file
This commit is contained in:
@@ -7,60 +7,47 @@ import {Types} from 'contracts/libraries/constants/Types.sol';
|
||||
import {IERC20} from '@openzeppelin/contracts/token/ERC20/IERC20.sol';
|
||||
import {SafeERC20} from '@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol';
|
||||
import {CollectPublicationAction} from 'contracts/modules/act/collect/CollectPublicationAction.sol';
|
||||
import {BaseProfilePublicationData, IBaseFeeCollectModule} from 'contracts/modules/interfaces/IBaseFeeCollectModule.sol';
|
||||
import {Errors} from 'contracts/libraries/constants/Errors.sol';
|
||||
import {Events} from 'contracts/libraries/constants/Events.sol';
|
||||
import {Typehash} from 'contracts/libraries/constants/Typehash.sol';
|
||||
import {IERC1271} from '@openzeppelin/contracts/interfaces/IERC1271.sol';
|
||||
import {PublicActProxy_MetaTx} from 'contracts/misc/PublicActProxy_MetaTx.sol';
|
||||
|
||||
interface IProtocolSharedRevenueMinFeeMintModule {
|
||||
function getMintFeeParams() external view returns (address, uint256);
|
||||
}
|
||||
// This contract should be the owner/DE of the publicationActionParams.actorProfileId
|
||||
// This contract should be set as publicationActionParams.transactionExecutor
|
||||
// Correct collectNftRecipient should be passed in the publicationActionParams.actionModuleData
|
||||
|
||||
/*
|
||||
Here is an example of PublicationActionParams to pass:
|
||||
|
||||
struct PublicationActionParams {
|
||||
publicationActedProfileId: ---
|
||||
publicationActedId: ---
|
||||
actorProfileId: this contract's profile
|
||||
referrerProfileIds: ---
|
||||
referrerPubIds: ---
|
||||
actionModuleAddress: ---
|
||||
actionModuleData: {
|
||||
collectNftRecipient: who shall receive the NFT
|
||||
collectData: {
|
||||
expectedCurrency: should match what's stored in CollectModule
|
||||
expectedAmount: should match what's stored in CollectModule
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// @title PublicActProxy
|
||||
/// @author LensProtocol
|
||||
/// @notice This contract allows anyone to Act on a publication without holding a profile
|
||||
/// @dev This contract holds a profile (or is a DE of that profile) and acts on behalf of the caller
|
||||
contract PublicActProxy {
|
||||
string constant EIP712_DOMAIN_VERSION = '2';
|
||||
bytes32 constant EIP712_DOMAIN_VERSION_HASH = keccak256(bytes(EIP712_DOMAIN_VERSION));
|
||||
bytes4 constant EIP1271_MAGIC_VALUE = 0x1626ba7e;
|
||||
|
||||
contract PublicActProxy is PublicActProxy_MetaTx {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
ILensHub public immutable HUB;
|
||||
CollectPublicationAction public immutable COLLECT_PUBLICATION_ACTION;
|
||||
|
||||
uint[9] private __gap;
|
||||
mapping(address => uint256) private _nonces; // Slot 10 - to match with MetaTxLib/StorageLib
|
||||
|
||||
constructor(address lensHub, address collectPublicationAction) {
|
||||
HUB = ILensHub(lensHub);
|
||||
COLLECT_PUBLICATION_ACTION = CollectPublicationAction(collectPublicationAction);
|
||||
}
|
||||
|
||||
/*
|
||||
struct PublicationActionParams {
|
||||
publicationActedProfileId: ---
|
||||
publicationActedId: ---
|
||||
actorProfileId: this contract's profile
|
||||
referrerProfileIds: ---
|
||||
referrerPubIds: ---
|
||||
actionModuleAddress: ---
|
||||
actionModuleData: {
|
||||
collectNftRecipient: who shall receive the NFT
|
||||
collectData: {
|
||||
expectedCurrency: should match what's stored in CollectModule
|
||||
expectedAmount: should match what's stored in CollectModule
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// This contract should be the owner/DE of the publicationActionParams.actorProfileId
|
||||
// This contract should be set as publicationActionParams.transactionExecutor
|
||||
// Correct collectNftRecipient should be passed in the publicationActionParams.actionModuleData
|
||||
|
||||
// The free act is pretty simple, but should follow the rules above:
|
||||
/// @notice For actions not involving any ERC20 transfers or approvals from the actor
|
||||
/// @dev This is used in the same way as the general .act() function, while following the rules above.
|
||||
@@ -94,146 +81,6 @@ contract PublicActProxy {
|
||||
_publicAct(publicationActionParams, currency, amount, approveTo, signature.signer);
|
||||
}
|
||||
|
||||
struct PaymentParams {
|
||||
address currency;
|
||||
uint256 amount;
|
||||
address approveTo;
|
||||
}
|
||||
|
||||
function _validatePaidActSignature(
|
||||
Types.EIP712Signature calldata signature,
|
||||
Types.PublicationActionParams calldata publicationActionParams,
|
||||
PaymentParams memory paymentParams
|
||||
) internal {
|
||||
bytes memory encodedAbi = abi.encode(
|
||||
Typehash.PUBLIC_PAID_ACT,
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId,
|
||||
publicationActionParams.actorProfileId,
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerProfileIds),
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerPubIds),
|
||||
publicationActionParams.actionModuleAddress,
|
||||
_encodeUsingEip712Rules(publicationActionParams.actionModuleData),
|
||||
paymentParams.currency,
|
||||
paymentParams.amount,
|
||||
paymentParams.approveTo,
|
||||
_getNonceIncrementAndEmitEvent(signature.signer),
|
||||
signature.deadline
|
||||
);
|
||||
_validateRecoveredAddress(_calculateDigest(keccak256(encodedAbi)), signature);
|
||||
}
|
||||
|
||||
function _validateActSignature(
|
||||
Types.EIP712Signature calldata signature,
|
||||
Types.PublicationActionParams calldata publicationActionParams
|
||||
) internal {
|
||||
_validateRecoveredAddress(
|
||||
_calculateDigest(
|
||||
keccak256(
|
||||
abi.encode(
|
||||
Typehash.ACT,
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId,
|
||||
publicationActionParams.actorProfileId,
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerProfileIds),
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerPubIds),
|
||||
publicationActionParams.actionModuleAddress,
|
||||
_encodeUsingEip712Rules(publicationActionParams.actionModuleData),
|
||||
_getNonceIncrementAndEmitEvent(signature.signer),
|
||||
signature.deadline
|
||||
)
|
||||
)
|
||||
),
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Wrapper for ecrecover to reduce code size, used in meta-tx specific functions.
|
||||
*/
|
||||
function _validateRecoveredAddress(bytes32 digest, Types.EIP712Signature calldata signature) private view {
|
||||
if (block.timestamp > signature.deadline) revert Errors.SignatureExpired();
|
||||
// If the expected address is a contract, check the signature there.
|
||||
if (signature.signer.code.length != 0) {
|
||||
bytes memory concatenatedSig = abi.encodePacked(signature.r, signature.s, signature.v);
|
||||
if (IERC1271(signature.signer).isValidSignature(digest, concatenatedSig) != EIP1271_MAGIC_VALUE) {
|
||||
revert Errors.SignatureInvalid();
|
||||
}
|
||||
} else {
|
||||
address recoveredAddress = ecrecover(digest, signature.v, signature.r, signature.s);
|
||||
if (recoveredAddress == address(0) || recoveredAddress != signature.signer) {
|
||||
revert Errors.SignatureInvalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _encodeUsingEip712Rules(bytes memory bytesValue) private pure returns (bytes32) {
|
||||
return keccak256(bytesValue);
|
||||
}
|
||||
|
||||
function _encodeUsingEip712Rules(uint256[] memory uint256Array) private pure returns (bytes32) {
|
||||
return keccak256(abi.encodePacked(uint256Array));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev This fetches a signer's current nonce and increments it so it's ready for the next meta-tx. Also emits
|
||||
* the `NonceUpdated` event.
|
||||
*
|
||||
* @param signer The address to get and increment the nonce for.
|
||||
*
|
||||
* @return uint256 The current nonce for the given signer prior to being incremented.
|
||||
*/
|
||||
function _getNonceIncrementAndEmitEvent(address signer) private returns (uint256) {
|
||||
uint256 currentNonce;
|
||||
unchecked {
|
||||
currentNonce = _nonces[signer]++;
|
||||
}
|
||||
emit Events.NonceUpdated(signer, currentNonce + 1, block.timestamp);
|
||||
return currentNonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates EIP712 digest based on the current DOMAIN_SEPARATOR.
|
||||
*
|
||||
* @param hashedMessage The message hash from which the digest should be calculated.
|
||||
*
|
||||
* @return bytes32 A 32-byte output representing the EIP712 digest.
|
||||
*/
|
||||
function _calculateDigest(bytes32 hashedMessage) private view returns (bytes32) {
|
||||
return keccak256(abi.encodePacked('\x19\x01', _calculateDomainSeparator(), hashedMessage));
|
||||
}
|
||||
|
||||
function _calculateDomainSeparator() internal view returns (bytes32) {
|
||||
return
|
||||
keccak256(
|
||||
abi.encode(
|
||||
Typehash.EIP712_DOMAIN,
|
||||
keccak256(bytes(name())),
|
||||
EIP712_DOMAIN_VERSION_HASH,
|
||||
block.chainid,
|
||||
address(this)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// For the paid collect to work, additional steps are required:
|
||||
// Collector should set enough allowance to this contract to pay for collect NFT
|
||||
// Funds will be taken from msg.sender
|
||||
// Funds will be approved from this contract to collectModule found in publication storage
|
||||
// DEPRECATED. Use publicPaidAct() function instead.
|
||||
function publicCollect(Types.PublicationActionParams calldata publicationActionParams) external {
|
||||
_publicCollect(publicationActionParams, msg.sender);
|
||||
}
|
||||
|
||||
// DEPRECATED. Use publicPaidActWithSig() function instead.
|
||||
function publicCollectWithSig(
|
||||
Types.PublicationActionParams calldata publicationActionParams,
|
||||
Types.EIP712Signature calldata signature
|
||||
) external {
|
||||
_validateActSignature(signature, publicationActionParams);
|
||||
_publicCollect(publicationActionParams, signature.signer);
|
||||
}
|
||||
|
||||
// Internal functions
|
||||
|
||||
function _publicAct(
|
||||
@@ -249,46 +96,4 @@ contract PublicActProxy {
|
||||
}
|
||||
HUB.act(publicationActionParams);
|
||||
}
|
||||
|
||||
// DEPRECATED:
|
||||
function _publicCollect(
|
||||
Types.PublicationActionParams calldata publicationActionParams,
|
||||
address transactionExecutor
|
||||
) internal {
|
||||
address collectModule = COLLECT_PUBLICATION_ACTION
|
||||
.getCollectData(
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId
|
||||
)
|
||||
.collectModule;
|
||||
|
||||
BaseProfilePublicationData memory collectData = IBaseFeeCollectModule(collectModule).getBasePublicationData(
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId
|
||||
);
|
||||
|
||||
if (collectData.amount > 0) {
|
||||
IERC20(collectData.currency).safeTransferFrom(transactionExecutor, address(this), collectData.amount);
|
||||
IERC20(collectData.currency).safeIncreaseAllowance(collectModule, collectData.amount);
|
||||
}
|
||||
|
||||
HUB.act(publicationActionParams);
|
||||
}
|
||||
|
||||
// View functions
|
||||
|
||||
function nonces(address signer) public view returns (uint256) {
|
||||
return _nonces[signer];
|
||||
}
|
||||
|
||||
/// @dev This function is used to invalidate signatures by incrementing the nonce
|
||||
function incrementNonce(uint8 increment) external {
|
||||
uint256 currentNonce = _nonces[msg.sender];
|
||||
_nonces[msg.sender] = currentNonce + increment;
|
||||
emit Events.NonceUpdated(msg.sender, currentNonce + increment, block.timestamp);
|
||||
}
|
||||
|
||||
function name() public pure returns (string memory) {
|
||||
return 'PublicActProxy';
|
||||
}
|
||||
}
|
||||
|
||||
156
contracts/misc/PublicActProxy_MetaTx.sol
Normal file
156
contracts/misc/PublicActProxy_MetaTx.sol
Normal file
@@ -0,0 +1,156 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity ^0.8.19;
|
||||
|
||||
import {Types} from 'contracts/libraries/constants/Types.sol';
|
||||
import {Typehash} from 'contracts/libraries/constants/Typehash.sol';
|
||||
import {IERC1271} from '@openzeppelin/contracts/interfaces/IERC1271.sol';
|
||||
import {Events} from 'contracts/libraries/constants/Events.sol';
|
||||
import {Errors} from 'contracts/libraries/constants/Errors.sol';
|
||||
|
||||
contract PublicActProxy_MetaTx {
|
||||
string constant EIP712_DOMAIN_VERSION = '2';
|
||||
bytes32 constant EIP712_DOMAIN_VERSION_HASH = keccak256(bytes(EIP712_DOMAIN_VERSION));
|
||||
bytes4 constant EIP1271_MAGIC_VALUE = 0x1626ba7e;
|
||||
|
||||
mapping(address => uint256) private _nonces;
|
||||
|
||||
struct PaymentParams {
|
||||
address currency;
|
||||
uint256 amount;
|
||||
address approveTo;
|
||||
}
|
||||
|
||||
function _validatePaidActSignature(
|
||||
Types.EIP712Signature calldata signature,
|
||||
Types.PublicationActionParams calldata publicationActionParams,
|
||||
PaymentParams memory paymentParams
|
||||
) internal {
|
||||
bytes memory encodedAbi = abi.encode(
|
||||
Typehash.PUBLIC_PAID_ACT,
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId,
|
||||
publicationActionParams.actorProfileId,
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerProfileIds),
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerPubIds),
|
||||
publicationActionParams.actionModuleAddress,
|
||||
_encodeUsingEip712Rules(publicationActionParams.actionModuleData),
|
||||
paymentParams.currency,
|
||||
paymentParams.amount,
|
||||
paymentParams.approveTo,
|
||||
_getNonceIncrementAndEmitEvent(signature.signer),
|
||||
signature.deadline
|
||||
);
|
||||
_validateRecoveredAddress(_calculateDigest(keccak256(encodedAbi)), signature);
|
||||
}
|
||||
|
||||
function _validateActSignature(
|
||||
Types.EIP712Signature calldata signature,
|
||||
Types.PublicationActionParams calldata publicationActionParams
|
||||
) internal {
|
||||
_validateRecoveredAddress(
|
||||
_calculateDigest(
|
||||
keccak256(
|
||||
abi.encode(
|
||||
Typehash.ACT,
|
||||
publicationActionParams.publicationActedProfileId,
|
||||
publicationActionParams.publicationActedId,
|
||||
publicationActionParams.actorProfileId,
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerProfileIds),
|
||||
_encodeUsingEip712Rules(publicationActionParams.referrerPubIds),
|
||||
publicationActionParams.actionModuleAddress,
|
||||
_encodeUsingEip712Rules(publicationActionParams.actionModuleData),
|
||||
_getNonceIncrementAndEmitEvent(signature.signer),
|
||||
signature.deadline
|
||||
)
|
||||
)
|
||||
),
|
||||
signature
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Wrapper for ecrecover to reduce code size, used in meta-tx specific functions.
|
||||
*/
|
||||
function _validateRecoveredAddress(bytes32 digest, Types.EIP712Signature calldata signature) private view {
|
||||
if (block.timestamp > signature.deadline) revert Errors.SignatureExpired();
|
||||
// If the expected address is a contract, check the signature there.
|
||||
if (signature.signer.code.length != 0) {
|
||||
bytes memory concatenatedSig = abi.encodePacked(signature.r, signature.s, signature.v);
|
||||
if (IERC1271(signature.signer).isValidSignature(digest, concatenatedSig) != EIP1271_MAGIC_VALUE) {
|
||||
revert Errors.SignatureInvalid();
|
||||
}
|
||||
} else {
|
||||
address recoveredAddress = ecrecover(digest, signature.v, signature.r, signature.s);
|
||||
if (recoveredAddress == address(0) || recoveredAddress != signature.signer) {
|
||||
revert Errors.SignatureInvalid();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _encodeUsingEip712Rules(bytes memory bytesValue) private pure returns (bytes32) {
|
||||
return keccak256(bytesValue);
|
||||
}
|
||||
|
||||
function _encodeUsingEip712Rules(uint256[] memory uint256Array) private pure returns (bytes32) {
|
||||
return keccak256(abi.encodePacked(uint256Array));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev This fetches a signer's current nonce and increments it so it's ready for the next meta-tx. Also emits
|
||||
* the `NonceUpdated` event.
|
||||
*
|
||||
* @param signer The address to get and increment the nonce for.
|
||||
*
|
||||
* @return uint256 The current nonce for the given signer prior to being incremented.
|
||||
*/
|
||||
function _getNonceIncrementAndEmitEvent(address signer) private returns (uint256) {
|
||||
uint256 currentNonce;
|
||||
unchecked {
|
||||
currentNonce = _nonces[signer]++;
|
||||
}
|
||||
emit Events.NonceUpdated(signer, currentNonce + 1, block.timestamp);
|
||||
return currentNonce;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Calculates EIP712 digest based on the current DOMAIN_SEPARATOR.
|
||||
*
|
||||
* @param hashedMessage The message hash from which the digest should be calculated.
|
||||
*
|
||||
* @return bytes32 A 32-byte output representing the EIP712 digest.
|
||||
*/
|
||||
function _calculateDigest(bytes32 hashedMessage) private view returns (bytes32) {
|
||||
return keccak256(abi.encodePacked('\x19\x01', _calculateDomainSeparator(), hashedMessage));
|
||||
}
|
||||
|
||||
function _calculateDomainSeparator() internal view returns (bytes32) {
|
||||
return
|
||||
keccak256(
|
||||
abi.encode(
|
||||
Typehash.EIP712_DOMAIN,
|
||||
keccak256(bytes(name())),
|
||||
EIP712_DOMAIN_VERSION_HASH,
|
||||
block.chainid,
|
||||
address(this)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// View functions
|
||||
|
||||
function nonces(address signer) public view returns (uint256) {
|
||||
return _nonces[signer];
|
||||
}
|
||||
|
||||
/// @dev This function is used to invalidate signatures by incrementing the nonce
|
||||
function incrementNonce(uint8 increment) external {
|
||||
uint256 currentNonce = _nonces[msg.sender];
|
||||
_nonces[msg.sender] = currentNonce + increment;
|
||||
emit Events.NonceUpdated(msg.sender, currentNonce + increment, block.timestamp);
|
||||
}
|
||||
|
||||
function name() public pure returns (string memory) {
|
||||
return 'PublicActProxy';
|
||||
}
|
||||
}
|
||||
@@ -89,134 +89,135 @@ contract PublicActProxyTest is BaseTest {
|
||||
assertTrue(collectNFT.balanceOf(nftRecipient) > 0, 'NFT recipient balance is 0');
|
||||
}
|
||||
|
||||
function testCanPublicCollect() public {
|
||||
vm.prank(deployer);
|
||||
address simpleFeeCollectModule = address(
|
||||
new SimpleFeeCollectModule(
|
||||
address(hub),
|
||||
address(collectPublicationAction),
|
||||
address(moduleRegistry),
|
||||
address(this)
|
||||
)
|
||||
);
|
||||
// DEPRECATED
|
||||
// function testCanPublicCollect() public {
|
||||
// vm.prank(deployer);
|
||||
// address simpleFeeCollectModule = address(
|
||||
// new SimpleFeeCollectModule(
|
||||
// address(hub),
|
||||
// address(collectPublicationAction),
|
||||
// address(moduleRegistry),
|
||||
// address(this)
|
||||
// )
|
||||
// );
|
||||
|
||||
collectPublicationAction.registerCollectModule(simpleFeeCollectModule);
|
||||
// collectPublicationAction.registerCollectModule(simpleFeeCollectModule);
|
||||
|
||||
MockCurrency currency = new MockCurrency();
|
||||
currency.mint(payer, 10 ether);
|
||||
// MockCurrency currency = new MockCurrency();
|
||||
// currency.mint(payer, 10 ether);
|
||||
|
||||
BaseFeeCollectModuleInitData memory exampleInitData;
|
||||
exampleInitData.amount = 1 ether;
|
||||
exampleInitData.collectLimit = 0;
|
||||
exampleInitData.currency = address(currency);
|
||||
exampleInitData.referralFee = 0;
|
||||
exampleInitData.followerOnly = false;
|
||||
exampleInitData.endTimestamp = 0;
|
||||
exampleInitData.recipient = defaultAccount.owner;
|
||||
// BaseFeeCollectModuleInitData memory exampleInitData;
|
||||
// exampleInitData.amount = 1 ether;
|
||||
// exampleInitData.collectLimit = 0;
|
||||
// exampleInitData.currency = address(currency);
|
||||
// exampleInitData.referralFee = 0;
|
||||
// exampleInitData.followerOnly = false;
|
||||
// exampleInitData.endTimestamp = 0;
|
||||
// exampleInitData.recipient = defaultAccount.owner;
|
||||
|
||||
Types.PostParams memory postParams = _getDefaultPostParams();
|
||||
postParams.actionModules[0] = address(collectPublicationAction);
|
||||
postParams.actionModulesInitDatas[0] = abi.encode(simpleFeeCollectModule, abi.encode(exampleInitData));
|
||||
// Types.PostParams memory postParams = _getDefaultPostParams();
|
||||
// postParams.actionModules[0] = address(collectPublicationAction);
|
||||
// postParams.actionModulesInitDatas[0] = abi.encode(simpleFeeCollectModule, abi.encode(exampleInitData));
|
||||
|
||||
vm.prank(defaultAccount.owner);
|
||||
defaultPubId = hub.post(postParams);
|
||||
// vm.prank(defaultAccount.owner);
|
||||
// defaultPubId = hub.post(postParams);
|
||||
|
||||
collectActionParams = Types.PublicationActionParams({
|
||||
publicationActedProfileId: defaultAccount.profileId,
|
||||
publicationActedId: defaultPubId,
|
||||
actorProfileId: publicProfile.profileId,
|
||||
referrerProfileIds: _emptyUint256Array(),
|
||||
referrerPubIds: _emptyUint256Array(),
|
||||
actionModuleAddress: address(collectPublicationAction),
|
||||
actionModuleData: abi.encode(nftRecipient, abi.encode(currency, exampleInitData.amount))
|
||||
});
|
||||
// collectActionParams = Types.PublicationActionParams({
|
||||
// publicationActedProfileId: defaultAccount.profileId,
|
||||
// publicationActedId: defaultPubId,
|
||||
// actorProfileId: publicProfile.profileId,
|
||||
// referrerProfileIds: _emptyUint256Array(),
|
||||
// referrerPubIds: _emptyUint256Array(),
|
||||
// actionModuleAddress: address(collectPublicationAction),
|
||||
// actionModuleData: abi.encode(nftRecipient, abi.encode(currency, exampleInitData.amount))
|
||||
// });
|
||||
|
||||
vm.startPrank(payer);
|
||||
currency.approve(address(publicActProxy), exampleInitData.amount);
|
||||
publicActProxy.publicCollect(collectActionParams);
|
||||
vm.stopPrank();
|
||||
// vm.startPrank(payer);
|
||||
// currency.approve(address(publicActProxy), exampleInitData.amount);
|
||||
// publicActProxy.publicCollect(collectActionParams);
|
||||
// vm.stopPrank();
|
||||
|
||||
CollectNFT collectNFT = CollectNFT(
|
||||
CollectPublicationAction(collectPublicationAction)
|
||||
.getCollectData(defaultAccount.profileId, defaultPubId)
|
||||
.collectNFT
|
||||
);
|
||||
// CollectNFT collectNFT = CollectNFT(
|
||||
// CollectPublicationAction(collectPublicationAction)
|
||||
// .getCollectData(defaultAccount.profileId, defaultPubId)
|
||||
// .collectNFT
|
||||
// );
|
||||
|
||||
assertTrue(collectNFT.balanceOf(nftRecipient) > 0, 'NFT recipient balance is 0');
|
||||
}
|
||||
// assertTrue(collectNFT.balanceOf(nftRecipient) > 0, 'NFT recipient balance is 0');
|
||||
// }
|
||||
|
||||
function testCanPublicCollectWithSig() public {
|
||||
vm.prank(deployer);
|
||||
address simpleFeeCollectModule = address(
|
||||
new SimpleFeeCollectModule(
|
||||
address(hub),
|
||||
address(collectPublicationAction),
|
||||
address(moduleRegistry),
|
||||
address(this)
|
||||
)
|
||||
);
|
||||
// function testCanPublicCollectWithSig() public {
|
||||
// vm.prank(deployer);
|
||||
// address simpleFeeCollectModule = address(
|
||||
// new SimpleFeeCollectModule(
|
||||
// address(hub),
|
||||
// address(collectPublicationAction),
|
||||
// address(moduleRegistry),
|
||||
// address(this)
|
||||
// )
|
||||
// );
|
||||
|
||||
collectPublicationAction.registerCollectModule(simpleFeeCollectModule);
|
||||
// collectPublicationAction.registerCollectModule(simpleFeeCollectModule);
|
||||
|
||||
MockCurrency currency = new MockCurrency();
|
||||
currency.mint(payer, 10 ether);
|
||||
// MockCurrency currency = new MockCurrency();
|
||||
// currency.mint(payer, 10 ether);
|
||||
|
||||
BaseFeeCollectModuleInitData memory exampleInitData;
|
||||
exampleInitData.amount = 1 ether;
|
||||
exampleInitData.collectLimit = 0;
|
||||
exampleInitData.currency = address(currency);
|
||||
exampleInitData.referralFee = 0;
|
||||
exampleInitData.followerOnly = false;
|
||||
exampleInitData.endTimestamp = 0;
|
||||
exampleInitData.recipient = defaultAccount.owner;
|
||||
// BaseFeeCollectModuleInitData memory exampleInitData;
|
||||
// exampleInitData.amount = 1 ether;
|
||||
// exampleInitData.collectLimit = 0;
|
||||
// exampleInitData.currency = address(currency);
|
||||
// exampleInitData.referralFee = 0;
|
||||
// exampleInitData.followerOnly = false;
|
||||
// exampleInitData.endTimestamp = 0;
|
||||
// exampleInitData.recipient = defaultAccount.owner;
|
||||
|
||||
Types.PostParams memory postParams = _getDefaultPostParams();
|
||||
postParams.actionModules[0] = address(collectPublicationAction);
|
||||
postParams.actionModulesInitDatas[0] = abi.encode(simpleFeeCollectModule, abi.encode(exampleInitData));
|
||||
// Types.PostParams memory postParams = _getDefaultPostParams();
|
||||
// postParams.actionModules[0] = address(collectPublicationAction);
|
||||
// postParams.actionModulesInitDatas[0] = abi.encode(simpleFeeCollectModule, abi.encode(exampleInitData));
|
||||
|
||||
vm.prank(defaultAccount.owner);
|
||||
defaultPubId = hub.post(postParams);
|
||||
// vm.prank(defaultAccount.owner);
|
||||
// defaultPubId = hub.post(postParams);
|
||||
|
||||
collectActionParams = Types.PublicationActionParams({
|
||||
publicationActedProfileId: defaultAccount.profileId,
|
||||
publicationActedId: defaultPubId,
|
||||
actorProfileId: publicProfile.profileId,
|
||||
referrerProfileIds: _emptyUint256Array(),
|
||||
referrerPubIds: _emptyUint256Array(),
|
||||
actionModuleAddress: address(collectPublicationAction),
|
||||
actionModuleData: abi.encode(nftRecipient, abi.encode(currency, exampleInitData.amount))
|
||||
});
|
||||
// collectActionParams = Types.PublicationActionParams({
|
||||
// publicationActedProfileId: defaultAccount.profileId,
|
||||
// publicationActedId: defaultPubId,
|
||||
// actorProfileId: publicProfile.profileId,
|
||||
// referrerProfileIds: _emptyUint256Array(),
|
||||
// referrerPubIds: _emptyUint256Array(),
|
||||
// actionModuleAddress: address(collectPublicationAction),
|
||||
// actionModuleData: abi.encode(nftRecipient, abi.encode(currency, exampleInitData.amount))
|
||||
// });
|
||||
|
||||
vm.prank(payer);
|
||||
currency.approve(address(publicActProxy), exampleInitData.amount);
|
||||
// vm.prank(payer);
|
||||
// currency.approve(address(publicActProxy), exampleInitData.amount);
|
||||
|
||||
domainSeparator = keccak256(
|
||||
abi.encode(
|
||||
Typehash.EIP712_DOMAIN,
|
||||
keccak256('PublicActProxy'),
|
||||
MetaTxLib.EIP712_DOMAIN_VERSION_HASH,
|
||||
block.chainid,
|
||||
address(publicActProxy)
|
||||
)
|
||||
);
|
||||
// domainSeparator = keccak256(
|
||||
// abi.encode(
|
||||
// Typehash.EIP712_DOMAIN,
|
||||
// keccak256('PublicActProxy'),
|
||||
// MetaTxLib.EIP712_DOMAIN_VERSION_HASH,
|
||||
// block.chainid,
|
||||
// address(publicActProxy)
|
||||
// )
|
||||
// );
|
||||
|
||||
publicActProxy.publicCollectWithSig({
|
||||
publicationActionParams: collectActionParams,
|
||||
signature: _getSigStruct({
|
||||
pKey: payerPk,
|
||||
digest: _getActTypedDataHash(collectActionParams, publicActProxy.nonces(payer), type(uint256).max),
|
||||
deadline: type(uint256).max
|
||||
})
|
||||
});
|
||||
// publicActProxy.publicCollectWithSig({
|
||||
// publicationActionParams: collectActionParams,
|
||||
// signature: _getSigStruct({
|
||||
// pKey: payerPk,
|
||||
// digest: _getActTypedDataHash(collectActionParams, publicActProxy.nonces(payer), type(uint256).max),
|
||||
// deadline: type(uint256).max
|
||||
// })
|
||||
// });
|
||||
|
||||
CollectNFT collectNFT = CollectNFT(
|
||||
CollectPublicationAction(collectPublicationAction)
|
||||
.getCollectData(defaultAccount.profileId, defaultPubId)
|
||||
.collectNFT
|
||||
);
|
||||
// CollectNFT collectNFT = CollectNFT(
|
||||
// CollectPublicationAction(collectPublicationAction)
|
||||
// .getCollectData(defaultAccount.profileId, defaultPubId)
|
||||
// .collectNFT
|
||||
// );
|
||||
|
||||
assertTrue(collectNFT.balanceOf(nftRecipient) > 0, 'NFT recipient balance is 0');
|
||||
}
|
||||
// assertTrue(collectNFT.balanceOf(nftRecipient) > 0, 'NFT recipient balance is 0');
|
||||
// }
|
||||
|
||||
function testCanPublicPaidAct_SharedRevenuePaidCollect() public {
|
||||
vm.prank(deployer);
|
||||
|
||||
Reference in New Issue
Block a user