Putty contest - TrungOre's results

An order-book based american options market for NFTs and ERC20s.

General Information

Platform: Code4rena

Start Date: 29/06/2022

Pot Size: $50,000 USDC

Total HM: 20

Participants: 133

Period: 5 days

Judge: hickuphh3

Total Solo HM: 1

Id: 142

League: ETH

Putty

Findings Distribution

Researcher Performance

Rank: 36/133

Findings: 2

Award: $185.31

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: berndartmueller

Also found by: IllIllI, Lambda, TrungOre, auditor0517, hansfriese, sashik_eth, shenwilly

Labels

bug
duplicate
2 (Med Risk)
old-submission-method

Awards

137.9519 USDC - $137.95

External Links

Lines of code

https://github.com/code-423n4/2022-06-putty/blob/3b6b844bc39e897bd0bbb69897f2deff12dc3893/contracts/src/PuttyV2.sol#L500

Vulnerability details

Impact

user can't withdraw their asset

Proof of concept

Now there are no checks for the feeAmount to be transfered via function withdraw(). As baseAsset can be an arbitrary token, in the case when such token doesn't allow for zero amount transfers and feeAmount = 0, the fee and also the asset can become unavailable. (tx revert)

if ((order.isCall && isExercised) || (!order.isCall && !isExercised)) {
    // send the fee to the admin/DAO if fee is greater than 0%
    uint256 feeAmount = 0;
    if (fee > 0) {
        feeAmount = (order.strike * fee) / 1000;
        /// feeAmount = 0 --> transfer fail 
        ERC20(order.baseAsset).safeTransfer(owner(), feeAmount);
    }


    ERC20(order.baseAsset).safeTransfer(msg.sender, order.strike - feeAmount);


    return;
}

Of course, if the amount of baseToken is high enough, this loss can't happen. But assume that there is a token with low precision and high price (precision = 1,2 and token value is very high like BTC), this issue will be noticeable.

Tools Used

Manual review

add check feeAmount > 0 before transfer

if ((order.isCall && isExercised) || (!order.isCall && !isExercised)) {
    // send the fee to the admin/DAO if fee is greater than 0%
    uint256 feeAmount = 0;
    if (fee > 0) {
        feeAmount = (order.strike * fee) / 1000;
        if (feeAmount > 0) { /// add check here 
            ERC20(order.baseAsset).safeTransfer(owner(), feeAmount);    
        }
    }

    ERC20(order.baseAsset).safeTransfer(msg.sender, order.strike - feeAmount);

    return;
}

#0 - outdoteth

2022-07-07T12:48:24Z

Duplicate: withdraw() can be DOS’d for baseAsset ERC20s that prevent 0 transfers if the calculated feeAmount is 0 due to rounding: https://github.com/code-423n4/2022-06-putty-findings/issues/283

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