Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: merklV2 poc #47

Closed
wants to merge 20 commits into from
Closed

feat: merklV2 poc #47

wants to merge 20 commits into from

Conversation

sogipec
Copy link
Contributor

@sogipec sogipec commented Dec 1, 2023

No description provided.

Comment on lines 486 to 488
function _getRoundedEpoch(uint32 epoch) internal pure returns (uint32) {
return (epoch / EPOCH_DURATION) * EPOCH_DURATION;
}

Check warning

Code scanning / Slither

Divide before multiply

CampaignCreatorV2._getRoundedEpoch(uint32) (contracts/CampaignCreatorV2.sol#486-488) performs a multiplication on the result of a division: - (epoch / EPOCH_DURATION) * EPOCH_DURATION (contracts/CampaignCreatorV2.sol#487)
contracts/CampaignCreatorV2.sol Fixed Show fixed Hide fixed
contracts/CampaignCreatorV2.sol Fixed Show fixed Hide fixed
}

/// @notice Sets a new address to receive fees
function setFeeRecipient(address _feeRecipient) external onlyGovernorOrGuardian {

Check notice

Code scanning / Slither

Missing zero address validation

CampaignCreatorV2.setFeeRecipient(address)._feeRecipient (contracts/CampaignCreatorV2.sol#463) lacks a zero-check on : - feeRecipient = _feeRecipient (contracts/CampaignCreatorV2.sol#464)
Comment on lines 435 to 443
function recoverFees(IERC20[] calldata tokens, address to) external onlyGovernorOrGuardian {
uint256 tokensLength = tokens.length;
for (uint256 i; i < tokensLength; ) {
tokens[i].safeTransfer(to, tokens[i].balanceOf(address(this)));
unchecked {
++i;
}
}
}

Check notice

Code scanning / Slither

Calls inside a loop

CampaignCreatorV2.recoverFees(IERC20[],address) (contracts/CampaignCreatorV2.sol#435-443) has external calls inside a loop: tokens[i].safeTransfer(to,tokens[i].balanceOf(address(this))) (contracts/CampaignCreatorV2.sol#438)
Comment on lines 223 to 264
function _createCampaign(
CampaignParameters memory campaign
) internal nonReentrant returns (uint256 campaignAmount) {
uint32 epochStart = _getRoundedEpoch(campaign.epochStart);
uint256 minCampaignAmount = rewardTokenMinAmounts[campaign.rewardToken];
campaign.epochStart = epochStart;
// Reward are not accepted in the following conditions:
if (
// if epoch parameters lead to a past campaign
epochStart + EPOCH_DURATION < block.timestamp ||
// if the amount of epochs for which this campaign should last is zero
campaign.numEpoch == 0 ||
// if the reward token is not whitelisted as an incentive token
minCampaignAmount == 0 ||
// if the amount distributed is too small with respect to what is allowed
campaign.amount / campaign.numEpoch < minCampaignAmount
) revert InvalidReward();
campaignAmount = campaign.amount;
// Computing fees: these are waived for whitelisted addresses and if there is a whitelisted token in a pool
uint256 userFeeRebate = feeRebate[msg.sender];
if (userFeeRebate < BASE_9) {
uint256 _fees = (fees * (BASE_9 - userFeeRebate)) / BASE_9;
uint256 campaignAmountMinusFees = (campaignAmount * (BASE_9 - _fees)) / BASE_9;
address _feeRecipient = feeRecipient;
_feeRecipient = _feeRecipient == address(0) ? address(this) : _feeRecipient;
IERC20(campaign.rewardToken).safeTransferFrom(
msg.sender,
_feeRecipient,
campaignAmount - campaignAmountMinusFees
);
campaignAmount = campaignAmountMinusFees;
campaign.amount = campaignAmount;
}

IERC20(campaign.rewardToken).safeTransferFrom(msg.sender, distributor, campaignAmount);
uint256 senderNonce = nonces[msg.sender];
nonces[msg.sender] = senderNonce + 1;
campaign.rewardId = bytes32(keccak256(abi.encodePacked(msg.sender, senderNonce)));
campaign.creator = msg.sender;
campaignList.push(campaign);
emit NewCampaign(campaign);
}

Check notice

Code scanning / Slither

Reentrancy vulnerabilities

Reentrancy in CampaignCreatorV2._createCampaign(CampaignParameters) (contracts/CampaignCreatorV2.sol#223-264): External calls: - IERC20(campaign.rewardToken).safeTransferFrom(msg.sender,_feeRecipient,campaignAmount - campaignAmountMinusFees) (contracts/CampaignCreatorV2.sol#248-252) - IERC20(campaign.rewardToken).safeTransferFrom(msg.sender,distributor,campaignAmount) (contracts/CampaignCreatorV2.sol#257) State variables written after the call(s): - campaignList.push(campaign) (contracts/CampaignCreatorV2.sol#262) - nonces[msg.sender] = senderNonce + 1 (contracts/CampaignCreatorV2.sol#259)
Comment on lines 308 to 327
function getValidRewardTokens() external view returns (RewardTokenAmounts[] memory) {
uint256 length;
uint256 rewardTokenListLength = rewardTokens.length;
RewardTokenAmounts[] memory validRewardTokens = new RewardTokenAmounts[](rewardTokenListLength);
for (uint32 i; i < rewardTokenListLength; ) {
address token = rewardTokens[i];
uint256 minAmount = rewardTokenMinAmounts[token];
if (minAmount > 0) {
validRewardTokens[length] = RewardTokenAmounts(token, minAmount);
length += 1;
}
unchecked {
++i;
}
}
assembly {
mstore(validRewardTokens, length)
}
return validRewardTokens;
}

Check warning

Code scanning / Slither

Assembly usage

CampaignCreatorV2.getValidRewardTokens() (contracts/CampaignCreatorV2.sol#308-327) uses assembly - INLINE ASM (contracts/CampaignCreatorV2.sol#323-325)
Comment on lines 503 to 529
function _getCampaignsBetweenEpochs(
uint32 epochStart,
uint32 epochEnd,
uint32 skip,
uint32 first
) internal view returns (CampaignParameters[] memory, uint256) {
uint256 length;
uint256 campaignListLength = campaignList.length;
uint256 returnSize = first > campaignListLength ? campaignListLength : first;
CampaignParameters[] memory activeRewards = new CampaignParameters[](returnSize);
uint32 i = skip;
while (i < campaignListLength) {
CampaignParameters memory campaign = campaignList[i];
if (_isCampaignLiveBetweenEpochs(campaign, epochStart, epochEnd)) {
activeRewards[length] = campaign;
length += 1;
}
unchecked {
++i;
}
if (length == returnSize) break;
}
assembly {
mstore(activeRewards, length)
}
return (activeRewards, i);
}

Check warning

Code scanning / Slither

Assembly usage

CampaignCreatorV2._getCampaignsBetweenEpochs(uint32,uint32,uint32,uint32) (contracts/CampaignCreatorV2.sol#503-529) uses assembly - INLINE ASM (contracts/CampaignCreatorV2.sol#525-527)
/// @notice List of all reward tokens that have at some point been accepted
address[] public rewardTokens;

uint256[36] private __gap;

Check warning

Code scanning / Slither

Unused state variable

CampaignCreatorV2.__gap (contracts/CampaignCreatorV2.sol#125) is never used in CampaignCreatorV2 (contracts/CampaignCreatorV2.sol#71-530)
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Outdated Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
contracts/DistributionCreator.sol Show resolved Hide resolved
sogipec and others added 3 commits February 2, 2024 17:03
* fix updates

* feat: campaign specific fees

* change old distrib

* feat: change access control
@Picodes Picodes closed this Feb 7, 2024
@Picodes Picodes deleted the merkl-v2 branch February 7, 2024 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants