- $47,500 USDC main award pot
- $2,500 USDC gas optimization award pot
- Join C4 Discord to register
- Submit findings using the C4 form
- Read our guidelines for more details
- Starts October 5, 2022 20:00 UTC
- Ends October 10, 2022 20:00 UTC
- How many contracts are in scope? 10
- Total SLoC for these contracts? around 1100
- How many external imports are there? 11
- How many separate interfaces and struct definitions are there for the contracts within scope? 5
- Does most of your code generally use composition or inheritance? more composition
- How many external calls? only erc20, erc721, and erc1155 transfers
- What is the overall line coverage percentage provided by your tests? 90%
- Is there a need to understand a separate part of the codebase / get context in order to audit this part of the protocol? false
- Does it use an oracle? true
- If yes, please describe what kind? e.g. chainlink or ..? Optional feature requires an oracle signature in order to fulfill an order. We will maintain the oracle that creates signatures unless the user requests us to stop.
- Does the token conform to the ERC20 standard? No token is involved.
- Are there any novel or unique curve logic or mathematical models? No
- Does it use a timelock function? Only the listingTime and expirationTime on orders
- Is it an NFT? No
- Does it have an AMM? No
- Is it a fork of a popular project? false
- Does it use rollups? false
- Is it multi-chain? false
- Does it use a side-chain? false
- Do you have a preferred timezone for communication? PDT
The Blur Exchange is a single token exchange enabling transfers of ERC721/ERC1155 for ETH/WETH. It uses a ERC1967 proxy pattern and consists of three main components (1) BlurExchange, (2) MatchingPolicy, (3) ExecutionDelegate.
The exchange accepts two types of signature authentication determined by a signatureVersion
parameter - single or bulk. Single listings are authenticated via a signature of the order hash.
To bulk list, the user will produce a merkle tree from the order hashes and sign the root. To verify, the respective merkle path for the order will be packed in extraSignature
, the merkle root will be reconstructed from the order and merkle path, and the signature will be validated.
This feature allows a user to opt-in to require an authorized oracle signature of the order with a recent block number. This enables an off-chain cancellation method where the oracle can continue to provide signatures to potential takers, until the user requests the oracle to stop. After some period of time, the old oracle signatures will expire.
To opt-in, the user has to set the expirationTime
to 0. In order to fulfill the order, the oracle signature has to be packed in extraSignature
and the blockNumber
set to what was signed by the oracle.
Order matching - PolicyManager
In order to maintain flexibility with the types of orders and methods of matching that the exchange is able to execute, the order matching logic is separated to a set of whitelisted matching policies. The responsibility of each policy is to assert the criteria for a valid match are met and return the parameters for proper execution -
price
- matching pricetokenId
- NFT token id to transferamount
- (for erc1155) amount of the token to transferassetType
-ERC721
orERC1155
Transfer approvals - ExecutionDelegate
Ultimately, token approval is only needed for calling transfer functions on ERC721
, ERC1155
, or ERC20
. The ExecutionDelegate
is a shared transfer proxy that can only call these transfer functions. There are additional safety features to ensure the proxy approval cannot be used maliciously.
- The calling contract must be approved on the
ExecutionDelegate
- Users have the ability to revoke approval from the
ExecutionDelegate
without having to individually calling every token contract.
On-chain methods
cancelOrder(Order order)
- must be called fromtrader
; records order hash incancelledOrFilled
mapping that's checked when validating orderscancelOrders(Order[] orders)
- must be called fromtrader
; callscancelOrder
for each orderincrementNonce()
- increments the nonce of themsg.sender
; all orders signed with the previous nonce are invalid
Off-chain methods
- Oracle cancellations - if the order is signed with an
expirationTime
of 0, a user can request an oracle to stop producing authorization signatures; without a recent signature, the order will not be able to be matched
All the contracts in this section are to be reviewed. Any contracts not in this list are to be ignored for this contest.
File | SLOC | Coverage |
---|---|---|
Interfaces (4) | ||
contracts/interfaces/IPolicyManager.sol | 8 | - |
contracts/interfaces/IExecutionDelegate.sol | 13 | - |
contracts/interfaces/IMatchingPolicy.sol | 24 | - |
contracts/interfaces/IBlurExchange.sol ๐ฐ | 27 | - |
Total (over 4 files): | 72 | - |
Core exchange contract responsible for coordinating the matching of orders and execution of the transfers.
It calls 3 external contracts
PolicyManager
ExecutionDelegate
- Matching Policy
It uses 1 library
MerkleVerifier
It inherits the following contracts
Contract containing all EIP712 compliant order hashing functions
Standard ERC1967 Proxy implementation
Contains all necessary structs and enums for the Blur Exchange
Modifier for reentrancy protection
Library for Merkle tree computations
Approved proxy to execute ERC721, ERC1155, and ERC20 transfers
Includes safety functions to allow for easy management of approvals by users
It calls 3 external contract interfaces
- ERC721
- ERC20
- ERC1155
Contract reponsible for maintaining a whitelist for matching policies
Matching policy for standard fixed price sale of an ERC721 token
Matching policy for standard fixed price sale of an ERC1155 token
Node version v16
- Setup -
yarn setup
- Install packages -
yarn
- Compile contracts -
yarn compile
- Test coverage -
yarn coverage
- Run tests -
yarn test
Or use this all-in-one build command to run the tests
rm -Rf 2022-10-blur || true && git clone https://github.com/code-423n4/2022-10-blur.git && cd 2022-10-blur && yarn setup && nvm install 16.0 && yarn && yarn compile && REPORT_GAS=true yarn test