mirror of
https://github.com/lens-protocol/core.git
synced 2026-04-22 03:02:03 -04:00
Merge branch 'main' into refactor/general-optimizations
This commit is contained in:
@@ -2,6 +2,8 @@ module.exports = {
|
||||
skipFiles: [
|
||||
'/core/base/ERC721Time.sol',
|
||||
'/core/base/ERC721Enumerable.sol',
|
||||
'/core/modules/follow/SecretCodeFollowModule.sol',
|
||||
'/upgradeability',
|
||||
'/interfaces',
|
||||
'/mocks',
|
||||
],
|
||||
|
||||
@@ -133,7 +133,8 @@ contract FeeCollectModule is ICollectModule, FeeModuleBase, FollowValidationModu
|
||||
uint256 adjustedAmount = amount - treasuryAmount;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
|
||||
function _processCollectWithReferral(
|
||||
@@ -173,6 +174,7 @@ contract FeeCollectModule is ICollectModule, FeeModuleBase, FollowValidationModu
|
||||
address recipient = _dataByPublicationByProfile[profileId][pubId].recipient;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,8 @@ contract LimitedFeeCollectModule is ICollectModule, FeeModuleBase, FollowValidat
|
||||
uint256 adjustedAmount = amount - treasuryAmount;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
|
||||
function _processCollectWithReferral(
|
||||
@@ -193,6 +194,7 @@ contract LimitedFeeCollectModule is ICollectModule, FeeModuleBase, FollowValidat
|
||||
address recipient = _dataByPublicationByProfile[profileId][pubId].recipient;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,8 @@ contract LimitedTimedFeeCollectModule is ICollectModule, FeeModuleBase, FollowVa
|
||||
uint256 adjustedAmount = amount - treasuryAmount;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
|
||||
function _processCollectWithReferral(
|
||||
@@ -204,6 +205,7 @@ contract LimitedTimedFeeCollectModule is ICollectModule, FeeModuleBase, FollowVa
|
||||
address recipient = _dataByPublicationByProfile[profileId][pubId].recipient;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,7 +149,8 @@ contract TimedFeeCollectModule is ICollectModule, FeeModuleBase, FollowValidatio
|
||||
uint256 adjustedAmount = amount - treasuryAmount;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
|
||||
function _processCollectWithReferral(
|
||||
@@ -189,6 +190,7 @@ contract TimedFeeCollectModule is ICollectModule, FeeModuleBase, FollowValidatio
|
||||
address recipient = _dataByPublicationByProfile[profileId][pubId].recipient;
|
||||
|
||||
IERC20(currency).safeTransferFrom(collector, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(collector, treasury, treasuryAmount);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,8 @@ contract FeeFollowModule is IFollowModule, FeeModuleBase, FollowValidatorFollowM
|
||||
uint256 adjustedAmount = amount - treasuryAmount;
|
||||
|
||||
IERC20(currency).safeTransferFrom(follower, recipient, adjustedAmount);
|
||||
IERC20(currency).safeTransferFrom(follower, treasury, treasuryAmount);
|
||||
if (treasuryAmount > 0)
|
||||
IERC20(currency).safeTransferFrom(follower, treasury, treasuryAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,16 +26,17 @@ export function matchEvent(
|
||||
receipt: TransactionReceipt,
|
||||
name: string,
|
||||
expectedArgs?: any[],
|
||||
eventContract: Contract = eventsLib
|
||||
eventContract: Contract = eventsLib,
|
||||
emitterAddress?: string
|
||||
) {
|
||||
const events = receipt.logs;
|
||||
|
||||
if (events != undefined) {
|
||||
// match name from list of events in eventContract, when found, compute the sigHash
|
||||
let sigHash: string | undefined;
|
||||
for (let contractEvents of Object.keys(eventContract.interface.events)) {
|
||||
if (contractEvents.startsWith(name) && contractEvents.charAt(name.length) == '(') {
|
||||
sigHash = keccak256(toUtf8Bytes(contractEvents));
|
||||
for (let contractEvent of Object.keys(eventContract.interface.events)) {
|
||||
if (contractEvent.startsWith(name) && contractEvent.charAt(name.length) == '(') {
|
||||
sigHash = keccak256(toUtf8Bytes(contractEvent));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -51,6 +52,10 @@ export function matchEvent(
|
||||
for (let emittedEvent of events) {
|
||||
// If we find one with the correct sighash, check if it is the one we're looking for
|
||||
if (emittedEvent.topics[0] == sigHash) {
|
||||
// If an emitter address is passed, validate that this is indeed the correct emitter, if not, continue
|
||||
if (emitterAddress) {
|
||||
if (emittedEvent.address != emitterAddress) continue;
|
||||
}
|
||||
const event = eventContract.interface.parseLog(emittedEvent);
|
||||
// If there are expected arguments, validate them, otherwise, return here
|
||||
if (expectedArgs) {
|
||||
@@ -106,7 +111,9 @@ export function matchEvent(
|
||||
if (invalidParamsButExists) {
|
||||
logger.throwError(`Event "${name}" found in logs but with unexpected args`);
|
||||
} else {
|
||||
logger.throwError(`Event "${name}" not found in given transaction log`);
|
||||
logger.throwError(
|
||||
`Event "${name}" not found emitted by "${emitterAddress}" in given transaction log`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
logger.throwError('No events were emitted');
|
||||
|
||||
@@ -2,6 +2,7 @@ import { BigNumber } from '@ethersproject/contracts/node_modules/@ethersproject/
|
||||
import { parseEther } from '@ethersproject/units';
|
||||
import '@nomiclabs/hardhat-ethers';
|
||||
import { expect } from 'chai';
|
||||
import { ERC20__factory } from '../../../typechain-types';
|
||||
import { MAX_UINT256, ZERO_ADDRESS } from '../../helpers/constants';
|
||||
import { ERRORS } from '../../helpers/errors';
|
||||
import { getTimestamp, matchEvent, waitForTx } from '../../helpers/utils';
|
||||
@@ -13,6 +14,7 @@ import {
|
||||
FIRST_PROFILE_ID,
|
||||
governance,
|
||||
lensHub,
|
||||
lensHubImpl,
|
||||
makeSuiteCleanRoom,
|
||||
MOCK_FOLLOW_NFT_URI,
|
||||
MOCK_PROFILE_HANDLE,
|
||||
@@ -22,6 +24,7 @@ import {
|
||||
REFERRAL_FEE_BPS,
|
||||
treasuryAddress,
|
||||
TREASURY_FEE_BPS,
|
||||
user,
|
||||
userAddress,
|
||||
userTwo,
|
||||
userTwoAddress,
|
||||
@@ -138,6 +141,105 @@ makeSuiteCleanRoom('Fee Collect Module', function () {
|
||||
).to.not.be.reverted;
|
||||
});
|
||||
|
||||
it('Governance should set the treasury fee BPS to zero, userTwo collecting should not emit a transfer event to the treasury', async function () {
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(feeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(1);
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, DEFAULT_COLLECT_PRICE],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should mirror the original post, governance should set the treasury fee BPS to zero, userTwo collecting their mirror should not emit a transfer event to the treasury', async function () {
|
||||
const secondProfileId = FIRST_PROFILE_ID + 1;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).createProfile({
|
||||
to: userTwoAddress,
|
||||
handle: 'usertwo',
|
||||
imageURI: MOCK_PROFILE_URI,
|
||||
followModule: ZERO_ADDRESS,
|
||||
followModuleData: [],
|
||||
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).mirror({
|
||||
profileId: secondProfileId,
|
||||
profileIdPointed: FIRST_PROFILE_ID,
|
||||
pubIdPointed: 1,
|
||||
referenceModule: ZERO_ADDRESS,
|
||||
referenceModuleData: [],
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(feeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(secondProfileId, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(2);
|
||||
|
||||
const expectedReferralAmount = BigNumber.from(DEFAULT_COLLECT_PRICE)
|
||||
.mul(REFERRAL_FEE_BPS)
|
||||
.div(BPS_MAX);
|
||||
const amount = DEFAULT_COLLECT_PRICE.sub(expectedReferralAmount);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, amount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userTwoAddress, expectedReferralAmount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should fail to collect without following', async function () {
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
|
||||
@@ -174,6 +174,105 @@ makeSuiteCleanRoom('Limited Fee Collect Module', function () {
|
||||
).to.not.be.reverted;
|
||||
});
|
||||
|
||||
it('Governance should set the treasury fee BPS to zero, userTwo collecting should not emit a transfer event to the treasury', async function () {
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(limitedFeeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(1);
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, DEFAULT_COLLECT_PRICE],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should mirror the original post, governance should set the treasury fee BPS to zero, userTwo collecting their mirror should not emit a transfer event to the treasury', async function () {
|
||||
const secondProfileId = FIRST_PROFILE_ID + 1;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).createProfile({
|
||||
to: userTwoAddress,
|
||||
handle: 'usertwo',
|
||||
imageURI: MOCK_PROFILE_URI,
|
||||
followModule: ZERO_ADDRESS,
|
||||
followModuleData: [],
|
||||
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).mirror({
|
||||
profileId: secondProfileId,
|
||||
profileIdPointed: FIRST_PROFILE_ID,
|
||||
pubIdPointed: 1,
|
||||
referenceModule: ZERO_ADDRESS,
|
||||
referenceModuleData: [],
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(limitedFeeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(secondProfileId, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(2);
|
||||
|
||||
const expectedReferralAmount = BigNumber.from(DEFAULT_COLLECT_PRICE)
|
||||
.mul(REFERRAL_FEE_BPS)
|
||||
.div(BPS_MAX);
|
||||
const amount = DEFAULT_COLLECT_PRICE.sub(expectedReferralAmount);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, amount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userTwoAddress, expectedReferralAmount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should fail to collect without following', async function () {
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
|
||||
@@ -174,6 +174,105 @@ makeSuiteCleanRoom('Limited Timed Fee Collect Module', function () {
|
||||
).to.not.be.reverted;
|
||||
});
|
||||
|
||||
it('Governance should set the treasury fee BPS to zero, userTwo collecting should not emit a transfer event to the treasury', async function () {
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(limitedTimedFeeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(1);
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, DEFAULT_COLLECT_PRICE],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should mirror the original post, governance should set the treasury fee BPS to zero, userTwo collecting their mirror should not emit a transfer event to the treasury', async function () {
|
||||
const secondProfileId = FIRST_PROFILE_ID + 1;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).createProfile({
|
||||
to: userTwoAddress,
|
||||
handle: 'usertwo',
|
||||
imageURI: MOCK_PROFILE_URI,
|
||||
followModule: ZERO_ADDRESS,
|
||||
followModuleData: [],
|
||||
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).mirror({
|
||||
profileId: secondProfileId,
|
||||
profileIdPointed: FIRST_PROFILE_ID,
|
||||
pubIdPointed: 1,
|
||||
referenceModule: ZERO_ADDRESS,
|
||||
referenceModuleData: [],
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(limitedTimedFeeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(secondProfileId, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(2);
|
||||
|
||||
const expectedReferralAmount = BigNumber.from(DEFAULT_COLLECT_PRICE)
|
||||
.mul(REFERRAL_FEE_BPS)
|
||||
.div(BPS_MAX);
|
||||
const amount = DEFAULT_COLLECT_PRICE.sub(expectedReferralAmount);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, amount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userTwoAddress, expectedReferralAmount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should fail to collect without following', async function () {
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
|
||||
@@ -138,6 +138,105 @@ makeSuiteCleanRoom('Timed Fee Collect Module', function () {
|
||||
).to.not.be.reverted;
|
||||
});
|
||||
|
||||
it('Governance should set the treasury fee BPS to zero, userTwo collecting should not emit a transfer event to the treasury', async function () {
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(timedFeeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(FIRST_PROFILE_ID, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(1);
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, DEFAULT_COLLECT_PRICE],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should mirror the original post, governance should set the treasury fee BPS to zero, userTwo collecting their mirror should not emit a transfer event to the treasury', async function () {
|
||||
const secondProfileId = FIRST_PROFILE_ID + 1;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).createProfile({
|
||||
to: userTwoAddress,
|
||||
handle: 'usertwo',
|
||||
imageURI: MOCK_PROFILE_URI,
|
||||
followModule: ZERO_ADDRESS,
|
||||
followModuleData: [],
|
||||
followNFTURI: MOCK_FOLLOW_NFT_URI,
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
await expect(
|
||||
lensHub.connect(userTwo).mirror({
|
||||
profileId: secondProfileId,
|
||||
profileIdPointed: FIRST_PROFILE_ID,
|
||||
pubIdPointed: 1,
|
||||
referenceModule: ZERO_ADDRESS,
|
||||
referenceModuleData: [],
|
||||
})
|
||||
).to.not.be.reverted;
|
||||
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_COLLECT_PRICE]
|
||||
);
|
||||
await expect(lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [[]])).to.not.be.reverted;
|
||||
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(timedFeeCollectModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).collect(secondProfileId, 1, data);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(2);
|
||||
|
||||
const expectedReferralAmount = BigNumber.from(DEFAULT_COLLECT_PRICE)
|
||||
.mul(REFERRAL_FEE_BPS)
|
||||
.div(BPS_MAX);
|
||||
const amount = DEFAULT_COLLECT_PRICE.sub(expectedReferralAmount);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, amount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userTwoAddress, expectedReferralAmount],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should fail to collect without following', async function () {
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
|
||||
@@ -113,6 +113,36 @@ makeSuiteCleanRoom('Fee Follow Module', function () {
|
||||
).to.not.be.reverted;
|
||||
});
|
||||
|
||||
it('Governance should set the treasury fee BPS to zero, userTwo following should not emit a transfer event to the treasury', async function () {
|
||||
await expect(moduleGlobals.connect(governance).setTreasuryFee(0)).to.not.be.reverted;
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
[currency.address, DEFAULT_FOLLOW_PRICE]
|
||||
);
|
||||
await expect(currency.mint(userTwoAddress, MAX_UINT256)).to.not.be.reverted;
|
||||
await expect(
|
||||
currency.connect(userTwo).approve(feeFollowModule.address, MAX_UINT256)
|
||||
).to.not.be.reverted;
|
||||
|
||||
const tx = lensHub.connect(userTwo).follow([FIRST_PROFILE_ID], [data]);
|
||||
const receipt = await waitForTx(tx);
|
||||
|
||||
let currencyEventCount = 0;
|
||||
for (let log of receipt.logs) {
|
||||
if (log.address == currency.address) {
|
||||
currencyEventCount++;
|
||||
}
|
||||
}
|
||||
expect(currencyEventCount).to.eq(1);
|
||||
matchEvent(
|
||||
receipt,
|
||||
'Transfer',
|
||||
[userTwoAddress, userAddress, DEFAULT_FOLLOW_PRICE],
|
||||
currency,
|
||||
currency.address
|
||||
);
|
||||
});
|
||||
|
||||
it('UserTwo should fail to follow passing a different expected price in data', async function () {
|
||||
const data = abiCoder.encode(
|
||||
['address', 'uint256'],
|
||||
|
||||
Reference in New Issue
Block a user