-
Notifications
You must be signed in to change notification settings - Fork 0
Fix execution hashes #22
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
base: main
Are you sure you want to change the base?
Changes from all commits
39f81d0
699b717
06cf4e7
3a8ac8c
8d0fcea
4b7272f
a81bccf
e48821e
7d9212a
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 |
|---|---|---|
|
|
@@ -45,7 +45,7 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| address public staker; | ||
| address public minter; | ||
| address public veAsset; | ||
| address public feeDistro; | ||
| // address public feeDistro; | ||
| address public rewardFactory; | ||
| address public stashFactory; | ||
| address public tokenFactory; | ||
|
|
@@ -55,8 +55,8 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| address public stakerRewards; //vetoken rewards | ||
| address public stakerLockRewards; // veToken lock rewards xVE3D | ||
| address public lockRewards; //ve3Token rewards(veAsset) | ||
| address public lockFees; //ve3Token veVeAsset fees | ||
| address public feeToken; | ||
| // address public lockFees; //ve3Token veVeAsset fees | ||
| // address public feeToken; | ||
|
|
||
| bool public isShutdown; | ||
|
|
||
|
|
@@ -69,6 +69,18 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| bool shutdown; | ||
| } | ||
|
|
||
| struct FeeDistro { | ||
| address distro; | ||
| address rewards; | ||
| bytes32 executionHash; | ||
| bool active; | ||
| } | ||
|
|
||
| address[] public allFeeTokens; | ||
|
|
||
| //reward identifier -> distro, execution and virtual pool data | ||
| mapping(address => FeeDistro) public feeTokens; | ||
|
|
||
| //index(pid) -> pool | ||
| PoolInfo[] public poolInfo; | ||
| mapping(address => bool) public gaugeMap; | ||
|
|
@@ -110,8 +122,8 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| function __Booster_init( | ||
| address _staker, | ||
| address _minter, | ||
| address _veAsset, | ||
| address _feeDistro | ||
| address _veAsset | ||
| // address _feeDistro | ||
| ) external initializer { | ||
| isShutdown = false; | ||
| staker = _staker; | ||
|
|
@@ -121,7 +133,7 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| poolManager = msg.sender; | ||
| minter = _minter; | ||
| veAsset = _veAsset; | ||
| feeDistro = _feeDistro; | ||
| // feeDistro = _feeDistro; | ||
| lockIncentive = 1000; | ||
| stakerIncentive = 450; | ||
| earmarkIncentive = 50; | ||
|
|
@@ -190,34 +202,39 @@ contract Booster is ReentrancyGuardUpgradeable { | |
|
|
||
| //reward contracts are immutable or else the owner | ||
| //has a means to redeploy and mint cvx via rewardClaimed() | ||
| if (lockRewards == address(0)) { | ||
| require(_rewards != address(0), "Not allowed!"); | ||
| if (lockRewards == address(0) && _rewards != address(0)) { | ||
| lockRewards = _rewards; | ||
| } | ||
| if (stakerRewards == address(0)) { | ||
| require(_stakerRewards != address(0), "Not allowed!"); | ||
| if (stakerRewards == address(0) && _stakerRewards != address(0)) { | ||
| stakerRewards = _stakerRewards; | ||
| } | ||
| if (stakerLockRewards == address(0)) { | ||
| require(_stakerLockRewards != address(0), "Not allowed!"); | ||
| if (stakerLockRewards == address(0) && _stakerLockRewards != address(0)) { | ||
| stakerLockRewards = _stakerLockRewards; | ||
| } | ||
|
|
||
| emit RewardContractsUpdated(_rewards, _stakerRewards, _stakerLockRewards); | ||
| } | ||
|
|
||
| // Set reward token and claim contract, get from Curve's registry | ||
| function setFeeInfo(uint256 _lockFeesIncentive, uint256 _stakerLockFeesIncentive) external { | ||
| // Set reward token and distro claim contract; create new virtual reward pool and sets execution hash | ||
| // Also used to add or update distro contracts and execution hashes for an already active reward token | ||
| function setFeeInfo( | ||
| uint256 _lockFeesIncentive, | ||
| uint256 _stakerLockFeesIncentive, | ||
| address _feeToken, | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we have to pass array of fee tokens even if it is only one to support multiple fee tokens |
||
| address _distro, | ||
| bytes32 _executionHash | ||
| ) external { | ||
| require(msg.sender == feeManager, "!auth"); | ||
| require(_lockFeesIncentive.add(_stakerLockFeesIncentive) == FEE_DENOMINATOR); | ||
| require(_lockFeesIncentive.add(_stakerLockFeesIncentive) == FEE_DENOMINATOR, "!fee"); | ||
|
|
||
| lockFeesIncentive = _lockFeesIncentive; | ||
| stakerLockFeesIncentive = _stakerLockFeesIncentive; | ||
|
|
||
| address _feeToken = IFeeDistro(feeDistro).token(); | ||
| if (feeToken != _feeToken) { | ||
| if (feeTokens[_feeToken].active != true) { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so here we need an iteration on fee tokens and check if it is exist or not |
||
| require(!gaugeMap[_feeToken], "!token"); | ||
| //require that we initialize at the zero index | ||
| //create a new reward contract for the new token | ||
| lockFees = IRewardFactory(rewardFactory).CreateTokenRewards(_feeToken, lockRewards); | ||
| address lockFees = IRewardFactory(rewardFactory).CreateTokenRewards(_feeToken, lockRewards); | ||
|
|
||
| if (_feeToken != veAsset) { | ||
| IRewards(stakerLockRewards).addReward( | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it will create new reward pool (lookFees) for each fee tokens and use mapping to save it |
||
|
|
@@ -230,7 +247,14 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| ); | ||
| } | ||
|
|
||
| feeToken = _feeToken; | ||
| feeTokens[_feeToken] = FeeDistro(_distro, lockFees, _executionHash, true); | ||
|
|
||
| allFeeTokens.push(_feeToken); | ||
|
|
||
| } else { | ||
| feeTokens[_feeToken].distro = _distro; | ||
| feeTokens[_feeToken].executionHash = _executionHash; | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could be move to up with these two lines for update the state |
||
|
|
||
| } | ||
| } | ||
|
|
||
|
|
@@ -407,6 +431,13 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| address token = pool.token; | ||
| ITokenMinter(token).burn(_from, _amount); | ||
|
|
||
| // @dev handle staking factor for Angle , | ||
| // use try and catch as not all Angle gauges have scaling factor | ||
| if (IVoteEscrow(staker).escrowModle() == IVoteEscrow.EscrowModle.ANGLE) { | ||
| try IGauge(gauge).scaling_factor() { | ||
| _amount = _amount.mul(IGauge(gauge).scaling_factor()).div(10**18); | ||
| } catch {} | ||
| } | ||
| //pull from gauge if not shutdown | ||
| // if shutdown tokens will be in this contract | ||
| if (!pool.shutdown) { | ||
|
|
@@ -524,6 +555,7 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| _claimStashReward(stash); | ||
| } | ||
| } | ||
|
|
||
| //veAsset balance | ||
| uint256 veAssetBal = IERC20Upgradeable(veAsset).balanceOf(address(this)); | ||
|
|
||
|
|
@@ -594,20 +626,27 @@ contract Booster is ReentrancyGuardUpgradeable { | |
| } | ||
|
|
||
| //claim fees from fee distro contract, put in lockers' reward contract | ||
| function earmarkFees() external returns (bool) { | ||
| function earmarkFees(address feeToken, bytes calldata _executionData) external returns (bool) { | ||
| // hash our execution data for comparison | ||
| bytes32 hashedExecutionData = keccak256(_executionData); | ||
| // enforce that the execution data is approved | ||
| require(hashedExecutionData == feeTokens[feeToken].executionHash, "!auth"); | ||
| //claim fee rewards | ||
| IStaker(staker).claimFees(feeDistro, feeToken); | ||
| //send fee rewards to reward contract | ||
| IStaker(staker).claimFees(feeTokens[feeToken].distro, feeToken, _executionData); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. as I understand _executionData will have the function signature without the inputs , so I think the inputs are missing here when pass it to function claimFee
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. _executionData is both the function signature and the arguments. This is how we enforce that the arguments passed into claimFees can't be tampered with <3 |
||
| // access contract token balance after claiming rewards | ||
| uint256 _balance = IERC20Upgradeable(feeToken).balanceOf(address(this)); | ||
|
|
||
| // calculate incentive split for reward contracts | ||
| uint256 _lockFeesIncentive = _balance.mul(lockFeesIncentive).div(FEE_DENOMINATOR); | ||
| uint256 _stakerLockFeesIncentive = _balance.mul(stakerLockFeesIncentive).div( | ||
| FEE_DENOMINATOR | ||
| ); | ||
| // transfer to virtual reward pool and queue the new rewards | ||
| if (_lockFeesIncentive > 0) { | ||
| IERC20Upgradeable(feeToken).safeTransfer(lockFees, _lockFeesIncentive); | ||
| IRewards(lockFees).queueNewRewards(_lockFeesIncentive); | ||
| IERC20Upgradeable(feeToken).safeTransfer(feeTokens[feeToken].rewards, _lockFeesIncentive); | ||
| IRewards(feeTokens[feeToken].rewards).queueNewRewards(_lockFeesIncentive); | ||
| } | ||
| // transfer to the VE3D Locker and queue the new rewards | ||
| if (_stakerLockFeesIncentive > 0) { | ||
| IERC20Upgradeable(feeToken).safeTransfer(stakerLockRewards, _stakerLockFeesIncentive); | ||
| IRewards(stakerLockRewards).queueNewRewards(feeToken, _stakerLockFeesIncentive); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. after call the function , it needs iteration for the fee tokens list |
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -251,9 +251,17 @@ contract VoterProxy { | |
| return true; | ||
| } | ||
|
|
||
| function claimFees(address _distroContract, address _token) external returns (uint256) { | ||
| // execute low level contract call on the distro contract and forward claimed rewards to Booster | ||
| function claimFees( | ||
| address _distroContract, | ||
| address _token, | ||
| bytes calldata executionData) | ||
| external returns (uint256) { | ||
| // enforce contract call comes from the correct source | ||
| require(msg.sender == operator, "!auth"); | ||
| IFeeDistro(_distroContract).claim(); | ||
| // execute arbitrary enforced claim | ||
| (bool success, bytes memory result) = _distroContract.call(executionData); | ||
| require(success, "!fail"); | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. did you test it
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested that we were successfully able to claim rewards yup |
||
| uint256 _balance = IERC20(_token).balanceOf(address(this)); | ||
| IERC20(_token).safeTransfer(operator, _balance); | ||
| return _balance; | ||
|
|
@@ -275,4 +283,4 @@ contract VoterProxy { | |
|
|
||
| return (success, result); | ||
| } | ||
| } | ||
| } | ||
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.
we don't need a mapping for all fee distro info for each veasset project , because we have one booster for each veasset project , so it should be a single state for fee distro , execution hash and array of fee tokens (in case there is multiple fee tokens) you could use openzipplein EnumerableSet for fee tokens , and add new mapping for fee token => lockfee (reward address)