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` labelHighA valid High severity issueRewardA payout will be made for this issue
Due to an unsafe external call on the _mint() function a user can break the depositQueue.
Vulnerability Detail
When the mintDepositInQueue() function is executed, it process all the deposits in the depositQueue in a FILO order. Eventually, the _mintShares() function is called, which calls the _mint() function of the ERC1155.sol contract, with queue[i].receiver as the to parameter.
At the end of the _mint() function, the _doSafeTransferAcceptanceCheck() function is called, this function makes an external call to to, which is an address chosen arbitrarily by the depositor, if this is a contract. This contract can fail on purpose to revert the execution of the mintDepositInQueue() function.
Impact
Because the deposits are never processed and hence the vault shares never minted, there is no a viable way to take out the tokens sent by the depositors that decided to use the queueDeposit.
Changing the controller to call the sendTokens() function on the vault does not work since the vault can only send tokens up to an amount equal to finalTVL[epochId] which is equal to the totalSupply of the vault shares for the given epochId.
A way to take the tokens out from the contract is by changing the controller and calling the setClaimTVL() function with an amount (like if they won the epoch) that allows the users who have vault shares to withdraw them via the withdraw() function (because their shares are worth more). But there is no guarantee these users will send back the tokens.
Because the depositQueue follows a FILO order, the only affected entries are the ones previous to the attacker deposit, but because the cost of the attack is too low (the minimum cost is the relayerFee), the attacker can place multiple entries to affect the most users.
Proof of Concept
Create the next contract:
// SPDX-License-Identifier: MITpragma solidity0.8.17;
interfaceCarousel2 {
function deposit(uint256id, uint256assets, addressreceiver) external;
function mintDepositInQueue(uint256epochId, uint256operations) external;
}
interfaceERC202 {
function balanceOf(addressaccount) externalreturns(uint256);
function approve(addressspender, uint256amount) externalreturns(bool);
}
contractBreakDepositQueue {
Carousel2 public collateralVault;
Carousel2 public premiumVault;
ERC202public underlyingAsset;
constructor(address_collateralVault, address_premiumVault, address_underlyingAsset) {
collateralVault =Carousel2(_collateralVault);
premiumVault =Carousel2(_premiumVault);
underlyingAsset =ERC202(_underlyingAsset);
}
function breakDepositQueue(uint256epochId) external {
uint256 balance = underlyingAsset.balanceOf(address(this));
underlyingAsset.approve(address(premiumVault), balance);
callDepositPremium();
}
function callDepositPremium() internal {
premiumVault.deposit(0, underlyingAsset.balanceOf(address(this)), address(this));
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytesmemory
) publicreturns (bytes4) {
revert();
}
}
Then create a test on the EndToEndCaraouselTest.t.sol file.
Import the attacker contract: import "../../../src/attacker/BreakDepositQueue.sol";
Add to the state variables BreakDepositQueue public breakDepositQueueContract;
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
0xRobocop
high
The depositQueue can get DoSed
Summary
Due to an unsafe external call on the
_mint()
function a user can break thedepositQueue
.Vulnerability Detail
When the
mintDepositInQueue()
function is executed, it process all the deposits in thedepositQueue
in a FILO order. Eventually, the_mintShares()
function is called, which calls the_mint()
function of theERC1155.sol
contract, withqueue[i].receiver
as theto
parameter.At the end of the
_mint()
function, the_doSafeTransferAcceptanceCheck()
function is called, this function makes an external call toto
, which is an address chosen arbitrarily by the depositor, if this is a contract. This contract can fail on purpose to revert the execution of themintDepositInQueue()
function.Impact
Because the deposits are never processed and hence the vault shares never minted, there is no a viable way to take out the tokens sent by the depositors that decided to use the
queueDeposit
.Changing the
controller
to call thesendTokens()
function on the vault does not work since the vault can only send tokens up to an amount equal tofinalTVL[epochId]
which is equal to thetotalSupply
of the vault shares for the given epochId.A way to take the tokens out from the contract is by changing the
controller
and calling thesetClaimTVL()
function with an amount (like if they won the epoch) that allows the users who have vault shares to withdraw them via thewithdraw()
function (because their shares are worth more). But there is no guarantee these users will send back the tokens.Because the
depositQueue
follows a FILO order, the only affected entries are the ones previous to the attacker deposit, but because the cost of the attack is too low (the minimum cost is therelayerFee
), the attacker can place multiple entries to affect the most users.Proof of Concept
Create the next contract:
Then create a test on the
EndToEndCaraouselTest.t.sol
file.import "../../../src/attacker/BreakDepositQueue.sol";
BreakDepositQueue public breakDepositQueueContract;
setUp()
function:forge test --match-contract EndToEndCarouselTest --match-test testBreakingDepositQueue
.Code Snippet
https://github.com/sherlock-audit/2023-03-Y2K/blob/main/Earthquake/src/v2/Carousel/Carousel.sol#L334
Tool used
Manual Review
Recommendation
Remove
_doSafeTransferAcceptanceCheck()
from_mint()
.Duplicate of #468
The text was updated successfully, but these errors were encountered: