Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/Hyperfund.sol
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,11 @@ contract Hyperfund is AccessControlUpgradeable, PausableUpgradeable, UUPSUpgrade
/// @notice Issue a Hypercert fraction for a non-financial contribution, only callable by a manager
/// @param _contributor address of the contributor to receive the Hypercert fraction
/// @param _units amount of units to register as a non-financial contribution
function nonfinancialContribution(address _contributor, uint256 _units) external whenNotPaused onlyRole(MANAGER_ROLE) {
function nonfinancialContribution(address _contributor, uint256 _units)
external
whenNotPaused
onlyRole(MANAGER_ROLE)
{
uint256 availableSupply = hypercertMinter.unitsOf(hypercertId);
require(availableSupply >= _units, AmountExceedsAvailableSupply(availableSupply));
_nonfinancialContribution(_contributor, _units);
Expand Down
29 changes: 20 additions & 9 deletions src/Hyperstaker.sol
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ contract Hyperstaker is AccessControlUpgradeable, PausableUpgradeable, UUPSUpgra
address staker = stakes[_hypercertId].staker;
require(staker == msg.sender, NotStakerOfHypercert(staker));
require(!isRoundClaimed(_hypercertId, _roundId), AlreadyClaimed());
uint256 reward = calculateReward(_hypercertId, _roundId);
uint256 reward = _calculateReward(_hypercertId, _roundId);
require(reward != 0, NoRewardAvailable());

_setRoundClaimed(_hypercertId, _roundId);
Expand All @@ -184,14 +184,10 @@ contract Hyperstaker is AccessControlUpgradeable, PausableUpgradeable, UUPSUpgra
/// @param _roundId id of the round to calculate the reward for
/// @return amount of the reward eligable for the staked Hypercert for the given round
function calculateReward(uint256 _hypercertId, uint256 _roundId) public view returns (uint256) {
Round memory round = rounds[_roundId];
require(round.endTime != 0, RoundNotSet());
uint256 stakeStartTime = stakes[_hypercertId].stakingStartTime;
require(stakeStartTime != 0, NotStaked());
stakeStartTime = stakeStartTime < round.startTime ? round.startTime : stakeStartTime;
uint256 stakeDuration = stakeStartTime > round.endTime ? 0 : round.endTime - stakeStartTime;
return
round.totalRewards * hypercertMinter.unitsOf(_hypercertId) * stakeDuration / (totalUnits * round.duration);
if (isRoundClaimed(_hypercertId, _roundId)) {
return 0;
}
return _calculateReward(_hypercertId, _roundId);
}

/// @notice Check if a staked Hypercert had already claimed a reward for a given round
Expand All @@ -218,6 +214,21 @@ contract Hyperstaker is AccessControlUpgradeable, PausableUpgradeable, UUPSUpgra

// INTERNAL FUNCTIONS

/// @notice Calculate the reward for a staked Hypercert for a given round
/// @param _hypercertId id of the Hypercert to calculate the reward for
/// @param _roundId id of the round to calculate the reward for
/// @return amount of the reward eligable for the staked Hypercert for the given round
function _calculateReward(uint256 _hypercertId, uint256 _roundId) internal view returns (uint256) {
Round memory round = rounds[_roundId];
require(round.endTime != 0, RoundNotSet());
uint256 stakeStartTime = stakes[_hypercertId].stakingStartTime;
require(stakeStartTime != 0, NotStaked());
stakeStartTime = stakeStartTime < round.startTime ? round.startTime : stakeStartTime;
uint256 stakeDuration = stakeStartTime > round.endTime ? 0 : round.endTime - stakeStartTime;
return
round.totalRewards * hypercertMinter.unitsOf(_hypercertId) * stakeDuration / (totalUnits * round.duration);
}

/// @notice Get the hypercert type id for a given hypercert id
/// @param _hypercertId id of the Hypercert to get the type id for
/// @return hypercert type id for the given hypercert id
Expand Down
2 changes: 2 additions & 0 deletions test/Hyperfund.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ contract HyperfundTest is Test {
}

function test_RevertWhen_RedeemNotFraction() public {
vm.prank(manager);
hyperfund.nonfinancialContribution(contributor, amount);
vm.startPrank(contributor);
vm.recordLogs();
hypercertMinter.mintClaim(contributor, totalUnits, "uri", IHypercertToken.TransferRestrictions.AllowAll);
Expand Down
8 changes: 8 additions & 0 deletions test/Hyperstaker.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@ contract HyperstakerTest is Test {
assertEq(hyperstaker.calculateReward(stakerHypercertId, 0), 0);
}

function test_CalculateReward_0WhenRoundClaimed() public {
_setupStake();
_setupRewardEth();
vm.prank(staker);
hyperstaker.claimReward(stakerHypercertId, 0);
assertEq(hyperstaker.calculateReward(stakerHypercertId, 0), 0);
}

function test_RevertWhen_CalculateRewardNoReward() public {
_setupStake();
vm.expectRevert(RoundNotSet.selector);
Expand Down
Loading