Delegate - Baki's results

Securing onchain identities by linking cold and hot wallets

General Information

Platform: Code4rena

Start Date: 05/09/2023

Pot Size: $50,000 USDC

Total HM: 2

Participants: 16

Period: 6 days

Judge: GalloDaSballo

Total Solo HM: 2

Id: 284

League: ETH

Delegate

Findings Distribution

Researcher Performance

Rank: 6/16

Findings: 1

Award: $451.09

🌟 Selected for report: 0

🚀 Solo Findings: 0

Findings Information

🌟 Selected for report: Sathish9098

Also found by: Baki

Labels

bug
G (Gas Optimization)
grade-a
sponsor disputed
G-01

Awards

451.087 USDC - $451.09

External Links

Gas Optimizations Report

Gas OptimizationsIssuesInstances
[G-01]processSpentItems should have non-array input to save gas1

Total issues: 1 instances across 1 issue Total gas saved: 1189 gas

[G-01] processSpentItems should have non-array input to save gas

Total gas saved: 1189 gas

https://github.com/code-423n4/2023-09-delegate/blob/main/src/libraries/CreateOffererLib.sol#L346

Before VS After Function execution cost: 45583 - 44394 = 1189 gas saved (min.)

Instead of this:

    function processSpentItems(SpentItem[] calldata minimumReceived, SpentItem[] calldata maximumSpent)
        internal
        view
        returns (SpentItem[] memory offer, ReceivedItem[] memory consideration)
    {
        if (!(minimumReceived.length == 1 && maximumSpent.length == 1)) revert CreateOffererErrors.NoBatchWrapping();
        if (minimumReceived[0].itemType != ItemType.ERC721 || minimumReceived[0].token != address(this) || minimumReceived[0].amount != 1) {
            revert CreateOffererErrors.MinimumReceivedInvalid(minimumReceived[0]);
        }
        if (maximumSpent[0].itemType != ItemType.ERC721 && maximumSpent[0].itemType != ItemType.ERC20 && maximumSpent[0].itemType != ItemType.ERC1155) {
            revert CreateOffererErrors.MaximumSpentInvalid(maximumSpent[0]);
        }
        offer = new SpentItem[](1);
        offer[0] = SpentItem({itemType: minimumReceived[0].itemType, token: minimumReceived[0].token, identifier: minimumReceived[0].identifier, amount: minimumReceived[0].amount});
        consideration = new ReceivedItem[](1);
        consideration[0] = ReceivedItem({
            itemType: maximumSpent[0].itemType,
            token: maximumSpent[0].token,
            identifier: maximumSpent[0].identifier,
            amount: maximumSpent[0].amount,
            recipient: payable(address(this))
        });
    }

Use this:

    function processSpentItems(SpentItem memory minimumReceived, SpentItem memory maximumSpent)
        internal
        view
        returns (SpentItem[] memory offer, ReceivedItem[] memory consideration)
    {
        if (minimumReceived.itemType != ItemType.ERC721 || minimumReceived.token != address(this) || minimumReceived.amount != 1) {
            revert CreateOffererErrors.MinimumReceivedInvalid(minimumReceived);
        }
        if (maximumSpent.itemType != ItemType.ERC721 && maximumSpent.itemType != ItemType.ERC20 && maximumSpent.itemType != ItemType.ERC1155) {
            revert CreateOffererErrors.MaximumSpentInvalid(maximumSpent);
        }
        offer = new SpentItem[](1);
        offer[0] = SpentItem({itemType: minimumReceived.itemType, token: minimumReceived.token, identifier: minimumReceived.identifier, amount: minimumReceived.amount});
        consideration = new ReceivedItem[](1);
        consideration[0] = ReceivedItem({
            itemType: maximumSpent.itemType,
            token: maximumSpent.token,
            identifier: maximumSpent.identifier,
            amount: maximumSpent.amount,
            recipient: payable(address(this))
        });
    }

#0 - GalloDaSballo

2023-10-02T08:51:23Z

Great refactoring imo

#1 - c4-judge

2023-10-02T09:08:45Z

GalloDaSballo marked the issue as grade-a

#2 - 0xfoobar

2023-10-03T23:21:09Z

This isn't possible to change, this is the interface that Seaport expects

#3 - c4-sponsor

2023-10-03T23:21:22Z

0xfoobar (sponsor) disputed

#4 - GalloDaSballo

2023-10-04T07:50:48Z

This seems to compile

Rewriting the tests looks very laborious

CreateOfferer.sol

    function generateOrder(address fulfiller, SpentItem[] calldata minimumReceived, SpentItem[] calldata maximumSpent, bytes calldata context)
        external
        checkStage(Enums.Stage.generate, Enums.Stage.transfer)
        onlySeaport(msg.sender)
        returns (SpentItem[] memory offer, ReceivedItem[] memory consideration)
    {
        if (context.length != 160) revert Errors.InvalidContextLength();
        Structs.Context memory decodedContext = abi.decode(context, (Structs.Context));
        /// @audit Add some validation here
        (offer, consideration) = Helpers.processSpentItems(minimumReceived[0], maximumSpent[0]);
        Helpers.updateTransientState(transientState, fulfiller, minimumReceived[0], maximumSpent[0], decodedContext);
    }

CreateOffererLib.sol

function processSpentItems(SpentItem calldata minimumReceived, SpentItem calldata maximumSpent)
        internal
        view
        returns (SpentItem[] memory offer, ReceivedItem[] memory consideration)
    {
        if (minimumReceived.itemType != ItemType.ERC721 || minimumReceived.token != address(this) || minimumReceived.amount != 1) {
            revert CreateOffererErrors.MinimumReceivedInvalid(minimumReceived);
        }
        if (maximumSpent.itemType != ItemType.ERC721 && maximumSpent.itemType != ItemType.ERC20 && maximumSpent.itemType != ItemType.ERC1155) {
            revert CreateOffererErrors.MaximumSpentInvalid(maximumSpent);
        }
        offer = new SpentItem[](1);
        offer[0] = SpentItem({itemType: minimumReceived.itemType, token: minimumReceived.token, identifier: minimumReceived.identifier, amount: minimumReceived.amount});
        consideration = new ReceivedItem[](1);
        consideration[0] = ReceivedItem({
            itemType: maximumSpent.itemType,
            token: maximumSpent.token,
            identifier: maximumSpent.identifier,
            amount: maximumSpent.amount,
            recipient: payable(address(this))
        });
    }
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