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 Oct 1, 2023. It is now read-only.
sherlock-admin opened this issue
Mar 27, 2023
· 0 comments
Labels
DuplicateA valid issue that is a duplicate of an issue with `Has Duplicates` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
Unbounded loop causes dos and relayers cannot be compensated
Summary
Unbounded loop causes dos and relayers cannot be compensated
Vulnerability Detail
In the Carousel.sol contract there is unbounded loop in the mintRollovers function. we can see this unbounded loop in the snippet below.
while ((index - prevIndex) < (_operations)) {
// only roll over if last epoch is resolvedif (epochResolved[queue[index].epochId]) {
uint256 entitledShares =previewWithdraw(
queue[index].epochId,
queue[index].assets
);
// mint only if user won epoch he is rolling overif (entitledShares > queue[index].assets) {
// skip the rollover for the user if the assets cannot cover the relayer fee instead of revert.if (queue[index].assets < relayerFee) {
index++;
continue;
}
// @note we know shares were locked up to this point_burn(
queue[index].receiver,
queue[index].epochId,
queue[index].assets
);
// transfer emission tokens out of contract otherwise user could not access them as vault shares are burned_burnEmissions(
queue[index].receiver,
queue[index].epochId,
queue[index].assets
);
// @note emission token is a known token which has no before transfer hooks which makes transfer safer
emissionsToken.safeTransfer(
queue[index].receiver,
previewEmissionsWithdraw(
queue[index].epochId,
queue[index].assets
)
);
emitWithdraw(
msg.sender,
queue[index].receiver,
queue[index].receiver,
_epochId,
queue[index].assets,
entitledShares
);
uint256 assetsToMint = queue[index].assets - relayerFee;
_mintShares(queue[index].receiver, _epochId, assetsToMint);
emitDeposit(
msg.sender,
queue[index].receiver,
_epochId,
assetsToMint
);
rolloverQueue[index].assets = assetsToMint;
rolloverQueue[index].epochId = _epochId;
// only pay relayer for successful mints
executions++;
}
}
index++;
}
because the amount can be infinitely large, the loop may run out of gas and this in turn will cause a dos for the protocol. The relayers will be failed to be compensated because of this denial of service.
only when the roll over request win in the epoch round, the execution is incremented and the relayer is compensated with the relayer fee, but it is possible there is a large number of queued request that does not win the epoch, the relayer still pay the gas fee to process fee and get no compensation. this is seen in the snippet below.
queue[index].epochId,
queue[index].assets
);
// mint only if user won epoch he is rolling overif (entitledShares > queue[index].assets) {
// skip the rollover for the user if the assets cannot cover the relayer fee instead of revert.if (queue[index].assets < relayerFee) {
index++;
continue;
}
Impact
Unbounded loop can cause a denial of service in the protocol. Relayers cannot be paid and functions do not work properly. Direct loss of funds for the relayers.
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` labelMediumA valid Medium severity issueRewardA payout will be made for this issue
ShadowForce
medium
Unbounded loop causes dos and relayers cannot be compensated
Summary
Unbounded loop causes dos and relayers cannot be compensated
Vulnerability Detail
In the
Carousel.sol
contract there is unbounded loop in themintRollovers
function. we can see this unbounded loop in the snippet below.because the amount can be infinitely large, the loop may run out of gas and this in turn will cause a dos for the protocol. The relayers will be failed to be compensated because of this denial of service.
only when the roll over request win in the epoch round, the execution is incremented and the relayer is compensated with the relayer fee, but it is possible there is a large number of queued request that does not win the epoch, the relayer still pay the gas fee to process fee and get no compensation. this is seen in the snippet below.
Impact
Unbounded loop can cause a denial of service in the protocol. Relayers cannot be paid and functions do not work properly. Direct loss of funds for the relayers.
Code Snippet
https://github.com/Y2K-Finance/Earthquake/blob/736b2e1e51bef6daa6a5ecd1decb7d156316d795/src/v2/Carousel/Carousel.sol#L361-L459
Tool used
Manual Review
Recommendation
still send at least a part of the relayer fee to relayer and also limit the unbounded loop to avoid running out of gas error.
Duplicate of #172
The text was updated successfully, but these errors were encountered: