SIZE contest - 8olidity's results

An on-chain sealed bid auction protocol.

General Information

Platform: Code4rena

Start Date: 04/11/2022

Pot Size: $42,500 USDC

Total HM: 9

Participants: 88

Period: 4 days

Judge: 0xean

Total Solo HM: 2

Id: 180

League: ETH

SIZE

Findings Distribution

Researcher Performance

Rank: 23/88

Findings: 2

Award: $176.56

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Trust

Also found by: 8olidity, HE1M, JTJabba, KIntern_NA, KingNFT, M4TZ1P, Picodes, PwnedNoMore, R2, V_B, bin2chen, cryptonue, cryptphi, fs0c, hansfriese

Awards

38.2759 USDC - $38.28

Labels

bug
3 (High Risk)
partial-25
upgraded by judge
duplicate-252

External Links

Lines of code

https://github.com/code-423n4/2022-11-size/blob/main/src/SizeSealed.sol#L391-L410

Vulnerability details

Impact

In cancelAuction, there are statements to determine whether to call before finalize(). Because createAuction() assigns the value of a.dat.lowestquote to type(uint128).max.

    function cancelAuction(uint256 auctionId) external {
        Auction storage a = idToAuction[auctionId];
        if (msg.sender != a.data.seller) {
            revert UnauthorizedCaller();
        }
        // Only allow cancellations before finalization
        // Equivalent to atState(idToAuction[auctionId], ~STATE_FINALIZED)
        if (a.data.lowestQuote != type(uint128).max) {
            revert InvalidState();
        }

        // Allowing bidders to cancel bids (withdraw quote)
        // Auction considered forever States.AcceptingBids but nobody can finalize
        a.data.seller = address(0);
        a.timings.endTimestamp = type(uint32).max;

        emit AuctionCancelled(auctionId);

        SafeTransferLib.safeTransfer(ERC20(a.params.baseToken), msg.sender, a.params.totalBaseAmount);
    }

However, he just rely on a.data.lowstquote! = type(uint128).max to judge, but if in finalize(), the clearingquote that was passed in was type(uint128).max. Then you can bypass his judgment. And there is no restriction on Clearingquote in finalize().

Proof of Concept

clearingQuote = type(uint128).max

Tools Used

vscode

Judging clearingquote in finalize()

#0 - trust1995

2022-11-09T00:53:13Z

I believe the issue is lacking specifics and a POC to demonstrate the issue, so not descriptive enough to be satisfactory. Issue is described well in #252 and many other dups.

#1 - c4-judge

2022-11-09T15:07:34Z

0xean marked the issue as duplicate

#2 - c4-judge

2022-11-09T16:02:51Z

0xean marked the issue as partial-25

#3 - c4-judge

2022-12-06T00:27:22Z

0xean changed the severity to 3 (High Risk)

Findings Information

🌟 Selected for report: neko_nyaa

Also found by: 8olidity, Bnke0x0, Matin, TwelveSec, brgltd, ctf_sec, djxploit, horsefacts, jayphbee

Labels

bug
2 (Med Risk)
satisfactory
duplicate-48

Awards

138.2838 USDC - $138.28

External Links

Lines of code

https://github.com/code-423n4/2022-11-size/blob/main/src/SizeSealed.sol#L163

Vulnerability details

Impact

solmate won't check if the token is a contract or not.

A hacker could set traps for non existing tokens to steal future funds from users.

ref: https://github.com/code-423n4/2022-08-olympus-findings/issues/489

Proof of Concept

The safeTransfer() functions used in the contract are wrappers around the solmate library. Solmate will not check for contract existance.

File: src/libraries/TransferHelper.sol
function safeTransferFrom(
    ERC20 token,
    address from,
    address to,
    uint256 amount
) internal {
    (bool success, bytes memory data) = address(token).call(
        abi.encodeWithSelector(ERC20.transferFrom.selector, from, to, amount)
    );

    require(success && (data.length == 0 || abi.decode(data, (bool))), "TRANSFER_FROM_FAILED");
}

function safeTransfer(
    ERC20 token,
    address to,
    uint256 amount
) internal {
    (bool success, bytes memory data) = address(token).call(
        abi.encodeWithSelector(ERC20.transfer.selector, to, amount)
    );

    require(success && (data.length == 0 || abi.decode(data, (bool))), "TRANSFER_FAILED");
}

Tools Used

vscode

Looking at OpenZeppelin's implementation, a check is made on the code for the token address.

https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L36-L42

address(token).code.length > 0

Consider using OpenZeppelin or checking for contract existance manually inside TransferHelper.sol.

#0 - c4-judge

2022-11-09T15:18:56Z

0xean marked the issue as duplicate

#1 - c4-judge

2022-12-06T00:25:37Z

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