Skip to content

Conversation

@sogipec
Copy link
Contributor

@sogipec sogipec commented Oct 15, 2025

No description provided.

Copilot AI review requested due to automatic review settings October 15, 2025 17:29
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the Merkl protocol with significant changes to support upgrades and new operator functionality. The changes primarily involve updating author attribution from "Angle Labs, Inc." to "Merkl SAS" and implementing a comprehensive operator system for campaign and reward management.

Key changes include:

  • Introduction of main operators and creator allowances for delegated campaign management
  • Enhanced claim recipient functionality with governance support
  • Removal of deprecated signature verification and distribution creation methods

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
contracts/partners/tokenWrappers/SonicFragment.sol Updated author attribution to Merkl SAS
contracts/partners/tokenWrappers/PointToken.sol Updated author attribution to Merkl SAS
contracts/mock/DistributionCreatorUpdatable.sol Updated author attribution to Merkl SAS
contracts/interfaces/IAccessControlManager.sol Updated author attribution to Merkl SAS
contracts/Distributor.sol Added main operator system and enhanced claim recipient functionality
contracts/DistributionCreatorWithDistributions.sol New contract for backward compatibility with deprecated distribution model
contracts/DistributionCreator.sol Major refactoring with operator allowances and removal of deprecated functionality
contracts/AccessControlManager.sol Updated author attribution to Merkl SAS
LICENSE Updated licensor information to Merkl SAS

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link
Contributor

@GuillaumeNervoXS GuillaumeNervoXS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't check the distributor and deployment scripts yet

}
}

// Sign script
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you remove this one and the one to create campaigns ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added it back

}

/// @notice Gets all the campaigns which were live at some point between `start` and `end` timestamp
/// @param skip Disregard distibutions with a global index lower than `skip`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did we let the functions linked to the old distributions type the last time? Wasn't it because a protocol relied on it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

put it on another file

address rewardToken,
address to,
uint256 amount
) external onlyUserOrGovernor(user) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this one with governor rights instead of just user amd operator?
The less we are liable the better I'd say

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More as a safeguard if accounting is broken in some way here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern as Guillaume.
If accounting is broken, we could upgrade if needed.
If client gets pwned, he will ask for us to handle this, which I don't think we want to do ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In terms of security, on our side this exposes the funds on creator to the security of multisig.
If we removed the Governor modifier here, we should also kill recoverFees functionnality as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indifferent, I still think we're good to leave it as is. It's more a sales stance and positioning of saying we won't do it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is not worth it, I don't see how/why we would be more reactive than a user


/// @notice Toggles the ability of an `operator` to manage campaigns on behalf of a `user`
/// @dev Only the user themselves or a governor can call this function
function toggleCampaignOperator(address user, address operator) external onlyUserOrGovernor(user) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not just having the mapping 'creatorAllowance' and if allowance non null --> valid operator

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for the sake of composability and having different addresses possible, like most people may not split roles, but seems cleaner to have different roles

// The recipient set in the context of the call to `claim` can override the default recipient set by the user
if (msg.sender != user || recipient == address(0)) {
address userSetRecipient = claimRecipient[user][token];
if (userSetRecipient == address(0)) userSetRecipient = claimRecipient[user][address(0)];
Copy link
Contributor

@nlecoufl nlecoufl Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A scenario that can happen:

  • First, a user set an address 0xA as claimRecipient for token A
  • Then, he finally set an address 0xB as default recipient for all tokens (using 0x0…0)
  • Finally, when a claim is triggered, claimRecipient[user][token] equal 0xA. Thus tokens will not flow to 0xB (as some users will expect I guess, because setting a default recipient for all tokens was their last action on-chain)

I wonder if we want to keep this behavior or not.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes in this setup, by default token recipient is less senior than what you set for a token -> imo this is navigated at the UI level

address rewardToken,
address to,
uint256 amount
) external onlyUserOrGovernor(user) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same concern as Guillaume.
If accounting is broken, we could upgrade if needed.
If client gets pwned, he will ask for us to handle this, which I don't think we want to do ?

address rewardToken,
address to,
uint256 amount
) external onlyUserOrGovernor(user) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In terms of security, on our side this exposes the funds on creator to the security of multisig.
If we removed the Governor modifier here, we should also kill recoverFees functionnality as well.

Copy link
Contributor

@GuillaumeNervoXS GuillaumeNervoXS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

doesn't cost much to keep this fallback if engine fees do not work well -> not confident removing it if we haven't tested it well enough

Just lisibility of the snmart contract and again there are already some tests as subcampaigns like Pendle/Spectra/stake dao/... reies on it already

Copy link
Contributor

@GuillaumeNervoXS GuillaumeNervoXS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes but then you end up reading twice in storage which is suboptimal

Ok but again gas cost is not as much an issue anymore

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.

6 participants