sherlock-audit / 2023-03-Y2K-judging

7 stars 1 forks source link

libratus - Adversary can block rollover by adding a smart contract that rejects new shares when minted #497

Closed sherlock-admin closed 1 year ago

sherlock-admin commented 1 year ago

libratus

high

Adversary can block rollover by adding a smart contract that rejects new shares when minted

Summary

Adversary can block rollover for all users by using a smart contract that rejects new shares minted

Vulnerability Detail

mintRollovers in Carousel goes over all requested rollovers sequentially and transfers users' positions to the new epoch. If, for some reason, it reverts for one of the positions, the whole rollover process is blocked.

An attacker can initiate such revert by using the ERC1155 callback functionality. On lines 436-437 new shares are being minted to the receiver address

uint256 assetsToMint = queue[index].assets - relayerFee;
_mintShares(queue[index].receiver, _epochId, assetsToMint);

The receiver in this case can be a smart contract. When new ERC1155 shares are minted to the smart contract, the onERC1155Received callback is invoked. The contract can revert during the callback, which will completely block rollover for all users.

For the attacker to put poisonous receiver address in the rollover queue, it has to deposit first. This means attacker's contract need to be able to accept shares during the deposit but reject shares during rollover. This can be done via configuration.

contract BlockingRollover is IERC1155Receiver, Ownable {
    bool private shouldRejectERC1155 = false;

    function setShouldReject(bool value) public onlyOwner {
        shouldRejectERC1155 = value;
    }

    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public override returns (bytes4) {
        if (shouldRejectERC1155) revert("Can't accept tokens");

        return this.onERC1155Received.selector;
    }
    // Methods to interact with Carousel below
    // ....
}

Impact

Rollover functionality completely broken

Code Snippet

https://github.com/sherlock-audit/2023-03-Y2K/blob/main/Earthquake/src/v2/Carousel/Carousel.sol#L436-L437

Tool used

Manual Review

Recommendation

Perhaps use try/catch when attempting to mint shares and skip over the rollover request in case of error

Duplicate of #468