Skip to content

Conversation

@aa-eyup
Copy link

@aa-eyup aa-eyup commented Dec 2, 2025

Motivation

Currently there is exists no way for an ATokenVault supplying to Aave to claim Merkl rewards. This change adds a contract that inherits from the upgradeable ATokenVault and adds functionality to claim Merkl rewards from a distributor address. If existing ATokenVault instances want to upgrade to support these functions then it can be done as this change consumes one of the gap slots reserved for upgrades to hold the Merkl distributor address.

Changes

  • inherits from ATokenVault
  • updates storage struct to store merkl distributor contract (consumes the first of 50 gap slots)
  • expose (onlyOwner) function to set distributor
  • expose function to get distributor
  • expose (onlyOwner) function to claim rewards from merkl distributor
  • add test that forks Ethereum mainnet to claim rewards (uses an address that was eligible to claim rewards as of the fork block)

@aa-eyup aa-eyup force-pushed the feat/merkl-rewards branch 4 times, most recently from 1c758c8 to c4178fe Compare December 2, 2025 22:27
@aa-eyup aa-eyup marked this pull request as ready for review December 2, 2025 22:30
@aa-eyup aa-eyup force-pushed the feat/merkl-rewards branch 2 times, most recently from f707b9d to 6069218 Compare December 2, 2025 23:10
- inherits from ATokenVault
- updates storage struct to store merkl distributor contract
  (consumes the first of 50 gap slots)
- expose functions to set/get distributor (onlyOwner)
- expose function to claim rewards from merkl distributor (onlyOwner)
- add test that forks Ethereum mainnet to claim rewards
@aa-eyup aa-eyup force-pushed the feat/merkl-rewards branch from 6069218 to 34ae3cb Compare December 2, 2025 23:11
@aa-eyup aa-eyup requested a review from miguelmtzinf December 5, 2025 05:19
- make comments more concise
- clarify in comment that native asset can not be rescued
- move custom interface into a /dependencies dir
- order read/write functions on ATokenVaultMerklRewardsClaim contract and interface
- an operator will be set on the reward distributor contract
- an operator can claim rewards on behalf of a user
  (rewards are still sent to the user i.e. the ATokenVault)
@aa-eyup aa-eyup force-pushed the feat/merkl-rewards branch from 422ca9b to 896fd68 Compare December 6, 2025 00:50
@aa-eyup aa-eyup force-pushed the feat/merkl-rewards branch from a2065b4 to 7d5c2f0 Compare December 6, 2025 01:00
* @param destination Address of the destination receiving the reward token
* @param amount Amount of the reward token transferred to the destination
*/
event MerklRewardsTokenForwarded(address indexed token, address indexed destination, uint256 indexed amount);
Copy link
Member

Choose a reason for hiding this comment

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

We could do smt similar to RewardsClaimed, and emit the destination, tokens array and amounts array.

Copy link
Author

Choose a reason for hiding this comment

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

I have no strong preference, but I wanted to avoid emitting the event if the rewardTokensToForward array is empty. If you have a strong preference please lmk. Maybe we return early if rewardTokensToForward is empty then iterate through the tokens then emit an event at the event.

Imagine it would look like this:
event MerklRewardsTokenForwarded(address indexed destination, address[] tokens, uint256[] amounts);

We can also pass in an array of destinations to claimMerklRewards(...) if you think the flexibility would be valuable - then the single token/amount/destination event makes more sense.

@aa-eyup aa-eyup requested a review from miguelmtzinf December 18, 2025 20:01
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