Arcade.xyz - 0xWaitress's results

The first of its kind Web3 platform to enable liquid lending markets for NFTs.

General Information

Platform: Code4rena

Start Date: 21/07/2023

Pot Size: $90,500 USDC

Total HM: 8

Participants: 60

Period: 7 days

Judge: 0xean

Total Solo HM: 2

Id: 264

League: ETH

Arcade.xyz

Findings Distribution

Researcher Performance

Rank: 9/60

Findings: 1

Award: $1,798.11

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: bin2chen

Also found by: 0xWaitress, caventa, ladboy233

Labels

bug
2 (Med Risk)
satisfactory
edited-by-warden
duplicate-85

Awards

1798.1148 USDC - $1,798.11

External Links

Lines of code

https://github.com/code-423n4/2023-07-arcade/blob/main/contracts/ArcadeTreasury.sol#L384-L394

Vulnerability details

Impact

gscApprove can overwrite the approved allowance of the same spender from previously approved value

gscApprove, approveSmallSpend, approveMediumSpend, approveLargeSpend all calls the same underlying _approve.

Let's say the DAO approved a MediumSpend budget on spender A. Coincidentally, gscWhitelist member would also like to approve some allowance to spender A on the same token. gscApprove would then over-write the previous allowance.

Alternatively, gscApprove caller can also maliciously over-write the allowance of the previously set value for a spender by DAO; or allowance set by other gsc members, by backrunning with a smaller allowance(1wei for example). This causes damage to the daily operation of DAO treasury.

    function gscApprove(
        address token,
        address spender,
        uint256 amount
    ) external onlyRole(GSC_CORE_VOTING_ROLE) nonReentrant {
        if (spender == address(0)) revert T_ZeroAddress("spender");
        if (amount == 0) revert T_ZeroAmount();

        // Will underflow if amount is greater than remaining allowance
        gscAllowance[token] -= amount;

        _approve(token, spender, amount, spendThresholds[token].small);
    }

    function _approve(address token, address spender, uint256 amount, uint256 limit) internal {
        // check that after processing this we will not have spent more than the block limit
        uint256 spentThisBlock = blockExpenditure[block.number];
        if (amount + spentThisBlock > limit) revert T_BlockSpendLimit();
        blockExpenditure[block.number] = amount + spentThisBlock;

        // approve tokens
        IERC20(token).approve(spender, amount);

        emit TreasuryApproval(token, spender, amount);
    }

https://github.com/code-423n4/2023-07-arcade/blob/main/contracts/ArcadeTreasury.sol#L384-L394 https://github.com/code-423n4/2023-07-arcade/blob/main/contracts/ArcadeTreasury.sol#L189-L201

Proof of Concept

Tools Used

Consider using increaseAllowance instead.

Assessed type

Context

#0 - c4-pre-sort

2023-07-29T13:42:04Z

141345 marked the issue as duplicate of #85

#1 - c4-judge

2023-08-11T16:30:58Z

0xean marked the issue as satisfactory

AuditHub

A portfolio for auditors, a security profile for protocols, a hub for web3 security.

Built bymalatrax © 2024

Auditors

Browse

Contests

Browse

Get in touch

ContactTwitter