-
Notifications
You must be signed in to change notification settings - Fork 3
velike: Remove Lock of reward, allow new reward contract to deploy and partial withdraw #307
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
Changes from 14 commits
442391e
56afe3c
50a8906
4e74282
0ad5aab
11cb16f
ab2744d
d28037e
a03c3e1
1f23fed
2e7011a
6c8ea4c
19a9acd
b021b66
1c45529
72fdde0
4199430
5f0872a
c1a434c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,7 +19,7 @@ interface IRewardContract { | |
| bool restake | ||
| ) external returns (uint256); | ||
| function deposit(address account, uint256 rewardAmount) external; | ||
| function withdraw(address account) external; | ||
| function withdraw(address account, uint256 amount) external; | ||
| } | ||
|
|
||
| /// @custom:security-contact [email protected] | ||
|
|
@@ -33,6 +33,7 @@ contract veLike is | |
| struct veLikeStorage { | ||
| address rewardContract; | ||
| uint256 lockTime; | ||
| mapping(address => bool) isLegacyRewardContract; | ||
| } | ||
|
|
||
| // keccak256(abi.encode(uint256(keccak256("veLike.storage")) - 1)) & ~bytes32(uint256(0xff)) | ||
|
|
@@ -50,6 +51,7 @@ contract veLike is | |
| error ErrNoRewardToClaim(); | ||
| error ErrNonTransferable(); | ||
| error ErrWithdrawLocked(); | ||
| error ErrNotLegacyRewardContract(); | ||
|
|
||
| /// @custom:oz-upgrades-unsafe-allow constructor | ||
| constructor() { | ||
|
|
@@ -83,6 +85,48 @@ contract veLike is | |
| $.rewardContract = rewardContract; | ||
| } | ||
|
|
||
| /** | ||
| * setLegacyRewardContract function | ||
| * | ||
| * Add or remove a legacy reward contract from the allowlist. | ||
| * Legacy reward contracts can be claimed by users after reward rotation. | ||
| * | ||
| * @param rewardContract - the legacy reward contract address | ||
| * @param allowed - true to allow, false to disallow | ||
| */ | ||
| function setLegacyRewardContract( | ||
| address rewardContract, | ||
| bool allowed | ||
| ) public onlyOwner { | ||
| veLikeStorage storage $ = _getveLikeData(); | ||
| $.isLegacyRewardContract[rewardContract] = allowed; | ||
| } | ||
|
|
||
| /** | ||
| * claimLegacyReward function | ||
| * | ||
| * Claim reward from a legacy (rotated-out) reward contract. | ||
| * The legacy reward contract must be allowlisted via setLegacyRewardContract. | ||
| * | ||
| * @param legacyReward - the legacy reward contract address | ||
| * @param account - the account to claim the reward for | ||
| * @return reward - the reward claimed | ||
| */ | ||
| function claimLegacyReward( | ||
| address legacyReward, | ||
| address account | ||
| ) public whenNotPaused nonReentrant returns (uint256) { | ||
| veLikeStorage storage $ = _getveLikeData(); | ||
| if (!$.isLegacyRewardContract[legacyReward]) { | ||
| revert ErrNotLegacyRewardContract(); | ||
| } | ||
| uint256 reward = IRewardContract(legacyReward).claimReward( | ||
| account, | ||
| false | ||
| ); | ||
| return reward; | ||
| } | ||
|
|
||
| /** | ||
| * setLockTime function | ||
| * | ||
|
|
@@ -236,14 +280,16 @@ contract veLike is | |
| address(this), | ||
| assets | ||
| ); | ||
| _mint(receiver, shares); | ||
|
|
||
| // Vault specific logic | ||
| // Vault specific logic: notify reward contract before mint so that | ||
| // _syncStaker reads the pre-deposit balanceOf for correct retroactive rewards. | ||
| IRewardContract rewardContract = getCurrentRewardContract(); | ||
| if (rewardContract != IRewardContract(address(0))) { | ||
| rewardContract.deposit(receiver, assets); | ||
| } | ||
|
|
||
| _mint(receiver, shares); | ||
|
|
||
| // Copying from ERC4626 _deposit function Event for clarity | ||
| emit Deposit(caller, receiver, assets, shares); | ||
| } | ||
|
|
@@ -278,7 +324,7 @@ contract veLike is | |
| // Vault specific logic | ||
| IRewardContract rewardContract = getCurrentRewardContract(); | ||
| if (rewardContract != IRewardContract(address(0))) { | ||
| rewardContract.withdraw(owner); | ||
| rewardContract.withdraw(owner, assets); | ||
| } | ||
|
|
||
| // Copying from ERC4626 _withdraw function Event for clarity | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -240,15 +240,15 @@ contract veLikeReward is | |
| $.totalStaked += stakedAmount; | ||
| } | ||
|
|
||
| function withdraw(address account) public whenNotPaused onlyVault { | ||
| function withdraw( | ||
| address account, | ||
| uint256 amount | ||
| ) public whenNotPaused onlyVault { | ||
| veLikeRewardStorage storage $ = _getveLikeRewardData(); | ||
| if (_isActive()) { | ||
| revert ErrWithdrawLocked(); | ||
| } | ||
| _updateVault(); | ||
| _claimReward(account, false); | ||
| $.totalStaked -= $.stakerInfos[account].stakedAmount; | ||
| $.stakerInfos[account].stakedAmount = 0; | ||
| $.totalStaked -= amount; | ||
| $.stakerInfos[account].stakedAmount -= amount; | ||
| } | ||
|
||
|
|
||
| /** | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to check
$.totalStaked >= amount;?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should keep track correctly, I updated the op manual. The amount should have sync via
_syncStakerin new noLock reward. For the 1st vault, it should no longer call this after the interface update.hmm, so you are right, this update is not necessary for the first lock, we can keep the old logic.