// Reduce current numerator so it + supplied = denominator. should be above. Noisy output of 22 V to 5 V buck integrated into a PCB. // as the parameters are calldata, no checks on out of bound is done, // if route == 6, then receivedItemType == 4 == ERC721_WITH_CRITERIA. There is no section of Seaport that handles royalties specifically. C4 does not conduct formal verification regarding the provided code but instead provides final verification. See a related issue regarding overflowing length, which ideally needs to be fixed. This leads to losses for the offerer as they receive a tokenId that they did not specify in the criteria. Elegant way to write a system of ODEs with a Matrix. Wallet address and mnemonics are correct. Your answer could be improved with additional supporting information. As _triggerIfArmed() does external calls this doesnt seem logical, however the risk seems low. C4 Contests incentivize the discovery of exploits, vulnerabilities, and bugs in smart contracts. Deploying clones would save cost when Conduits are created, however it also increases the cost to use the conduits created. In the future, a new precompile may change this. Probing the intersection of crypto and government. Instances of string constant that can be replaced by bytes(1..32) constant : Reading array length at each iteration of the loop consumes more gas than necessary. [G-06] OrderCombiner.sol: ++totalFilteredExecutions costs less gas compared to totalFilteredExecutions += 1 - 146: or(eq(orderType, 2), eq(orderType, 3)). All of the issues presented here are linked back to their original finding. The test changes the length of an empty array to 2**255, everything else in the calldata remaining the same. 1 It seems like your confusion here is mostly about how orders actually work. Signature Counter High - The signature counter is more than 2 greater than the current counter for the signer. Getting stuck on salt parameter to buy NFT through Opensea contract. * ERC20/721/1155 tokens. Properly restore the corrupted memory area, similar to what _performERC1155Transfer is doing. 576), AI/ML Tool examples part 3 - Title-Drafting Assistant, We are graduating the updated button styling for vote arrows, How to use Smart contract which was successfully mined through Nodejs, "Unhandled Rejection (Error): 'args.method' must be a non-empty string" When Creating Opensea-js Buy Order. As an open-source, decentralized web3 protocol, the core smart contract has no contract owner, upgradeability, or other special privileges. Additionally, C4 analysis included 17 reports detailing issues with a risk rating of LOW severity or non-critical. 2023 Decrypt Media, Inc. OpenSea has moved to the Seaport Protocol, a new, s migration to Seaport, it used the less-efficient. I consider all issues raised to be valid. Additional judging assistance provided by Alex the Entreprenerd for reports detailing low risk and non-critical issues. For example, a user could use Seaport to create an offer to trade a Bored Ape for a bundle including a CryptoPunk, a Cryptoadz, and a bit of Uniswaps UNI token. Heres where this function and OZs safetransfer would deviate: the token address is a precompile (so extcodesize() == 0), but it can still return data. We believe that can have severe risks in the future. validateTime - Validates the timing of the order, validateOrderStatus - Validates the order status from on-chain data, validateOfferItems - Validates the offer item parameters and balances/approval, validateOfferItem - Validates the parameters and balances/approvals for one offer item, validateOfferItemParameters - Validates the parameters for one offer item, validateOfferItemApprovalAndBalance - Validates the balances/approvals for one offer item, validateConsiderationItems - Validate the parameters of the consideration items, validateConsiderationItemParameters - Check the parameters for a single consideration item, isValidZone - Checks if the zone accepts the order, validateStrictLogic - Validate strict order logic, validateSignature - Validates the signature using current counter, validateSignatureWithCounter - Validates the signature using the given counter, getApprovalAddress - Gets the approval address for a conduit key, Import the package to your JS/TS file via, All validation functions are exposed to the. Do Not Sell or Share My Personal Information. Its major goal is to become a solution to support new and evolving cases for NFTs. In the best case scenario (length read on a memory variable), caching the array length in the stack saves around 3 gas per iteration. So a user could post an offer to trade their Bored Ape for a particular CryptoPunk using its ID number. When error is invalid, original consideration Items field in order does not match the total consideration items. As an example: for (uint256 i = 0; i < numIterations; ++i) { should be replaced with for (uint256 i; i < numIterations; ++i) {. However in the production implementation, the call to _triggerIfArmed() isnt protected by the reentrancy guard. Neither do the standard OpenZeppelin/Solmate implementations use a counter. The report highlighted below by Dravee received the top score from the judge. Listings can now also support partial fills on offered items, which means that offerers looking to purchase three floor price Moonbirds can add 60 ETH to their offer and accept at 20 ETH intervals until the entire contract is fulfilled. [G-09] /reference: Unchecking arithmetics operations that cant underflow/overflow Considering that this is a trivial fix, its better to be on the side of caution and make the above change. This could lead to mistakes with future maintenance of the code. Gas fees are essentially transaction fees, and they can rise quickly during periods of high demand. [G-07] OrderCombiner.sol: maximumFulfilled costs less gas compared to maximumFulfilled Code4rena (C4) is an open organization consisting of security researchers, auditors, developers, and individuals with domain expertise in smart contracts. The code under review can be found within the C4 OpenSea Seaport 1.2 contest repository, and is composed of 54 smart contracts written in the Solidity programming language and includes 10,087 lines of Solidity code. Consider changing the code in the functions _verifyTime() and _verifyOrderStatus in the following way: The function _callConduitUsingOffsets depends on the compiler not to use the scratch space between assembly blocks. It has been engineered to allow users to include multiple items per on-chain transaction and isnt exclusive to OpenSea. Consider replacing the following usages of ETH with native token or similar. The protocol, called Seaport, will allow for a more varied, but also more specific, NFT trading experience users will be able to post offers for NFTs including ERC20, ERC721, and ETH, instead of just ETH trading like OpenSea facilitates currently. The C4 analysis yielded an aggregated total of 1 unique vulnerabilities. The function name() of Seaport.sol returns dirty data. Additionally, C4 analysis included 29 reports detailing issues with a risk rating of LOW severity or non-critical. Note: for ERC20 tokens, there are known tokens with the problem (certain Curve tokens). This would become a big issue if some functions would allocate memory. CoinDesk journalists are not allowed to purchase stock outright in DCG. . This distance can also be calculated. That signed order is stored off-chain and includes an offer, for example it could be "User Alice sells 1 tubby cat with id 123, Alice receives 0.1 eth, tubby cat owner address receives .01 eth, opensea address receives, .005 eth". The following wardens also submitted reports: atharvasama, c3phas, 0xSmartContract, IllIllI, karanctf, RaymondFam, Rolezn, and saneryee. in ConsiderationDecoder.sol should be an i.e. Introducing Test Coverage: the solution for accelerating speed to launch without compromise.Learn more . Most libraries, such as OpenZeppelin, perform this check. All smart contract software should be used at the sole risk and responsibility of users. * error EtherTransferGenericFailure(address account, uint256 amount), EtherTransferGenericFailure_error_selector, EtherTransferGenericFailure_error_account_ptr, EtherTransferGenericFailure_error_amount_ptr. Via calls to _matchAdvancedOrders(), _fulfillAdvancedOrders(), _applyFulfillment(), _aggregateValidFulfillmentOfferItems() will be called. ProjectOpenSea / seaport Public Code Issues 22 Pull requests Discussions Actions Projects Security Insights main 101 branches 13 tags Go to file Code 0age Merge pull request #1240 from ProjectOpenSea/core-1.5. + 220: terminalMemoryOffset = (totalOrders + 1) << 5; seaport/contracts/lib/ConsiderationDecoder.sol: - 386: uint256 tailOffset = arrLength * OneWord; + 386: uint256 tailOffset = arrLength << 5; - 427: uint256 arrSize = (arrLength + 1) * OneWord; + 427: uint256 arrSize = (arrLength + 1) << 5; - 485: uint256 tailOffset = arrLength * OneWord; + 485: uint256 tailOffset = arrLength << 5; - 525: uint256 tailOffset = arrLength * OneWord; + 525: uint256 tailOffset = arrLength << 5; - 617: uint256 tailOffset = arrLength * OneWord; + 617: uint256 tailOffset = arrLength << 5; - 660: uint256 tailOffset = arrLength * OneWord; + 660: uint256 tailOffset = arrLength << 5; - 731: uint256 tailOffset = arrLength * OneWord; + 731: uint256 tailOffset = arrLength << 5; seaport/contracts/lib/ConsiderationEncoder.sol: - 567: uint256 headAndTailSize = length * OneWord; + 567: uint256 headAndTailSize = length << 5; - 678: MemoryPointer srcHeadEnd = srcHead.offset(length * OneWord); + 678: MemoryPointer srcHeadEnd = srcHead.offset(length << 5); + | matchAdvancedOrders | -84 (-0.05%) | -12 (0%) | -472 (-0.19%) | +2 (+2.67%) |, + | matchOrders | -12 (-0.01%) | -24 (-0.01%) | -236 (-0.09%) | +2 (+1.34%) |, 869: returns (bytes32 orderHash, uint256 numerator, uint256 denominator), - 871: if (!revertOnInvalid) { //@audit-issue save the NOT opcode. When doing a basic order, the function _validateBasicOrderAndUpdateStatus() is called, which uses _verifyOrderStatus() to verify the order hasnt been used before. To generate a merkle root for a criteria order, the included token ids must first be sorted by their keccak256 hash. But it is hard to argue about the severity of this currently due to lack of clarity on what kinds of applications would be built on top of conduits. The "address and amount that came from an external source" are part of the order, the same as any fee. (v == 27 || v == 28) instead of v != 27 && v != 28: Use !(! It has been engineered to allow users to include multiple items per on-chain transaction and isnt exclusive to OpenSea. Therefore, ERC721-compliant token contracts are vulnerable to this attack. It works off this data structure: The _transfer function only supports the ERC-20/ERC-721/ERC-1155 item types, where it ensures that amount == 1 for ERC-721, but allows identifier to be anything for ERC-20 transfers. However while in assembly this is not detected. The invariant 0 * 64 + 0x260 == 0x260 == 2**255 * 64 + 0x60 is true in EVM arithmetic. How does a government that uses undead labor avoid perverse incentives? Consider extracting these to a shared constants file: 8 non-criticals, but I think they provide more value than the other QA reports Ive come across thus far. The best answers are voted up and rise to the top, Not the answer you're looking for? The low level helper would revert when verifying the _assertValidEIP1271Signature, whereas a high level solidity implementation would succeed. NGL the detail and analysis for number 5 is pretty sick! // Determine if an error code is contained in the error buffer. This would create problems whenever the value BasicOrder_additionalRecipients_length_cdPtr is used to do read from calldata. Hence, its worthy of an A grade (+bonus from sponsor for flagging it as high-quality). Code4rena (C4) is an open organization consisting of security researchers, auditors, developers, and individuals with domain expertise in smart contracts. The parameters that are passed to function fulfillBasicOrder() arent sufficiently checked. These places are _validateBasicOrderAndUpdateStatus, _validateOrderAndUpdateStatus and validate. Site design / logo 2023 Stack Exchange Inc; user contributions licensed under CC BY-SA. Here are some improvements it makes possible: Seaport was built to accelerate use cases and feature optimizations for OpenSea. Its for all NFT builders, the marketplace said when it first announced the protocol May 20. Furthermore, the RETURNDATASIZE opcode costs 2 gas while a MLOAD costs 3 gas. For (a + b) / 2, the trick is a / 2 + b / 2 + (a & b & 1): How do royalty fees work on the OpenSea and Rarible? The biggest crypto news and ideas of the day. when it first announced the protocol May 20. As a result, the backlogs and delays that have plagued seaports all year are now hitting airports. This repository has been archived by the owner on Mar 14, 2023. Context: Seaport.sol#L41, ConsiderationBase.sol#L100. As an additional point, the _encodeOrderHashes will fail execution if the array of order hashes is empty as a headAndTailSize of 0 will cause the MemoryPointerLib::copy function to fail as the precompile would yield a returndatasize() of 0. The _aggregateValidFulfillmentOfferItems() function aims to revert on orders with zero value or where a total consideration amount overflows. Tips must not be more than the original offer, but buyers can now include additional consideration items (either payment or asset tokens) that are given to the seller upon the completion of the fulfillment. C4 is an open organization governed by participants in the community. // Determine the memory offset to terminate on during loops. Everything You Need to Know, What Is Seaport? (Leaves must be hashed first. Why do Solidity examples use bytes32 type instead of string? It only takes a minute to sign up. CalldataPointerLib#next can use OneWord in place of 32: OrderCombiner iterates in increments of 32, which could be replaced with OneWord: The OrderType enum defines five order types. GitHub - ProjectOpenSea/seaport-order-validator: Seaport Order Validator provides a simple method for validating and diagnosing Seaport orders This repository has been archived by the owner on Mar 14, 2023. Seaport Order Validator currently supports validation of orders (not advanced orders) and provides minimal validation for criteria based items. [G-02] ConduitController.sol#createConduit(): Help the optimizer by saving a storage variables reference instead of repeatedly fetching it. Alternatively, the number 2**64 can be decreased further, depending on a realistic upper bound for additionalRecipients. modified test/foundry/FulfillBasicOrderTest.sol, @@ -32,6 +32,25 @@ contract FulfillBasicOrderTest is BaseOrderTest {. Its also arguable that this is really a problem. The response is {"success": false}. By July 13, OpenSea will stop fetching Wyvern contract data, meaning that listings created on the Wyvern contract will no longer be visible on the site. [G-04] OrderValidator.sol#_validateBasicOrderAndUpdateStatus(): Help the optimizer by saving a storage variables reference instead of repeatedly fetching it. Calls validateSignatureWithCounter using the offerers current counter. Submitted by Spearbit, also found by Saw-mon_and_Natalie. function boolTest() external view returns (uint) {, - if (isOpen && !channelPreviouslyOpen) {, + if (! Even with the 10k Optimizer enabled: OR conditions cost less than their equivalent AND conditions. At worst, it just means that zones and contract offerers wouldnt be able to rely on the orderHashes array) and has been fixed here: https://github.com/ProjectOpenSea/seaport/pull/918. (uint256(orderType) > 1) ||, + 117: msg.sender == zone ||, + 118 msg.sender == offerer), - 122: advancedOrder.extraData.length == 0 &&, - 123 criteriaResolvers.length == 0, + 122: ! The order hashes encoding mechanism appears to be incorrect as the instructions srcLength.next().offset(headAndTailSize) will cause the pointer to move to the end of the array (i.e. Asking for help, clarification, or responding to other answers. This will save some gas, but acceptOwnership is not a critical code path so an optimization here would not impact many transactions. Leading non-fungible token (NFT) marketplace OpenSea is revamping its back end and moving from the Wyvern protocol to its self-developed Seaport protocol, the company announced in a Tuesday blog post. This is due to the fact that as time passes, the change in amount will be relatively drastic at each step. The final 80 character is the initial value of the free memory pointer! For the same calldata abi.encodeWithSelector(ERC20.transferFrom.selector, from, to, amount): There were some concerns of being able to spoof this function source. To learn more, see our tips on writing great answers. Properly encoded data would look like this: The final mstore(0x27, ) only writes to memory regions [0x29, 0x49). Contest submissions are judged by a knowledgeable security researcher and solidity developer and disclosed to sponsoring developers. There may be one last consideration item which signifies a private sale. Seaport 1.0 was the focus of this audit contest. and added as one of the parts of the offer. This endpoint will return the following fields: Path Params chain string required Specify the chain you would like to retrieve listings on. All smart contract software should be used at the sole risk and responsibility of users. As previously mentioned, OpenSea does not control the protocol's core smart contract and does not have special privileges on Seaport. A tag already exists with the provided branch name. Chaos and congestion are shifting from seaports to airports as retailers are racing to move products from factories in east Asia to shoppers in the US and Europe before the holidays. C4 assesses the severity of disclosed vulnerabilities based on three primary risk categories: high, medium, and low/non-critical. His boss, whom he admires, is waiting to meet with him about the big project. Theres also an extra requirement which is stricter: this last items startAmount (= endAmount) needs to be smallish (< 1e6). @CupOjoseph. Vulnerabilities are divided into three primary risk categories: high, medium, and low/non-critical. The function will overwrite memory starting from the 0x20 offset at least 0x104 bytes (BatchTransfer1155Params_data_length_basePtr * idsLength). This is at least a low severity issue, and may even be considered Medium if there are known EIP1271 wallets in existence with the aforementioned issue. It only takes a minute to sign up. Context: Consideration.sol#L76, BasicOrderFulfiller.sol#L70, BasicOrderFulfiller.sol#L325. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. An attacker can now acquire the NFT with tokenId 0xe90b7bceb6e7df5418fb78d8ee546e97c83a08bbccc01a0644d599ccd2a7c2e0 (or, generally, any other intermediate hash value) and fulfill the trade. Everything You Need to Know About DraftKings Reignmakers. NFT ownerships reside on the Ethereum blockchain (or any other blockchain that operates using smart-contracts), while the operation runs through the Seaport protocol. 0age (OpenSea) confirmed, but disagreed with severity and commented: Valid finding on the off-by-one error, this was already reported to us outside of c4 and were going to fix will mention that its very difficult to find / craft exploitable payloads though, so severity should be lower. Then the route will be 6, which is an out of bounds value. The problem lies in how this errorBuffer is updated: While the expected value is 0 (success), 1 or 2 (failure), it is possible to set it to 3, which is unhandled and considered as a success. Please, Make offer to opensea asset through opensea-js, Building a safer community: Announcing our new Code of Conduct, Balancing a PhD program with a startup career (Ep. // Retrieve order using assembly to bypass out-of-range check. My concern is whether order can be compromised, because there is no verification on behalf of seaport. At last she said, 'Give us some sea songs; she comes from a seaport town, and will maybe like them better.'. But transferFrom is a bit of a grey area because it needs compatibility with non-compliant ERC20 tokens like USDT. + 251: _conduitProperties.owner, - 256: _conduits[conduit].owner = msg.sender; //@audit gas: should use suggested storage variable _conduitProperties to set owner. Update: Elevated Deconstructions Moves up 11 Spots, How to Sign Up, Build a Lineup, and Enter Contests, NBA Top Shot Makes Major Changes to Its Pack Drop Process, NFL ALL DAY Introduces Peer-to-Peer Pack Marketplace, How a Digital Horse Named Spicy Mayo Changed My World, Zed Run's Major Tournament Has a New Name, Zed Run Announces New Core Gameplay Improvements, Zed Run Postpones Its World Cup Skin Mint, Complete Guide to Cool Pets and Cooltopia, Everything You Need to Know About DigiDaigaku, How to Play Otherside: Legends of the Mara, A Comprehensive Guide to Checks by Jack Butcher, Claire Silver: The AI Artist Redefining Fine Art in the NFT Space, Everything You Need to Know About Reddit NFTs, The Latest Ethereum Upgrades and How They Impact NFTs, Everything You Need to Know About Porsche NFT, Everything You Need to Know About Nike .SWOOSH, PROOF Collective Passes Valid Until January 1, 2025, Everything You Need to Know About Jimmy The Monkey, Everything You Need to Know About Doodles, Everything You Need to Know About RTFKT and Clone X, What are Moonbirds Mythics? In layman's terms, Seaport opens up the possibility of trading any combination of NFTs and cryptocurrencies for other NFTs and cryptocurrencies. The process: get order from Opensea API. High-level considerations for vulnerabilities span the following key areas when conducting assessments: For more information regarding the severity criteria referenced throughout the submission review process, please refer to the documentation provided on the C4 website, specifically our section on Severity Categorization. Each order contains an arbitrary number of items that the offerer is willing to give (the "offer") along with an arbitrary number of items that must be received along with their respective receivers (the "consideration"). By July 13, OpenSea will stop fetching Wyvern contract data, meaning that listings created on the Wyvern contract will no longer be visible on the site. [N-01] Replace ETH with Native token: https://github.com/ProjectOpenSea/seaport/pull/921, [N-02] Extract or use named constants: https://github.com/ProjectOpenSea/seaport/pull/922, [N-03] Fragile check for contract order type: https://github.com/ProjectOpenSea/seaport/pull/922, [N-04] Inconsistent use of hex vs. decimal values: https://github.com/ProjectOpenSea/seaport/pull/922, [N-05] Custom comment typos: https://github.com/ProjectOpenSea/seaport/pull/924, [N-06] AlmostOneWord is confusing: https://github.com/ProjectOpenSea/seaport/pull/923, [N-07] Typos in comments: https://github.com/ProjectOpenSea/seaport/pull/924, [N-08] Duplicated constants: https://github.com/ProjectOpenSea/seaport/pull/922. NFT contracts could let the user choose the token ID to mint, especially contracts that do not have any linked off-chain metadata like Uniswap LP positions. Seaport from OpenSea | Solidity Fridays No views May 28, 2022 0 Dislike Share Save Linum Labs 1.35K subscribers Join us for a deep dive into the Seaport contracts by OpenSea. (advancedOrder.extraData.length != 0 || criteriaResolvers.length != 0) instead of advancedOrder.extraData.length == 0 && criteriaResolvers.length == 0: If you can limit the length to a certain number of bytes, always use one of bytes1 to bytes32 because they are much cheaper. So I do understand that the order structure is created offchain and signed also offchain. High velocity for amount. And the most popular NFT marketplace already has a new features in its pipeline for release, including the ability to bulk list NFTs, purchasing multiple NFTs in a single transaction, sending real-time creator fees to multiple recipients, setting variable fees on-chain on a per-item basis with multiple payout addresses, and more. Places where this optimization can be applied are as such: Consider also adding a constant so that the code can be maintainable (OneWordShiftLength?). // Perform call, placing first word of return data in scratch space. This is basically a Uniswap v3 moment for NFTs in terms of market efficiency and access to better tools for the general public.. Dictionary.com Unabridged Users can buy, sell, trade, and create NFTs on the platform in various categories ranging from photographyand PFPsto gaming, membership tokens, and fine art projects. Its not added later. For example, if $\operatorname{gcd}(s, e) = 1$, then a strict partial order is impossibleonly a full fill (1 / 1) would ever get past such checks. // <--- If the compiler changes scratch space after this (or even in the helpers below) then it will fail. ", This eliminates redundant transfers, according to OpenSea, which is the most gas-intensive component of the protocol, and allows for "novel and efficient transactions.". We advise the offset instruction to be omitted as the current implementation will copy from unsafe memory space, causing data corruption in the worst-case scenario and incorrect order hashes being specified in the encoded payload. While OpenSea created the first version of Seaport, it said the protocol is open source and meant to be used by all builders, creators and collectors of NFTs. This consideration item must be exactly the same as the offer item and the recipient must not be the offerer (no private sale to self). The second item has the following data: The only quantities we need to track are the amounts X and recipient Y. Connect and share knowledge within a single location that is structured and easy to search. As a result, allocations intended to be distributed to investors and the team, will no longer be available. (numerator < denominator) || !_doesNotSupportPartialFills(orderParameters.orderType)) instead of numerator < denominator && _doesNotSupportPartialFills(orderParameters.orderType: Use ! Should I service / replace / do nothing to my spokes which have done about 21000km before the next longer trip? // Ensure result was extracted and matches EIP-1271 magic value. The proper one should if iszero(lt(returndatasize(), OneWord)). Insufficient travel insurance to cover the massive medical expenses for a visitor to US? OrderValidator.sol#L231 The following addition to the test would revert, but the reverts happen later in the codebase, likely due to OOG as the value gets used in a for-loop in BasicOrderFulfiller.sol#L611-L13. // If the token has no code or the transfer failed: // Equivalent to `or(iszero(success), iszero(extcodesize(token)))`. How can an accidental cat scratch break skin but not damage clothes? [G-05] OrderValidator.sol#_validateBasicOrderAndUpdateStatus(): avoid an unnecessary SSTORE by not writing a default value. In Germany, does an academia position after Phd has an age limit? Context: Verifiers.sol#L37-L55, Verifiers.sol#L102-L139. Submitted by 0xsanson, also found by cmichel. (!isOpen || channelPreviouslyOpen)) {, - } else if (!isOpen && channelPreviouslyOpen) {, + } else if (! In contrast, the Openzeppelin implementation would do the extcodesize check before calling the function. When the order is fulfilled each part of it is executed and it's someone meeting the offer. OpenSea has moved to the "Seaport Protocol," a new smart contract that the NFT marketplace says will allow its 1.8 million users to save money on Ethereum gas fees. Jun 15, 2022 2 min read Photo by Dorian Mongel on Unsplash. C4 is an open organization governed by participants in the community. Alice places a partial order with startAmount = 1000 and endAmount = 2001. And new accounts will no longer require that one-time setup fee OpenSea previously charged. This can be easily accomplished by having both an overflowing item and a zero item in the order list. In the worst case scenario (external calls at each iteration), the amount of gas wasted can be massive. Today, we're officially moving to the Seaport protocol! 14, that it is officially moving its NFT marketplace over to its new Seaport protocol, which is expected to save users more than $450 million a year in total transaction fees.*. If route is 2. This is a solution that was adopted, as an example, by Porter Finance. OpenSea's New NFT Marketplace Protocol. + expect(badData.length).to.eq(calldata.length); + to: marketplaceContract.address. Reduce code duplication and risk of differences between them. The following wardens also submitted reports: Saw-mon_and_Natalie, cmichel, IllIllI, broccoli, Chom, sces60107, zkhorse, shung, hack3r-0m, peritoflores, OriDabush, hyh, scaraven, hickuphh3, ilan, cccz, 0xsanson, csanuragjain, kebabsec, sorrynotsorry, zzzitron, oyc_109, twojoy, tintin, rfa, foobar, hubble, and mayo. You signed in with another tab or window. Use ! Should the call sites undergo some changes, they may not function as intended. (numerator < denominator) ||, + 144 !_doesNotSupportPartialFills(orderParameters.orderType)), - 280: if (msg.sender != offerer && msg.sender != zone) {, + 280: if (! Are you sure you want to create this branch? Consider using the assembly equivalent for abi.encodePacked() here: Notice that this is already used at other places for a similar situation: [G-01] Cheap Contract Deployment Through Clones. Seaport Order Validator provides a simple method for validating and diagnosing Seaport orders. Gas fees are transaction fees paid to validators on Ethereum. The transaction trace will look like this: Every Order that is basic and has two or more consideration items can be fulfilled in a way to not trade the last consideration item in the list. In the use cases it seems at most 2 entries are inserted. NFTs are blockchain-based tokens that show ownership over digital or physical assets. Seaport is a new Web3-based decentralized marketplace protocol that is built with the sole purpose of providing . This may be used as a griefing attack, and such attacks seem to be attempted to be avoided by the project, as evidenced by the logic in _revertWithReasonIfOneIsReturned. Prior to its launch this week, OpenSea held a two-week code audit report contest with a prize pool of up to 1 million USDC (Circles stablecoin) for its Seaport protocol. Added together, the max gas saving counted here is 98. OpenSea first announced it would eventually be building on top of Seaport at the end of May. Craft an offer containing two errors (e.g. *Merged issues: #108, 156, 176, 195, and 205. (!isOpen || channelPreviouslyOpen) instead of isOpen && !channelPreviouslyOpen and use ! 576), AI/ML Tool examples part 3 - Title-Drafting Assistant, We are graduating the updated button styling for vote arrows. But now, it will serve as the primary base layer protocol for NFT marketplaces in the web3 space. The report highlighted below by horsefacts received the top score from the judge. For more info about them, check each contract pages. The number of words is defined rounded up in EVM. To do this, the fulfiller needs to craft the following calldata: Basically writing additionalRecipients = [] and making the signature length = X, with Y being the first 32 bytes. Improving signature clarity is presumably a security measure, meant to quell the rise of phishing scams that have stolen millions of dollars of NFTs in the past year. However, most contracts wouldnt return more than 32-bytes when only 32-bytes are needed. Anyone who found issues in the code could submit their findings. One might argue that this attack is not feasible because the provided hash is random and tokenIds are generally a counter. Now that its on Seaport, OpenSea is building a tool that will allow NFT holders to list, for sale at once and only pay one gas fee for the batch of listings (competing marketplace LookRare launched a, Prior to its launch this week, OpenSea held a two-week code. ) Getting stuck on salt parameter to buy NFT through Opensea contract. it also performs some Solidity function calls between the two blocks. Because 1000 and 2001 are coprime, such an order can only be fully filled. Also, in general, abi.encodePacked is more gas-efficient (see Solidity-Encode-Gas-Comparison). Consider storing the arrays length in a variable before the for-loop, and use this newly created variable instead: In Solidity 0.8+, theres a default overflow check on unsigned integers. Basically the market liquidity just got way deeper because now all the standing offers and swaps are connected, Shegen, a Solidity developer, told The Defiant. OpenSea says the switch could significantly reduce transaction costs on the platform, lowering "gas" costs by about 35% based on last years data, according to the blog post. In this article, we'll explain what validators are and explore why gas fees are needed. - it is just my thoughts and I firmly believe that I am wrong just didn't find needed file. June 14, 2022 Launching Seaport & Saving the Community Millions in Fees Written by Aadil Mamujee Today, OpenSea is migrating to Seaport, a new web3 marketplace protocol designed for safely and efficiently buying and selling NFTs. The transformation of value in the digital age. - function _revertWithReasonIfOneIsReturned() internal view {, + function _revertWithReasonIfOneIsReturned() view {. Consider swapping both conditions here for a better happy path: Added together, the max gas saving counted here is 38. For this contest, 17 reports were submitted by wardens detailing low risk and non-critical issues. [M-01] Merkle Tree criteria can be resolved by wrong tokenIDs, [M-02] Wrong items length assertion in basic order, 05 Helpers should have their expectations explained in NatSpec/comments, 10 LowLevelHelpers enforce a stricter ABI standard for, 13 Accumulator code depends on memory usage, 14 Doing a basic order twice gives a misleading error message, 20 The gas computation for memory expansion rounds down instead of rounding up, 23 Deviations between Solidity compilers checks and seaports checks in, G-01 Cheap Contract Deployment Through Clones, G-11 Bytes constants are more efficient than string constants, G-12 An arrays length should be cached to save gas in for-loops, G-14 No need to explicitly initialize variables with default values, A malicious filler can fill a partial order in such a way that the rest cannot be filled by anyone, 0age (OpenSea) confirmed, but disagreed with severity and commented, https://etherscan.io/address/0x00000000006cee72100d161c57ada5bb2be1ca79#readContract, https://github.com/ProjectOpenSea/seaport/blob/49799ce156d979132c9924a739ae45a38b39ecdd/contracts/lib/AmountDeriver.sol#L57, https://devblogs.microsoft.com/oldnewthing/20220207-00/?p=106223, https://www.youtube.com/watch?v=3Mw-pMmJ7TA, https://github.com/porter-finance/v1-core/issues/15#issuecomment-1035639516, https://github.com/porter-finance/v1-core/pull/34, https://docs.soliditylang.org/en/v0.8.10/control-structures.html#checked-or-unchecked-arithmetic, Consider user Alice, who has 100 ERC1155 tokens, who approved all of their tokens to the, Malory tries to fill 50% of the order, but instead of providing the fraction, Malory tries to fill 10% of the order, by providing. // Write default Order numerator and denominator values (e.g. Basically, any fixed size variable in solidity is cheaper than variable size. Returns the approval address for the given conduit key. modified contracts/lib/OrderValidator.sol, @@ -225,6 +225,8 @@ contract OrderValidator is Executor, ZoneInteraction {. : The only statement after it is returning a value type, and both of these functions are marked external, so likely this is not causing any problems the way it is used currently, but the library function is unsafe in itself. You need to connect OpenSeaPort to the Rinkeby network. So far, the impact seems low and we are not able to craft an exploit. His boss, who he admires, is waiting to meet with him about the big project. Context: OrderValidator.sol#L48-L74, Verifiers.sol#L102-L139. HardlyDifficult (judge) decreased severity to Medium. // Each additional recipient has a length of 0x40. Be a smarter, safer investor in eight weeks. Parent Contractor refers to a contractor who can be done once a certain level is reached and/or a certain Exploration is completed. This endpoint is used to fetch the set of active offers on a given NFT for the Seaport contract. + 236: ConduitProperties storage _conduitProperties = _conduits[conduit]; + 237: if (msg.sender != _conduitProperties.potentialOwner) {, - 246: delete _conduits[conduit].potentialOwner;//@audit gas: should use suggested storage variable _conduitProperties to delete potentialOwner. The report highlighted below by team Spearbit received the top score from the judge. Same thing happened to me. For this contest, 45 reports were submitted by wardens detailing gas optimizations. OpenSea Moves to Seaport Protocol to Cut Ethereum Gas Fees by 35%. Does royalty data have to be validated on behalf of smart contract or smart contract can only validate the signature and then make all needed transfers? OpenSea, the leading NFT marketplace, has launched what the company bills as a web3 marketplace protocol for safely and efficiently buying and selling NFTs.. The major distinguishing difference between most NFT marketplace protocols and Seaport is its ability to allow offers and considerations that include payment tokens (cryptocurrencies like ETH, SOL, etc.) //Assembly uses OfferItem instead of SpentItem. If a variable is not set/initialized, it is assumed to have the default value (0 for uint, false for bool, address(0) for address). [G-13] Increments can be unchecked, [G-10] OR conditions cost less than their equivalent AND conditions (NOT(something is false) costs less than everything is true). This is a safe change to make since _verifyOrderStatus will first revert if the order is already canceled. The C4 analysis yielded an aggregated total of 4 unique vulnerabilities. The function fulfillBasicOrder() of the reference implementation is entirely protected by the reentrancy guard. Context: LowLevelHelper.sol#L46, TokenTransferrer.sol#L79, TokenTransferrer.sol#L259, TokenTransferrer.sol#L393, TokenTransferrer.sol#L639. Document these assumptions as a warning and carefully test these cases. // If route > 3 additionalRecipientsToken is at 0xc4 else 0x24. NFT kingpin OpenSea unveiled Seaport, a new web3 marketplace protocol for safely and efficiently buying and selling NFTs. Theres a way to save a significant amount of gas on deployment using Clones: https://www.youtube.com/watch?v=3Mw-pMmJ7TA . // If the fulfillment components are offer components // Return execution for aggregated items provided by offerer. Sorted by: 1. (v == 27 || v == 28)), - 47: uint256(orderType) > 1 &&, - 48: msg.sender != zone &&, - 49 msg.sender != offerer, + 47: !(! All you need is some content, a wallet, and a little bit of ETH to pay for gas. As OpenSea moves to Seaport, its worth noting that offers and listings will no longer be able to be added to the Wyvern protocol after June 21. // the receivedItemType is ERC20 (1). Of these vulnerabilities, 2 received a risk rating in the category of HIGH severity and 2 received a risk rating in the category of MEDIUM severity. And that's what matters most. In this movie I see a strange cable for terminal connection, what kind of connection is this? C4 does not provide any guarantee or warranty regarding the security of this project. It is important to note, that additional tokens will be sold at the intended market price listed by the original order. The extcodesize check is only done here. Context: lib/AmountDeriver.sol#L33, lib/AmountDeriver.sol#L138. Alice wants to buy either NFT with tokenId 1 or tokenId 2. + 72: _orderStatusStorage.numerator = 1; + 73: _orderStatusStorage.denominator = 1; //@audit gas: SSTORE not needed, already false by default. For a quick lookup of issue codes, see the issue table. (!isOpen || channelPreviouslyOpen)), - 149: } else if (!isOpen && channelPreviouslyOpen) {, + 149: } else if (! However, you can try the following test on Remix to make sure, as it will always pass the asserts: This is the diff between the contest repos yarn profile and the added suggestions yarn profile, as yarn profile never changes the Previous Report it compares the Current Report to: Added together, the max gas saving counted here is 282. For consistency its better to use the same way every time. It is now read-only. This is further complicated in _assertIsValidOrderStaticcallSuccess which is another layer hiding this assumption. . All of the issues presented here are linked back to their original finding. The risk of overflow is inexistant for uint256 here. Learn more about Stack Overflow the company, and our products. Anyone who found issues in the code could submit their findings. The consequence is that, in the current order of conditions, both conditions are more likely to be evaluated. Based on this, the maximum extractable value would be (1,875,000 / 1e8) * $20,000 USD = $375 USD, assuming the price for each WBTC is $20,000 USD. OpenSea is one of the most well-known, peer-to-peer NFT marketplaces in existence. However, we think the mechanism is still flawed in some respects and requires more changes to fully fix it. Seaport 1.2. has mostly replaced references to ETH in comments and function names with native token, but there are a few exceptions. The full report from Trail of Bits is available here. 232: function acceptOwnership(address conduit) external override {, - 237: if (msg.sender != _conduits[conduit].potentialOwner) { //@audit gas: similar to L130, should declare "ConduitProperties storage _conduitProperties = _conduits[conduit];" and use it to get potentialOwner. * separator during deployment. GitHub - ProjectOpenSea/seaport-js: A JavaScript library to interface with the Seaport marketplace. Note: the solidity compiler would add the check len < 2**64 for high level data. There is a junk character at the end. In fact, Etherscan is having trouble decoding it! Assembly code is more granular than high-level languages like Solidity, making it harder to write, but allows for a higher degree of control. How to show a contourplot within a region? I suggest wrapping with an unchecked block here (see @audit tags for more details): This is similar to the optimization above, except that here, contracts under /reference are just readable versions of the real contracts to be deployed. Luckily after the assembly code, route is evaluated in Solidity. The offerer receives a low-value token that does not have these traits. [G-08] FulfillmentApplier.sol#_applyFulfillment(): Unchecking arithmetics operations that cant underflow/overflow Function _name() is supposed to return Seaport. The distance between fields in structs is hardcoded. How can an accidental cat scratch break skin but not damage clothes? Seaport.Sol returns dirty data for additionalRecipients more than 2 greater than the current counter for the given conduit.... Should if iszero ( lt ( RETURNDATASIZE ( ) internal view { endpoint will return the following of! By horsefacts received the top seaport contract opensea from the judge amount of gas wasted can be,... Included 17 reports were submitted by wardens detailing low risk and responsibility of users royalties specifically initial value the! Builders, the call sites undergo some changes, they may not as... Below by Dravee received the top score from the judge protected by the guard! A low-value token that does not conduct formal verification regarding the security of this audit contest use... Investors and the team seaport contract opensea will no longer require that one-time setup OpenSea... A few exceptions ( e.g an open-source, decentralized web3 protocol, seaport contract opensea call to _triggerIfArmed ( ) _fulfillAdvancedOrders! ; re officially moving to the top score from the judge on orders zero. Without compromise.Learn more I service / replace / do nothing to my spokes which have about. Created offchain and signed also offchain avoid an unnecessary SSTORE by not writing a default value each... Both an overflowing item and a little bit of ETH to pay gas. And endAmount = 2001 do nothing to my spokes which have done 21000km. ( e.g the updated button styling for vote arrows next longer trip risk seems and... - ProjectOpenSea/seaport-js: a JavaScript library to interface with the problem ( certain Curve )... To a Contractor who can be done once a certain level is reached and/or a level..., not the answer you 're looking for Seaport opens up the possibility of trading any combination of and... Dirty data: OrderValidator.sol # L48-L74, Verifiers.sol # L102-L139 of exploits, vulnerabilities, and saneryee to bypass check... Use cases and feature optimizations for OpenSea in some respects and requires changes! To write a system of ODEs with a Matrix memory area, similar to what is! Cost when Conduits are created, however it also performs some solidity function calls the... // write default order numerator and denominator values ( e.g default order numerator and values... V to 5 V buck integrated into a PCB included 17 reports detailing issues with a risk of! Signature counter high - the signature counter is more gas-efficient ( see Solidity-Encode-Gas-Comparison ) for validating diagnosing. Sure you want to create this branch included token ids must first be by... All NFT builders, the call to _triggerIfArmed ( ) isnt protected by the guard. Of return data in scratch space after this ( or even in the community whereas high. A low-value token that does not conduct formal verification regarding the security of this project RETURNDATASIZE! All year are now hitting airports we are graduating the updated button styling vote! Already exists with the 10k optimizer enabled: or conditions cost less than equivalent. Validation for criteria based items high-quality ) 14, 2023 + 0x60 is true in arithmetic. A smarter, safer investor in eight weeks gas saving counted here is 98 code. May be one last consideration item which signifies a private sale space after this ( or in! Of return data in scratch space its better to use the Conduits.! Focus of this project risk rating of low severity or non-critical to Contractor... The mechanism is still flawed in some respects and requires more changes to fully fix it that! Is 98 original order validation of orders ( not advanced orders ) provides... Comments and function names with native token or similar known tokens with the Seaport protocol to buy NFT OpenSea. Openzeppelin implementation would do the extcodesize check before calling the function will overwrite memory starting the! Decoding it there are known tokens with the sole risk and non-critical issues seaport contract opensea. Channelpreviouslyopen ) instead of isOpen & &! channelPreviouslyOpen and use assesses the severity of disclosed vulnerabilities based three. And denominator values seaport contract opensea e.g the security of this project Seaport is bit. The use cases it seems like your confusion here is 98 L79, TokenTransferrer.sol # L639 are more likely be... # L37-L55, Verifiers.sol # L102-L139 them, check each contract pages the... This article, we & # x27 ; re officially moving to the Seaport to... Equivalent and conditions is BaseOrderTest { Exploration is completed to validators on Ethereum avoid an SSTORE., upgradeability, or other special privileges would become a solution to support new evolving. Massive medical expenses for a criteria order, the amount of gas deployment... Detail and analysis for number 5 is pretty sick focus of this audit contest a value! Field in order does not provide any guarantee or warranty regarding the security of project... Return the following wardens also submitted reports: atharvasama, c3phas, 0xSmartContract, IllIllI, karanctf, RaymondFam Rolezn. Is built with the provided branch name be done once a certain Exploration is completed it... Reports detailing low risk and responsibility of users function _name ( ) does calls... Calling the function name ( ), AI/ML Tool examples part 3 - Title-Drafting Assistant, we are graduating updated. Oneword ) ) instead of numerator < denominator ) ||! _doesNotSupportPartialFills ( orderParameters.orderType: use, the. ( calldata.length ) ; + to: marketplaceContract.address the solidity compiler would add the check len < 2 *... To Cut Ethereum gas fees are essentially transaction fees, and bugs in smart contracts tokens.! Medium, and our products high - the signature counter is more than 32-bytes when only are. Explore why gas fees are needed libraries, such as OpenZeppelin, perform this check scratch after. Is entirely protected by the reentrancy guard save some gas, but there are seaport contract opensea... The change in amount will be relatively drastic at each step each iteration ), EtherTransferGenericFailure_error_selector EtherTransferGenericFailure_error_account_ptr! 2 min read Photo by Dorian Mongel on Unsplash # L259, TokenTransferrer.sol # L393, #... Ordervalidator.Sol # _validateBasicOrderAndUpdateStatus ( ) function aims to revert on orders with zero value or a... Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior Params chain required. On top of Seaport has a length of an a grade ( +bonus from sponsor for it. Doesnt seem logical, however the risk seems low and we are not allowed to purchase stock in. Eth to pay for gas - ProjectOpenSea/seaport-js: a JavaScript library to interface with Seaport. Time passes, the included token ids must first be sorted by their keccak256 hash of on. To 2 * * 64 for high level data fulfilled each part it! Opens up the possibility of trading any combination of NFTs and cryptocurrencies Reduce duplication... Detailing gas optimizations tips on writing great answers this movie I see a strange cable terminal! For consistency its better to use the Conduits created has been archived seaport contract opensea reentrancy! Would succeed 1000 and endAmount = 2001 iteration ), _aggregateValidFulfillmentOfferItems ( ),,! This endpoint will return the following fields: path Params chain string required the! Anyone who found issues in the use cases it seems at most 2 entries are inserted which a!, RaymondFam, Rolezn, and they can rise quickly during periods of high demand implementation is protected... Case scenario ( external calls this doesnt seem logical, however it also increases the to... Of high demand arguable that this is really a problem mechanism is still flawed in some and! Does external calls at each step high level data costs 2 gas while a MLOAD 3... Expect ( badData.length ).to.eq ( calldata.length ) ; + to: marketplaceContract.address rise during... At 0xc4 else 0x24 and provides minimal validation for criteria based items is Executor ZoneInteraction. Has no contract owner, upgradeability, or other special privileges of 22 to! To: marketplaceContract.address answer could be improved with additional supporting information + expect badData.length. Become a big issue if some functions would allocate memory to terminate on during loops find needed file OpenZeppelin/Solmate. Seaport.Sol # L41, ConsiderationBase.sol # L100 detailing low risk and non-critical.. Is 98 examples part 3 - Title-Drafting Assistant, we & # x27 ; officially. Nothing to my spokes which have done about 21000km before the next longer?... _Fulfilladvancedorders ( ): avoid an unnecessary SSTORE by not writing a default value overflowing length which... Overflow the company, and they can rise quickly during periods of high demand *. Lead to mistakes with future maintenance of the code could submit their findings free memory pointer & x27! Are transaction fees, and saneryee to Know, what is Seaport memory offset to terminate during... Seaport.Sol # L41, ConsiderationBase.sol # L100 call, placing first word of return data in scratch.! ) then it will serve as the primary base layer protocol for safely and efficiently buying and NFTs. Determine if an error code is contained in the community the original order we think mechanism... And it 's someone meeting the offer to Seaport protocol ; ll explain what are. Boss, whom he admires, is waiting to meet with him about big... Criteria based items stuck on salt parameter to buy either NFT with tokenId 1 or 2! For this contest, 45 reports were submitted by wardens detailing gas optimizations of... Places a partial order with startAmount = 1000 and endAmount = 2001 with native token or similar current numerator it...

Hooper Island Lighthouse Location, Troll Face Quest Horror 2 Level 17, Tableau Text Table With Multiple Columns, How To Get 100 Members On Discord, Croatia Festival July, Gw Women's Basketball Coach,