-
Notifications
You must be signed in to change notification settings - Fork 11
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
Conversation
contracts/CampaignCreatorV2.sol
Outdated
function _getRoundedEpoch(uint32 epoch) internal pure returns (uint32) { | ||
return (epoch / EPOCH_DURATION) * EPOCH_DURATION; | ||
} |
Check warning
Code scanning / Slither
Divide before multiply
contracts/CampaignCreatorV2.sol
Outdated
} | ||
|
||
/// @notice Sets a new address to receive fees | ||
function setFeeRecipient(address _feeRecipient) external onlyGovernorOrGuardian { |
Check notice
Code scanning / Slither
Missing zero address validation
contracts/CampaignCreatorV2.sol
Outdated
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
contracts/CampaignCreatorV2.sol
Outdated
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
contracts/CampaignCreatorV2.sol
Outdated
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
contracts/CampaignCreatorV2.sol
Outdated
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
contracts/CampaignCreatorV2.sol
Outdated
/// @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
* fix: comments * fix updates * feat merkl V2 iterations * feat: checks on top * feat: last tests
* fix updates * feat: campaign specific fees * change old distrib * feat: change access control
No description provided.