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 22, 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
Griefing attack may cause indefinite DoS on refunding
Summary
Refunding can be blocked indefinitely if iterating all deposits consumes the entire gas limit of a block. Creating a huge number of deposits can be a cheap attack for two reasons: 1) transaction fees are low on Polygon; 2) fake ERC20 tokens, which cost nothing, can be deposited. As a result, deposited amounts may be locked indefinitely in the bounty contracts.
bytes32[] memory depList =this.getDeposits();
for (uint256 i =0; i < depList.length; i++) {
if (
block.timestamp<
depositTime[depList[i]] + expiration[depList[i]] &&
tokenAddress[depList[i]] == _depositId
) {
lockedFunds += volume[depList[i]];
}
}
Also, in each iteration, multiple storage slots are read: depositTime, expiration, tokenAddress, and volume, which increases the gas consumption, especially when there are many deposits to check.
Knowing the amount of locked funds is required to obtain the amount of available, i.e. unlocked, funds during refunding:
A malicious actor creates a fake ERC20 token and makes a huge amount of small deposits with infinite expiration (type(uint256)-1) into a bounty contract.
When a depositor tries to refund their deposits, the getLockedFunds function is called to compute locked funds.
Since the number of deposits in the contract is huge, the loop in the getLockedFunds function consumes the entire gas limit of a block and causes the refund transaction to revert.
The depositor is not able to withdraw their funds since refunding is blocked.
Impact
Deposited funds may be locked indefinitely in the bounty contracts due to an artificially increased gas consumption of a refunding transaction.
Consider setting a limit on the number of deposits so that the limit is high enough for all valid use cases and low enough to not allow the griefing attack.
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
Jeiwan
high
Griefing attack may cause indefinite DoS on refunding
Summary
Refunding can be blocked indefinitely if iterating all deposits consumes the entire gas limit of a block. Creating a huge number of deposits can be a cheap attack for two reasons: 1) transaction fees are low on Polygon; 2) fake ERC20 tokens, which cost nothing, can be deposited. As a result, deposited amounts may be locked indefinitely in the bounty contracts.
Vulnerability Detail
Every deposit into a bounty contract is saved into the
deposits
array. The array is iterated when calculating the amount of locked funds, i.e. the sum of all deposits that haven't expired yet. As you can see, the loop is not bounded:Also, in each iteration, multiple storage slots are read:
depositTime
,expiration
,tokenAddress
, andvolume
, which increases the gas consumption, especially when there are many deposits to check.Knowing the amount of locked funds is required to obtain the amount of available, i.e. unlocked, funds during refunding:
This opens up the following vulnerability:
type(uint256)-1
) into a bounty contract.getLockedFunds
function is called to compute locked funds.getLockedFunds
function consumes the entire gas limit of a block and causes the refund transaction to revert.Impact
Deposited funds may be locked indefinitely in the bounty contracts due to an artificially increased gas consumption of a refunding transaction.
Code Snippet
BountyCore.sol#L341-L349
Tool used
Manual Review
Recommendation
Consider setting a limit on the number of deposits so that the limit is high enough for all valid use cases and low enough to not allow the griefing attack.
Duplicate of #77
The text was updated successfully, but these errors were encountered: