code-423n4 / 2024-02-ai-arena-findings

4 stars 3 forks source link

`GameItems.sol#mint()` function: Malicious user can block stuff other users in order to replenish his `NFT daily allowance` and unfairly obtain the full amount (items) of specific NFTs #1517

Closed c4-bot-6 closed 8 months ago

c4-bot-6 commented 8 months ago

Lines of code

https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/GameItems.sol#L147-L176 https://github.com/code-423n4/2024-02-ai-arena/blob/main/src/GameItems.sol#L312-L315

Vulnerability details

Impact

The GameItems.sol contract in the AI Arena protocol is designed to manage the lifecycle of game items using the ERC-1155 standard, which includes minting, transferring, and burning of items. This contract plays a crucial role in the game's economy, allowing players to acquire, use, and trade various items within the game.

Game items are digital assets that provide players with various benefits, abilities, or cosmetic enhancements within the AI Arena game. These items can range from weapons and armor to unique skins and collectibles, each with specific attributes and value.

Players can mint new game items by calling the GameItems.sol#mint() function, specifying the tokenId of the item they wish to mint and the quantity. The minting process is subject to certain conditions, including the availability of the item (finite supply) and the player's daily allowance for that specific tokenId.

    function mint(uint256 tokenId, uint256 quantity) external {
        require(tokenId < _itemCount);
        uint256 price = allGameItemAttributes[tokenId].itemPrice * quantity;
        require(_neuronInstance.balanceOf(msg.sender) >= price, "Not enough NRN for purchase");
        require(
            allGameItemAttributes[tokenId].finiteSupply == false ||
            (
                allGameItemAttributes[tokenId].finiteSupply == true &&
                quantity <= allGameItemAttributes[tokenId].itemsRemaining
            )
        );
        require(
            dailyAllowanceReplenishTime[msg.sender][tokenId] <= block.timestamp ||
            quantity <= allowanceRemaining[msg.sender][tokenId]
        );

        _neuronInstance.approveSpender(msg.sender, price);
        bool success = _neuronInstance.transferFrom(msg.sender, treasuryAddress, price);
        if (success) {
            if (dailyAllowanceReplenishTime[msg.sender][tokenId] <= block.timestamp) {
                _replenishDailyAllowance(tokenId);
            }
            allowanceRemaining[msg.sender][tokenId] -= quantity;
            if (allGameItemAttributes[tokenId].finiteSupply) {
                allGameItemAttributes[tokenId].itemsRemaining -= quantity;
            }
            _mint(msg.sender, tokenId, quantity, bytes("random"));
            emit BoughtItem(msg.sender, tokenId, quantity);
        }
    }

Each tokenId has a daily allowance mechanism. The daily allowance mechanism is a feature designed to limit the number of certain game items a player can mint within a 24-hour period. This is particularly important for rare or valuable items, ensuring fair distribution among players and maintaining the items' scarcity and value. The contract tracks the daily allowance for each tokenId per user, along with the time when the allowance will be replenished. Code Reference: Daily Allowance Mechanism*

    /// @notice Replenishes the daily allowance for the specified game item token.
    /// @dev This function is called when a user buys a game item after the replenish interval has passed.
    /// @param tokenId The ID of the game item token.
    function _replenishDailyAllowance(uint256 tokenId) private {
        allowanceRemaining[msg.sender][tokenId] = allGameItemAttributes[tokenId].dailyAllowance;
        dailyAllowanceReplenishTime[msg.sender][tokenId] = uint32(block.timestamp + 1 days);
    }

The minting relays on this daily allowance. Now, there is a serious problem, because malicious user can stuffing (the whole duration that is required for his daily allowance to replenish) with dummy transactions. The stuffing with dummy transactions is very cheap on Arbitrum. According to https://www.cryptoneur.xyz/en/gas-fees-calculator 50M gas (which is several whole blocks) - costs ~11.1192 USD$ on Arbitrum. So malicious user can exploit the daily allowance mechanism to monopolize the minting of rare or valuable game items. By performing block stuffing - filling blocks with dummy transactions, the malicious user can delay other transactions, ensuring their own minting transactions are processed as soon as the daily allowance replenishes.

Also important note here is that mining the block takes significantly more time than executing the transactions (as it writes in the following article: https://medium.com/hackernoon/the-anatomy-of-a-block-stuffing-attack-a488698732ae)

Proof of Concept

  1. A malicious user identifies a valuable game item with limited daily allowance or just want the all items of specific NFT.
  2. The user prepares to mint the maximum allowable quantity of this item as soon as the daily allowance replenishes.
  3. Just before the allowance replenishment, the user initiates numerous dummy transactions to congest the network, effectively blocking or delaying other users' minting transactions.
  4. As the daily allowance replenishes, the malicious user's minting transaction is processed, allowing them to obtain the full amount of the rare items for that day, while other users are unable to mint due to network congestion.

Impact: This behavior allows the malicious user to unfairly accumulate rare or valuable items, undermining the fairness and balance intended by the daily allowance mechanism.

This exploit undermines the integrity of the game's economy and the fairness of item distribution. It allows individuals to gain an unfair advantage, potentially hoarding valuable items and disrupting the intended gameplay dynamics.

Tools Used

Manual Review

Recommended Mitigation Steps

There isn't very elegant way to fix this issue, but the mitigation that I can recommend is implement transaction rate limiting. Introduce rate limiting for user mining transactions to prevent rapid succession that can lead to block overflows.

Assessed type

Context

c4-pre-sort commented 8 months ago

raymondfam marked the issue as insufficient quality report

raymondfam commented 8 months ago

The function logic would revert circumventing paving the way as FCFS to the next transaction by others.

c4-pre-sort commented 8 months ago

raymondfam marked the issue as duplicate of #80

c4-judge commented 7 months ago

HickupHH3 marked the issue as unsatisfactory: Invalid

radeveth commented 7 months ago

Hey, @HickupHH3!

This isn't duplicate of issue #80. Please review it again!

HickupHH3 commented 7 months ago

wholeheartedly DISagree; this is a general DoS issue that can be applied to all protocols. stuff txns to prevent liquidations, swapping etc.

radeveth commented 7 months ago

but stuffing liquidations can't be done endlessly (in the more situation) and without ANY purpose, right.

here, users have purpose and they just need to complete the transaction in no more than one day, which is very cheap on Arbitrum. moreover, the impact is much more than DoS, a malicious user can exploit the daily allowance mechanism to monopolize the minting of rare or valuable game items. By performing block stuffing - filling blocks with dummy transactions, the malicious user can delay other transactions, ensuring their own minting transactions are processed as soon as the daily allowance replenishes.

also there is another bug in prevous c4 contest about block stuffing which was considered as valid medium severity issue: code-423n4/2023-05-venus-findings#525

@HickupHH3

HickupHH3 commented 7 months ago

disagree, in this context, it'll be like participating in a whitelist token sale, FCFS. there isn't a loss to the protocol; users unfortunately know that it's whilst stock last, if they fail, then too bad.

radeveth commented 7 months ago

yes, when we look at this side, I also think that:

But, this bug leads to unfair obtaining the full amount (items) of specific NFTs from a specific user/s, which will break the logic of AI Arena protocol as game items are digital assets that provide players with various benefits, abilities, etc, within the AI Arena game. These items can range from weapons and armor to unique skins and collectibles, each with specific attributes and value., which is definately not the protocol desire.

as in my report writes:

Impact: This behavior allows the malicious user to unfairly accumulate rare or valuable items, undermining the fairness and balance intended by the daily allowance mechanism. This exploit undermines the integrity of the game's economy and the fairness of item distribution. It allows individuals to gain an unfair advantage, potentially hoarding valuable items and disrupting the intended gameplay dynamics.

@HickupHH3

Cheers!

HickupHH3 commented 7 months ago

Rate limiting is kinda in-place already with allowanceRemaining (per user, per item).

radeveth commented 7 months ago

Rate limiting is kinda in-place already with allowanceRemaining (per user, per item). yep and my report describe how this allowanceRemaining (daily allowance) can be bypassed.

It's crucial to differentiate between general DoS vulnerabilities that affect various protocols and the specific exploit (aka my issue) within the AI Arena's GameItems.sol minting mechanism. While you argues that this issue falls under a general DoS category applicable to all protocols, the nuances of the AI Arena protocol warrant a closer examination. Let me explain.

Firstly, my issue leverages the daily allowance mechanism uniquely implemented in the AI Arena protocol, allowing a malicious user to monopolize the minting of rare or valuable game items. This is not merely a DoS attack but a strategic manipulation that undermines the fairness and competitive balance the daily allowance mechanism aims to ensure. In the context of AI Arena, where game items provide significant advantages, the ability to unfairly acquire these items can significantly disrupt the game's economy and player experience. Also the block stuffing cannot be done on every chain.

Furthermore, while you mentions that rate limiting through allowanceRemaining is similar to participating in a whitelist token sale on a first-come-first-serve basis, this perspective overlooks the strategic abuse potential. Unlike a token sale, where early participation is the only requirement, my issue involves deliberately timing and congesting the network to exclude others from participating. This is not about being first; it's about denying others the opportunity to participate at all.

Lastly, the as we saw, the block stuffing issues in previous contests were acknowledged as valid medium severity issues, underscores the legitimacy of the block stuffing, because block stuffing cannot be done on every chain. The ability to manipulate the minting process not only results in DoS but also in an unfair accumulation of valuable assets, contrary to the intended design of the AI Arena protocol.

imo my issue is valid because it exploits specific mechanics of the AI Arena protocol to gain an unfair advantage, going beyond general network congestion issues. It undermines both the fairness and the integrity of the AI Arena game, which requires consideration and mitigation beyond that provided by existing speed limit measures.

@HickupHH3!

HickupHH3 commented 7 months ago

i don't see this being an issue: if the period was a couple of blocks, sounds do-able. but an entire day? those interacting with other DApps on Arbitrum will complain that their txns aren't going through; devs will step in and do something.

my decision on this is final, you may escalate to the appeal committee if you'd like.