You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository has been archived by the owner on May 26, 2023. It is now read-only.
github-actionsbot opened this issue
Feb 21, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
Bounties can only be funded while they are still open. But, deposits can be refunded at any time. If a depositor refunds after the bounty is closed, the reward distribution will be broken.
Vulnerability Detail
This issue affects the TieredFixedBounty and TieredPercentageBounty. Before the first tier is claimed, the bounty is set to closed. After that, you're not able to deposit new funds through the DepositManager. But, depositors are still able to refund their deposits given that they expired.
If a deposit is refunded after the contest has ended, the bounty won't have enough funds to cover all the upcoming claims. At least one of the users won't be able to claim their rewards.
Impact
Refunds after a competition is closed will break the reward distribution.
Code Snippet
Given that we use a TieredPercentageBounty:
Alice, Bob, and Charlie deposit 1000 tokens each with Alice's expiration date set to 1 week
First user claims their reward and the ClaimManager closes the bounty using closeCompetition():
if (_bounty.status() == 0) {
_bounty.closeCompetition();
emit BountyClosed(
_bounty.bountyId(),
address(_bounty),
_bounty.organization(),
address(0),
block.timestamp,
_bounty.bountyType(),
new bytes(0),
VERSION_1
);
}
The bounty calculates the total funding which is used to distribute each tier's rewards:
/// @notice Similar to close() for single priced bounties. closeCompetition() freezes the current funds for the competition.
function closeCompetition() external onlyClaimManager {
require(
status == OpenQDefinitions.OPEN,
Errors.CONTRACT_ALREADY_CLOSED
);
status = OpenQDefinitions.CLOSED;
bountyClosedTime = block.timestamp;
for (uint256 i = 0; i < getTokenAddresses().length; i++) {
address _tokenAddress = getTokenAddresses()[i];
fundingTotals[_tokenAddress] = getTokenBalance(_tokenAddress);
}
}
As described in the function's comment, it assumes the funds to be frozen.
5. Alice's deposit expires and she refunds her deposit using refundDeposit():
This leaves the bounty with a total of 2000 tokens instead of the original 3000. But, the fundingTotals state variable still uses the original 3000 value. Subsequent claims will try to distribute more tokens than the bounty holds.
Tool used
Manual Review
Recommendation
Refunds should be disabled after the competition closes.
Sign up for freeto subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelHighA valid High severity issueRewardA payout will be made for this issue
Ruhum
medium
Deposits can be refunded after a bounty closed
Summary
Bounties can only be funded while they are still open. But, deposits can be refunded at any time. If a depositor refunds after the bounty is closed, the reward distribution will be broken.
Vulnerability Detail
This issue affects the TieredFixedBounty and TieredPercentageBounty. Before the first tier is claimed, the bounty is set to
closed
. After that, you're not able to deposit new funds through the DepositManager. But, depositors are still able to refund their deposits given that they expired.If a deposit is refunded after the contest has ended, the bounty won't have enough funds to cover all the upcoming claims. At least one of the users won't be able to claim their rewards.
Impact
Refunds after a competition is closed will break the reward distribution.
Code Snippet
Given that we use a TieredPercentageBounty:
setPayoutSchedule()
closeCompetition()
:As described in the function's comment, it assumes the funds to be frozen.
5. Alice's deposit expires and she refunds her deposit using
refundDeposit()
:This leaves the bounty with a total of 2000 tokens instead of the original 3000. But, the
fundingTotals
state variable still uses the original3000
value. Subsequent claims will try to distribute more tokens than the bounty holds.Tool used
Manual Review
Recommendation
Refunds should be disabled after the competition closes.
Duplicate of #266
The text was updated successfully, but these errors were encountered: