-
Notifications
You must be signed in to change notification settings - Fork 75
feat: add new contract to support merkl reward claiming #112
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
Open
aa-eyup
wants to merge
12
commits into
main
Choose a base branch
from
feat/merkl-rewards
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
34ae3cb
feat: add new contract to support merkl reward claiming
aa-eyup a2bdcc3
enh: address PR comments
aa-eyup 99a4131
test: add unit tests for ATokenVaultMerklRewardClaimer
aa-eyup 75990a7
feat: add function to merkl reward claimer vault to set operator
aa-eyup ffc8063
enh: include the merkl distributor address in events
aa-eyup adabf30
chore: rename test contract
aa-eyup 7d5c2f0
test: add check for non owner call to toggle operator
aa-eyup 558c9ef
refactor(ATokenVaultMerklRewardClaimer): address feedback
aa-eyup 510fc9c
enh(ATokenVaultMerklRewardClaimer): address feedback on additional te…
aa-eyup 4232f8c
feat(ATokenVaultMerklRewardClaimer): allow setting destination to for…
aa-eyup 4db183a
test(ATokenVaultMerklRewardClaimer): use weth mock token to test nati…
aa-eyup 7fedcd1
chore(IATokenVaultMerklRewardClaimer): format docs
aa-eyup File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,75 @@ | ||
| // SPDX-License-Identifier: UNLICENSED | ||
| // All Rights Reserved © AaveCo | ||
|
|
||
| pragma solidity ^0.8.10; | ||
|
|
||
| import {IPoolAddressesProvider} from "@aave-v3-core/interfaces/IPoolAddressesProvider.sol"; | ||
| import {IERC20} from "@openzeppelin/interfaces/IERC20.sol"; | ||
|
|
||
| import {ATokenVault} from "./ATokenVault.sol"; | ||
| import {IATokenVaultMerklRewardClaimer} from "./interfaces/IATokenVaultMerklRewardClaimer.sol"; | ||
|
|
||
| interface IMerklDistributor { | ||
| function claim( | ||
| address[] calldata users, | ||
| address[] calldata tokens, | ||
| uint256[] calldata amounts, | ||
| bytes32[][] calldata proofs | ||
| ) external; | ||
| } | ||
|
|
||
| /** | ||
| * @title ATokenVaultMerklRewardClaimer | ||
| * @author Aave Protocol | ||
| * @notice A contract that allows the owner to claim Merkl rewards for the ATokenVault | ||
aa-eyup marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| */ | ||
| contract ATokenVaultMerklRewardClaimer is ATokenVault, IATokenVaultMerklRewardClaimer { | ||
| /** | ||
| * @dev Constructor. | ||
| * @param underlying The underlying ERC20 asset which can be supplied to Aave | ||
| * @param referralCode The Aave referral code to use for deposits from this vault | ||
| * @param poolAddressesProvider The address of the Aave v3 Pool Addresses Provider | ||
| */ | ||
| constructor(address underlying, uint16 referralCode, IPoolAddressesProvider poolAddressesProvider) | ||
| ATokenVault(underlying, referralCode, poolAddressesProvider) | ||
| {} | ||
|
|
||
| /// @inheritdoc IATokenVaultMerklRewardClaimer | ||
| function getMerklDistributor() external view override returns (address) { | ||
miguelmtzinf marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return _s.merklDistributor; | ||
| } | ||
|
|
||
| /// @inheritdoc IATokenVaultMerklRewardClaimer | ||
| function setMerklDistributor(address merklDistributor) external override onlyOwner { | ||
| require(merklDistributor != address(0), "ZERO_ADDRESS_NOT_VALID"); | ||
| address currentMerklDistributor = _s.merklDistributor; | ||
| _s.merklDistributor = merklDistributor; | ||
| emit MerklDistributorUpdated(currentMerklDistributor, merklDistributor); | ||
| } | ||
|
|
||
| /// @inheritdoc IATokenVaultMerklRewardClaimer | ||
| function claimMerklRewards(address[] calldata rewardTokens, uint256[] calldata amounts, bytes32[][] calldata proofs) | ||
| public | ||
| override | ||
| onlyOwner | ||
| { | ||
| require(_s.merklDistributor != address(0), "MERKL_DISTRIBUTOR_NOT_SET"); | ||
miguelmtzinf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| address[] memory users = new address[](rewardTokens.length); | ||
| for (uint256 i = 0; i < rewardTokens.length; i++) { | ||
| // users represent depositors into Aave which is this contract | ||
| users[i] = address(this); | ||
| } | ||
|
|
||
| // The claim function does not return a list of tokens and amounts actually received. | ||
| // It is possible for rewards to be in aTokens, the underlying asset or some other token. | ||
| // If necessary the owner can use IATokenVault.emergencyRescue(...) to rescue the non-aToken rewards. | ||
miguelmtzinf marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| IMerklDistributor(_s.merklDistributor).claim(users, rewardTokens, amounts, proofs); | ||
| // Do not attempt to accrue yield as it can be delegated to subsequent calls to this contract. | ||
| // We do not need to accrue before claiming because new shares are not granted anywhere (rewards are socialized across all current share holders). | ||
| // We do not need to accrue after claiming because any subsequent call will trigger an accrual before state updates | ||
| // and preview functions read the balance of aTokens on the vault at runtime. | ||
|
|
||
| emit MerklRewardsClaimed(rewardTokens, amounts); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| // SPDX-License-Identifier: UNLICENSED | ||
| // All Rights Reserved © AaveCo | ||
|
|
||
| pragma solidity ^0.8.10; | ||
|
|
||
| /** | ||
| * @title IATokenVaultMerklRewardClaimer | ||
| * @author Aave Protocol | ||
| * | ||
| * @notice Defines the basic interface of the ATokenVaultMerklRewardClaimer | ||
aa-eyup marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| */ | ||
| interface IATokenVaultMerklRewardClaimer { | ||
| /** | ||
| * @dev Emitted when Merkl rewards are claimed by the vault contract | ||
| * @dev The token addresses do not always match the actual tokens received by the vault contract after rewards are claimed | ||
| * @dev The amounts do not always match the actual amounts received by the vault contract after rewards are claimed | ||
| * @param tokens Addresses of the ERC-20 reward tokens claimed (the tokens passed as params to the Merkl distributor contract) | ||
| * @param amounts Amounts of the reward tokens claimed for each token (the amounts passed as params to the Merkl distributor contract) | ||
| */ | ||
| event MerklRewardsClaimed(address[] tokens, uint256[] amounts); | ||
|
|
||
| /** | ||
| * @dev Emitted when the Merkl distributor address is updated | ||
| * @param oldMerklDistributor The old address of the Merkl distributor contract | ||
| * @param newMerklDistributor The new address of the Merkl distributor contract | ||
| */ | ||
| event MerklDistributorUpdated(address indexed oldMerklDistributor, address indexed newMerklDistributor); | ||
|
|
||
| /** | ||
| * @notice Getter for the contract address called to claim Merkl rewards | ||
| * @return Address of the Merkl distributor contract | ||
| */ | ||
| function getMerklDistributor() external view returns (address); | ||
|
|
||
| /** | ||
| * @notice Sets the Merkl distributor address for the vault uses to claim Merkl rewards. | ||
| * @dev Only callable by the owner | ||
| * @param merklDistributor Address of the new Merkl distributor contract | ||
| */ | ||
| function setMerklDistributor(address merklDistributor) external; | ||
|
|
||
| /** | ||
| * @notice Claims Merkl rewards earned by deposits from this contract through the Merkl distributor contract | ||
| * @dev Only callable by the owner | ||
| * @dev Merkl distributor address must be set | ||
| * @dev The IMerklDistributor.claim(...) function does not return a list of tokens and amounts the users actually receive | ||
| * @dev The order of the tokens, amounts, and proofs must align with eachother | ||
| * @param rewardTokens Addresses of the ERC-20 reward tokens to claim (the tokens passed as params to the Merkl distributor contract) | ||
| * @param amounts Amounts of the reward tokens to claim for each token | ||
| * @param proofs Merkl proof passed to the Merkl distributor contract | ||
| */ | ||
| function claimMerklRewards(address[] calldata rewardTokens, uint256[] calldata amounts, bytes32[][] calldata proofs) | ||
| external; | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.