diff --git a/.gas_reports/1b38bad3b68b67d33d46b883526b86eb39a0c747.json b/.gas_reports/1b38bad3b68b67d33d46b883526b86eb39a0c747.json
new file mode 100644
index 000000000..3963926d7
--- /dev/null
+++ b/.gas_reports/1b38bad3b68b67d33d46b883526b86eb39a0c747.json
@@ -0,0 +1,509 @@
+{
+ "commitHash": "1b38bad3b68b67d33d46b883526b86eb39a0c747",
+ "contractReports": {
+ "ConduitControllerMock": {
+ "name": "ConduitControllerMock",
+ "methods": [
+ {
+ "method": "createConduit",
+ "min": 218710,
+ "max": 225954,
+ "avg": 223418,
+ "calls": 6
+ }
+ ],
+ "bytecodeSize": 10231,
+ "deployedBytecodeSize": 7165
+ },
+ "EIP1271Wallet": {
+ "name": "EIP1271Wallet",
+ "methods": [
+ {
+ "method": "approveNFT",
+ "min": null,
+ "max": null,
+ "avg": 49640,
+ "calls": 14
+ },
+ {
+ "method": "registerDigest",
+ "min": 22220,
+ "max": 44132,
+ "avg": 36828,
+ "calls": 3
+ },
+ {
+ "method": "revertWithMessage",
+ "min": null,
+ "max": null,
+ "avg": 21658,
+ "calls": 1
+ },
+ {
+ "method": "setValid",
+ "min": 21682,
+ "max": 43594,
+ "avg": 32638,
+ "calls": 2
+ }
+ ],
+ "bytecodeSize": 2648,
+ "deployedBytecodeSize": 2475
+ },
+ "ExcessReturnDataRecipient": {
+ "name": "ExcessReturnDataRecipient",
+ "methods": [
+ {
+ "method": "setRevertDataSize",
+ "min": null,
+ "max": null,
+ "avg": 43431,
+ "calls": 2
+ }
+ ],
+ "bytecodeSize": 1939,
+ "deployedBytecodeSize": 1912
+ },
+ "LocalConduit": {
+ "name": "LocalConduit",
+ "methods": [
+ {
+ "method": "execute",
+ "min": 77373,
+ "max": 2230819,
+ "avg": 460006,
+ "calls": 6
+ },
+ {
+ "method": "executeBatch1155",
+ "min": null,
+ "max": null,
+ "avg": 97123,
+ "calls": 1
+ },
+ {
+ "method": "executeWithBatch1155",
+ "min": 97570,
+ "max": 361429,
+ "avg": 228658,
+ "calls": 4
+ },
+ {
+ "method": "updateChannel",
+ "min": null,
+ "max": null,
+ "avg": 45782,
+ "calls": 1
+ }
+ ],
+ "bytecodeSize": 3071,
+ "deployedBytecodeSize": 3030
+ },
+ "LocalConduitController": {
+ "name": "LocalConduitController",
+ "methods": [
+ {
+ "method": "acceptOwnership",
+ "min": null,
+ "max": null,
+ "avg": 32543,
+ "calls": 1
+ },
+ {
+ "method": "cancelOwnershipTransfer",
+ "min": null,
+ "max": null,
+ "avg": 27927,
+ "calls": 1
+ },
+ {
+ "method": "createConduit",
+ "min": 676714,
+ "max": 676858,
+ "avg": 676815,
+ "calls": 53
+ },
+ {
+ "method": "transferOwnership",
+ "min": null,
+ "max": null,
+ "avg": 50233,
+ "calls": 2
+ },
+ {
+ "method": "updateChannel",
+ "min": 34369,
+ "max": 120903,
+ "avg": 117103,
+ "calls": 71
+ }
+ ],
+ "bytecodeSize": 12007,
+ "deployedBytecodeSize": 8660
+ },
+ "PausableZone": {
+ "name": "PausableZone",
+ "methods": [
+ {
+ "method": "cancelOrders",
+ "min": null,
+ "max": null,
+ "avg": 63429,
+ "calls": 1
+ }
+ ],
+ "bytecodeSize": 6266,
+ "deployedBytecodeSize": 6162
+ },
+ "PausableZoneController": {
+ "name": "PausableZoneController",
+ "methods": [
+ {
+ "method": "acceptOwnership",
+ "min": null,
+ "max": null,
+ "avg": 28938,
+ "calls": 1
+ },
+ {
+ "method": "assignOperator",
+ "min": null,
+ "max": null,
+ "avg": 50920,
+ "calls": 1
+ },
+ {
+ "method": "assignPauser",
+ "min": null,
+ "max": null,
+ "avg": 47171,
+ "calls": 1
+ },
+ {
+ "method": "cancelOrders",
+ "min": null,
+ "max": null,
+ "avg": 71953,
+ "calls": 1
+ },
+ {
+ "method": "cancelOwnershipTransfer",
+ "min": null,
+ "max": null,
+ "avg": 24574,
+ "calls": 1
+ },
+ {
+ "method": "createZone",
+ "min": 1297527,
+ "max": 1297539,
+ "avg": 1297537,
+ "calls": 31
+ },
+ {
+ "method": "executeMatchAdvancedOrders",
+ "min": null,
+ "max": null,
+ "avg": 288317,
+ "calls": 2
+ },
+ {
+ "method": "executeMatchOrders",
+ "min": null,
+ "max": null,
+ "avg": 281910,
+ "calls": 2
+ },
+ {
+ "method": "pause",
+ "min": 49978,
+ "max": 52108,
+ "avg": 51043,
+ "calls": 4
+ },
+ {
+ "method": "transferOwnership",
+ "min": null,
+ "max": null,
+ "avg": 47194,
+ "calls": 2
+ }
+ ],
+ "bytecodeSize": 19205,
+ "deployedBytecodeSize": 12730
+ },
+ "Reenterer": {
+ "name": "Reenterer",
+ "methods": [
+ {
+ "method": "prepare",
+ "min": 49244,
+ "max": 2351445,
+ "avg": 1061658,
+ "calls": 26
+ }
+ ],
+ "bytecodeSize": 2594,
+ "deployedBytecodeSize": 2567
+ },
+ "Seaport": {
+ "name": "Seaport",
+ "methods": [
+ {
+ "method": "cancel",
+ "min": 39242,
+ "max": 56402,
+ "avg": 52034,
+ "calls": 16
+ },
+ {
+ "method": "fulfillAdvancedOrder",
+ "min": 95544,
+ "max": 226315,
+ "avg": 160994,
+ "calls": 194
+ },
+ {
+ "method": "fulfillAvailableAdvancedOrders",
+ "min": 147377,
+ "max": 331980,
+ "avg": 212402,
+ "calls": 30
+ },
+ {
+ "method": "fulfillAvailableOrders",
+ "min": 162397,
+ "max": 214502,
+ "avg": 201312,
+ "calls": 21
+ },
+ {
+ "method": "fulfillBasicOrder",
+ "min": 88569,
+ "max": 1630448,
+ "avg": 599930,
+ "calls": 187
+ },
+ {
+ "method": "fulfillBasicOrder_efficient_6GL6yc",
+ "min": 88181,
+ "max": 109207,
+ "avg": 98694,
+ "calls": 6
+ },
+ {
+ "method": "fulfillOrder",
+ "min": 118404,
+ "max": 225043,
+ "avg": 178518,
+ "calls": 108
+ },
+ {
+ "method": "incrementCounter",
+ "min": null,
+ "max": null,
+ "avg": 45076,
+ "calls": 6
+ },
+ {
+ "method": "matchAdvancedOrders",
+ "min": 178287,
+ "max": 299609,
+ "avg": 248806,
+ "calls": 72
+ },
+ {
+ "method": "matchOrders",
+ "min": 156696,
+ "max": 343360,
+ "avg": 261699,
+ "calls": 151
+ },
+ {
+ "method": "validate",
+ "min": 51276,
+ "max": 81981,
+ "avg": 71595,
+ "calls": 29
+ }
+ ],
+ "bytecodeSize": 25871,
+ "deployedBytecodeSize": 23981
+ },
+ "SeaportRouter": {
+ "name": "SeaportRouter",
+ "methods": [
+ {
+ "method": "fulfillAvailableAdvancedOrders",
+ "min": 179579,
+ "max": 305363,
+ "avg": 220418,
+ "calls": 8
+ }
+ ],
+ "bytecodeSize": 7172,
+ "deployedBytecodeSize": 6759
+ },
+ "TestContractOfferer": {
+ "name": "TestContractOfferer",
+ "methods": [
+ {
+ "method": "activate",
+ "min": 201532,
+ "max": 246646,
+ "avg": 205405,
+ "calls": 34
+ },
+ {
+ "method": "extendAvailable",
+ "min": null,
+ "max": null,
+ "avg": 50724,
+ "calls": 1
+ },
+ {
+ "method": "extendRequired",
+ "min": null,
+ "max": null,
+ "avg": 45800,
+ "calls": 1
+ }
+ ],
+ "bytecodeSize": 8697,
+ "deployedBytecodeSize": 8505
+ },
+ "TestContractOffererNativeToken": {
+ "name": "TestContractOffererNativeToken",
+ "methods": [
+ {
+ "method": "activate",
+ "min": null,
+ "max": null,
+ "avg": 139191,
+ "calls": 1
+ }
+ ],
+ "bytecodeSize": 6880,
+ "deployedBytecodeSize": 6709
+ },
+ "TestERC1155": {
+ "name": "TestERC1155",
+ "methods": [
+ {
+ "method": "mint",
+ "min": 47221,
+ "max": 49901,
+ "avg": 49441,
+ "calls": 249
+ },
+ {
+ "method": "setApprovalForAll",
+ "min": 26095,
+ "max": 45995,
+ "avg": 45402,
+ "calls": 470
+ }
+ ],
+ "bytecodeSize": 4147,
+ "deployedBytecodeSize": 4120
+ },
+ "TestERC20": {
+ "name": "TestERC20",
+ "methods": [
+ {
+ "method": "approve",
+ "min": 28908,
+ "max": 46272,
+ "avg": 45800,
+ "calls": 328
+ },
+ {
+ "method": "blockTransfer",
+ "min": 21993,
+ "max": 43905,
+ "avg": 32949,
+ "calls": 4
+ },
+ {
+ "method": "mint",
+ "min": 34012,
+ "max": 68476,
+ "avg": 67461,
+ "calls": 159
+ },
+ {
+ "method": "setNoReturnData",
+ "min": 21939,
+ "max": 43851,
+ "avg": 32895,
+ "calls": 2
+ }
+ ],
+ "bytecodeSize": 5835,
+ "deployedBytecodeSize": 4743
+ },
+ "TestERC721": {
+ "name": "TestERC721",
+ "methods": [
+ {
+ "method": "mint",
+ "min": 51478,
+ "max": 68782,
+ "avg": 65874,
+ "calls": 303
+ },
+ {
+ "method": "setApprovalForAll",
+ "min": 26180,
+ "max": 46080,
+ "avg": 45539,
+ "calls": 516
+ }
+ ],
+ "bytecodeSize": 5154,
+ "deployedBytecodeSize": 4413
+ },
+ "TestInvalidContractOfferer": {
+ "name": "TestInvalidContractOfferer",
+ "methods": [
+ {
+ "method": "activate",
+ "min": 201568,
+ "max": 201580,
+ "avg": 201574,
+ "calls": 2
+ }
+ ],
+ "bytecodeSize": 8132,
+ "deployedBytecodeSize": 7947
+ },
+ "TestInvalidContractOffererRatifyOrder": {
+ "name": "TestInvalidContractOffererRatifyOrder",
+ "methods": [
+ {
+ "method": "activate",
+ "min": null,
+ "max": null,
+ "avg": 201571,
+ "calls": 1
+ }
+ ],
+ "bytecodeSize": 8194,
+ "deployedBytecodeSize": 8002
+ },
+ "TransferHelper": {
+ "name": "TransferHelper",
+ "methods": [
+ {
+ "method": "bulkTransfer",
+ "min": 78155,
+ "max": 1445768,
+ "avg": 635839,
+ "calls": 3
+ }
+ ],
+ "bytecodeSize": 4207,
+ "deployedBytecodeSize": 3903
+ }
+ }
+}
\ No newline at end of file
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 000000000..76fc280cf
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,22 @@
+name: Publish Docs to Central Repository
+on:
+ release:
+ types: [created]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - name: Copy developer docs to repository
+ if: github.ref == 'refs/heads/main'
+ uses: nkoppel/push-files-to-another-repository@v1.1.1
+ env:
+ API_TOKEN_GITHUB: ${{ secrets.API_TOKEN_GITHUB }}
+ with:
+ source-files: "docs/"
+ destination-username: "ProjectOpenSea"
+ destination-repository: "developer-docs"
+ destination-directory: "seaport"
+ destination-branch: "main"
+ commit-username: "ProjectOpenSea-seaport"
+ commit-message: "Latest docs from seaport"
\ No newline at end of file
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 000000000..a23bdf588
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,18 @@
+name: Publish Package to npmjs
+on:
+ release:
+ types: [created]
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-node@v2
+ with:
+ node-version: "18.x"
+ registry-url: "https://registry.npmjs.org"
+ - run: grep -RiIln 'openzeppelin-contracts' src | xargs sed -i 's/openzeppelin\-contracts/@openzeppelin\/contracts/g'
+ - run: yarn
+ - run: npm publish --access public
+ env:
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index cb3132aa4..a864f4dbe 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -15,5 +15,5 @@ jobs:
days-before-stale: 60
days-before-close: 14
operations-per-run: 100
- exempt-pr-labels: "work-in-progress"
- exempt-issue-labels: "work-in-progress"
+ exempt-pr-labels: "work-in-progress,Informational"
+ exempt-issue-labels: "work-in-progress,Informational"
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 535cce3eb..0aea0264a 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
- node-version: [16.15.1]
+ node-version: [18.15.0]
steps:
- uses: actions/checkout@v3
@@ -36,7 +36,7 @@ jobs:
strategy:
matrix:
- node-version: [16.15.1]
+ node-version: [18.15.0]
steps:
- uses: actions/checkout@v3
@@ -54,7 +54,7 @@ jobs:
strategy:
matrix:
- node-version: [16.15.1]
+ node-version: [18.15.0]
steps:
- uses: actions/checkout@v3
@@ -73,7 +73,7 @@ jobs:
strategy:
matrix:
- node-version: [16.15.1]
+ node-version: [18.15.0]
env:
REFERENCE: true
@@ -90,9 +90,10 @@ jobs:
- run: yarn build:ref
- run: yarn test:ref
- forge-lite:
- name: Run "Lite" Forge Tests (via_ir = false; fuzz_runs = 1000)
+ forge:
+ name: Run Forge Tests (via_ir = true; fuzz_runs = 5000)
runs-on: ubuntu-latest
+ timeout-minutes: 30
steps:
- uses: actions/checkout@v3
with:
@@ -106,15 +107,19 @@ jobs:
- name: Install forge dependencies
run: forge install
- - name: Precompile reference using 0.8.13 and via-ir=false
+ - name: Precompile reference using 0.8.24 and via-ir=false
run: FOUNDRY_PROFILE=reference forge build
+ - name: Precompile optimized using 0.8.24 and via-ir=true
+ run: FOUNDRY_PROFILE=optimized forge build
+
- name: Run tests
- run: FOUNDRY_PROFILE=lite forge test -vvv
+ run: FOUNDRY_PROFILE=test forge test -vvv
- forge:
- name: Run Forge Tests (via_ir = true; fuzz_runs = 5000)
+ forge-ref:
+ name: Run Forge Reference Tests (via_ir = false; fuzz_runs = 5000)
runs-on: ubuntu-latest
+ timeout-minutes: 30
steps:
- uses: actions/checkout@v3
with:
@@ -128,15 +133,15 @@ jobs:
- name: Install forge dependencies
run: forge install
- - name: Precompile reference using 0.8.13 and via-ir=false
+ - name: Precompile reference using 0.8.24 and via-ir=false
run: FOUNDRY_PROFILE=reference forge build
- - name: Precompile optimized using 0.8.17 and via-ir=true
+ - name: Precompile optimized using 0.8.24 and via-ir=true
run: FOUNDRY_PROFILE=optimized forge build
- - name: Run tests
- run: FOUNDRY_PROFILE=test forge test -vvv
-
+ - name: Run reference tests
+ run: FOUNDRY_PROFILE=reference MOAT_PROFILE=reference forge test -vvv
+
forge-offerers:
name: Run Contract Offerer Forge Tests (via_ir = false; fuzz_runs = 1000)
runs-on: ubuntu-latest
@@ -180,28 +185,29 @@ jobs:
files: ./lcov.info
flags: foundry
- coverage:
- name: Run Coverage Tests
- runs-on: ubuntu-latest
-
- strategy:
- matrix:
- node-version: [16.15.1]
-
- steps:
- - uses: actions/checkout@v3
- - name: Use Node.js
- uses: actions/setup-node@v3
- with:
- node-version: ${{ matrix.node-version }}
- cache: "yarn"
- - run: yarn install
- - run: yarn build
- - run: yarn coverage
- - uses: codecov/codecov-action@v3
- with:
- files: ./coverage/lcov.info
- flags: production
+# TODO: work out how to run legacy coverage (also how to run against core)
+# coverage:
+# name: Run Coverage Tests
+# runs-on: ubuntu-latest
+#
+# strategy:
+# matrix:
+# node-version: [18.15.0]
+#
+# steps:
+# - uses: actions/checkout@v3
+# - name: Use Node.js
+# uses: actions/setup-node@v3
+# with:
+# node-version: ${{ matrix.node-version }}
+# cache: "yarn"
+# - run: yarn install
+# - run: yarn build
+# - run: yarn coverage
+# - uses: codecov/codecov-action@v3
+# with:
+# files: ./coverage/lcov.info
+# flags: production
reference-coverage:
name: Run Reference Coverage Tests
@@ -209,7 +215,7 @@ jobs:
strategy:
matrix:
- node-version: [16.15.1]
+ node-version: [18.15.0]
env:
REFERENCE: true
@@ -228,4 +234,4 @@ jobs:
- uses: codecov/codecov-action@v3
with:
files: ./coverage/lcov.info
- flags: reference
+ flags: reference
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
index b0ba74548..022c48821 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -21,3 +21,12 @@
[submodule "lib/ds-test"]
path = lib/ds-test
url = https://github.com/dapphub/ds-test
+[submodule "lib/seaport-types"]
+ path = lib/seaport-types
+ url = https://github.com/projectopensea/seaport-types
+[submodule "lib/seaport-core"]
+ path = lib/seaport-core
+ url = https://github.com/projectopensea/seaport-core
+[submodule "lib/seaport-sol"]
+ path = lib/seaport-sol
+ url = https://github.com/projectopensea/seaport-sol
diff --git a/.prettierignore b/.prettierignore
index 47a16e0d9..04c0abc60 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -6,10 +6,15 @@ gasReporterOutput.json
typechain-types/
-lib/ds-test
-lib/forge-std
-lib/murky
-lib/openzeppelin-contracts
-lib/solmate
+lib/ds-test/
+lib/murky/
+lib/seaport-core/
+lib/seaport-types/
+lib/solarray/
+lib/forge-std/
+lib/openzeppelin-contracts/
+lib/seaport-sol/
+lib/solady/
+lib/solmate/
docs/OrderValidator.md
\ No newline at end of file
diff --git a/README.md b/README.md
index 68f4fe71c..50633b875 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ Seaport is a marketplace protocol for safely and efficiently buying and selling
Seaport is a marketplace protocol for safely and efficiently buying and selling NFTs. Each listing 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").
-See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts/interfaces/SeaportInterface.sol), and the full [interface documentation](https://docs.opensea.io/v2.0/reference/seaport-overview) for more information on Seaport.
+See the [documentation](docs/SeaportDocumentation.md), the [interface](https://github.com/ProjectOpenSea/seaport-types/blob/main/src/interfaces/ConsiderationInterface.sol), and the full [interface documentation](https://docs.opensea.io/v2.0/reference/seaport-overview) for more information on Seaport.
## Deployments
@@ -68,6 +68,14 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
ConduitController |
0x00000000F9490004C11Cef243f5400493c00Ad63 |
+
+SeaportValidator |
+0x00e5F120f500006757E984F1DED400fc00370000 |
+
+
+SeaportNavigator |
+0x0000f00000627D293Ab4Dfb40082001724dB006F |
+
> Note: Seaport 1.2 and Seaport 1.3 both contain known limitations; proceed with caution if interacting with them, particularly when utilizing restricted or contract orders.
@@ -81,8 +89,9 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
Seaport 1.4 |
Seaport 1.1 |
ConduitController |
+SeaportValidator |
+SeaportNavigator |
-
Ethereum |
[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://etherscan.io/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
@@ -99,22 +108,13 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://etherscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
- |
-Goerli |
-
-[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://goerli.etherscan.io/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
-
|
-[0x00000000000001ad428e4906aE43D8F9852d0dD6](https://goerli.etherscan.io/address/0x00000000000001ad428e4906aE43D8F9852d0dD6#code)
+[0x00e5F120f500006757E984F1DED400fc00370000](https://etherscan.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
|
-[0x00000000006c3852cbEf3e08E8dF289169EdE581](https://goerli.etherscan.io/address/0x00000000006c3852cbEf3e08E8dF289169EdE581#code)
-
- |
-
-[0x00000000F9490004C11Cef243f5400493c00Ad63](https://goerli.etherscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://etherscan.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
|
Sepolia |
@@ -133,6 +133,14 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://sepolia.etherscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://sepolia.etherscan.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://sepolia.etherscan.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Polygon |
@@ -150,6 +158,14 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://polygonscan.com/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://polygonscan.com/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://polygonscan.com/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Mumbai |
@@ -167,6 +183,14 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://mumbai.polygonscan.com/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://mumbai.polygonscan.com/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://mumbai.polygonscan.com/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Optimism |
@@ -184,22 +208,38 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://optimistic.etherscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://optimistic.etherscan.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://optimistic.etherscan.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
-Optimistic Goerli |
+ |
Optimism Sepolia |
+
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://sepolia-optimism.etherscan.io/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
-[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://goerli-optimism.etherscan.io/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
+ |
+
+Not deployed
+
+ |
+
+Not deployed
|
-[0x00000000000001ad428e4906aE43D8F9852d0dD6](https://goerli-optimism.etherscan.io/address/0x00000000000001ad428e4906aE43D8F9852d0dD6#code)
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://sepolia-optimism.etherscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
|
-[0x00000000006c3852cbEf3e08E8dF289169EdE581](https://goerli-optimism.etherscan.io/address/0x00000000006c3852cbEf3e08E8dF289169EdE581#code)
+[0x00e5F120f500006757E984F1DED400fc00370000](https://sepolia-optimism.etherscan.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
|
-[0x00000000F9490004C11Cef243f5400493c00Ad63](https://goerli-optimism.etherscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://sepolia-optimism.etherscan.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
|
Arbitrum |
@@ -218,22 +258,38 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://arbiscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://arbiscan.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://arbiscan.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
-Arbitrum Goerli |
+ |
Arbitrum Sepolia |
-[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://goerli.arbiscan.io/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://sepolia.arbiscan.io/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
|
-[0x00000000000001ad428e4906aE43D8F9852d0dD6](https://goerli.arbiscan.io/address/0x00000000000001ad428e4906aE43D8F9852d0dD6#code)
+Not deployed
|
-[0x00000000006c3852cbEf3e08E8dF289169EdE581](https://goerli.arbiscan.io/address/0x00000000006c3852cbEf3e08E8dF289169EdE581#code)
+Not deployed
|
-[0x00000000F9490004C11Cef243f5400493c00Ad63](https://goerli.arbiscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://sepolia.arbiscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://sepolia.arbiscan.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://sepolia.arbiscan.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
|
Arbitrum Nova |
@@ -252,6 +308,64 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://nova.arbiscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://nova.arbiscan.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://nova.arbiscan.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
+ |
+Base |
+
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://basescan.org/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://basescan.org/address/0x00000000f9490004c11cef243f5400493c00ad63)
+
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://basescan.org/address/0x00e5f120f500006757e984f1ded400fc00370000)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://basescan.org/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
+ |
+Base Sepolia |
+
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://sepolia.basescan.org/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://sepolia.basescan.org/address/0x00000000f9490004c11cef243f5400493c00ad63)
+
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://sepolia.basescan.org/address/0x00e5f120f500006757e984f1ded400fc00370000)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://sepolia.basescan.org/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Avalanche C-Chain |
@@ -269,6 +383,14 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://snowtrace.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://snowtrace.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://snowtrace.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Avalanche Fuji |
@@ -286,6 +408,14 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://testnet.snowtrace.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://testnet.snowtrace.io/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://testnet.snowtrace.io/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Gnosis Chain |
@@ -301,7 +431,15 @@ See the [documentation](docs/SeaportDocumentation.md), the [interface](contracts
|
-[0x00000000F9490004C11Cef243f5400493c00Ad63](https://gnossiscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://gnosisscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
|
Chiado |
@@ -320,6 +458,14 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://blockscout.com/gnosis/chiado/address/0x00000000F9490004C11Cef243f5400493c00Ad63/contracts#address-tabs)
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
|
BSC |
@@ -337,6 +483,14 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://bscscan.com/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://bscscan.com/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://bscscan.com/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
BSC Testnet |
@@ -354,6 +508,14 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://testnet.bscscan.com/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://testnet.bscscan.com/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://testnet.bscscan.com/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Klaytn |
@@ -371,6 +533,14 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://scope.klaytn.com/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://scope.klaytn.com/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://scope.klaytn.com/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Baobab |
@@ -388,6 +558,14 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://baobab.scope.klaytn.com/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://baobab.scope.klaytn.com/address/0x00e5F120f500006757E984F1DED400fc00370000#code)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://baobab.scope.klaytn.com/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
Moonbeam |
@@ -405,6 +583,14 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://moonscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
|
Moonriver |
@@ -422,6 +608,14 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://moonriver.moonscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
|
Canto |
@@ -440,15 +634,125 @@ Not deployed
[0x00000000F9490004C11Cef243f5400493c00Ad63](https://evm.explorer.canto.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+Fantom |
+
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://ftmscan.com/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://ftmscan.com/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+Celo |
+
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://celoscan.io/address/0x00000000000000adc04c56bf30ac9d3c0aaf14dc#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://celoscan.io/address/0x00000000F9490004C11Cef243f5400493c00Ad63#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+Zora |
+
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://explorer.zora.energy/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://explorer.zora.energy/address/0x00000000f9490004c11cef243f5400493c00ad63)
+
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://explorer.zora.energy/address/0x00e5f120f500006757e984f1ded400fc00370000)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://explorer.zora.energy/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
+ |
+Zora Sepolia |
+
+[0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC](https://sepolia.explorer.zora.energy/address/0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC#code)
+
+ |
+
+Not deployed
+
+ |
+
+Not deployed
+
+ |
+
+[0x00000000F9490004C11Cef243f5400493c00Ad63](https://sepolia.explorer.zora.energy/address/0x00000000f9490004c11cef243f5400493c00ad63)
+
+ |
+
+[0x00e5F120f500006757E984F1DED400fc00370000](https://sepolia.explorer.zora.energy/address/0x00e5f120f500006757e984f1ded400fc00370000)
+
+ |
+
+[0x0000f00000627D293Ab4Dfb40082001724dB006F](https://sepolia.explorer.zora.energy/address/0x0000f00000627D293Ab4Dfb40082001724dB006F#code)
+
|
To be deployed on other EVM chains, such as:
-- Skale
-- Celo
-- Fantom
- RSK
+- Boba
+- Aurora
To deploy to a new EVM chain, follow the [steps outlined here](docs/Deployment.md).
diff --git a/config/.solhintignore b/config/.solhintignore
index 8d4fb4245..b4ac21a5c 100644
--- a/config/.solhintignore
+++ b/config/.solhintignore
@@ -1,6 +1,7 @@
node_modules/
contracts/test/
+contracts/zones/PausableZone.sol
test/
lib/
\ No newline at end of file
diff --git a/contracts/Seaport.sol b/contracts/Seaport.sol
index 634dd1d36..043a473b3 100644
--- a/contracts/Seaport.sol
+++ b/contracts/Seaport.sol
@@ -1,22 +1,22 @@
// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
+pragma solidity 0.8.24;
-import { Consideration } from "./lib/Consideration.sol";
+import { Consideration } from "seaport-core/src/lib/Consideration.sol";
/**
* @title Seaport
- * @custom:version 1.5
+ * @custom:version 1.6
* @author 0age (0age.eth)
* @custom:coauthor d1ll0n (d1ll0n.eth)
* @custom:coauthor transmissions11 (t11s.eth)
* @custom:coauthor James Wenzel (emo.eth)
+ * @custom:coauthor Daniel Viau (snotrocket.eth)
* @custom:contributor Kartik (slokh.eth)
* @custom:contributor LeFevre (lefevre.eth)
* @custom:contributor Joseph Schiarizzi (CupOJoseph.eth)
* @custom:contributor Aspyn Palatnick (stuckinaboot.eth)
* @custom:contributor Stephan Min (stephanm.eth)
* @custom:contributor Ryan Ghods (ralxz.eth)
- * @custom:contributor Daniel Viau (snotrocket.eth)
* @custom:contributor hack3r-0m (hack3r-0m.eth)
* @custom:contributor Diego Estevez (antidiego.eth)
* @custom:contributor Chomtana (chomtana.eth)
diff --git a/contracts/conduit/Conduit.sol b/contracts/conduit/Conduit.sol
index aa2ecae99..4eb6490cf 100644
--- a/contracts/conduit/Conduit.sol
+++ b/contracts/conduit/Conduit.sol
@@ -1,26 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
-
-import { ConduitItemType } from "./lib/ConduitEnums.sol";
-
-import { TokenTransferrer } from "../lib/TokenTransferrer.sol";
-
-import {
- ConduitBatch1155Transfer,
- ConduitTransfer
-} from "./lib/ConduitStructs.sol";
-
-import {
- ChannelClosed_channel_ptr,
- ChannelClosed_error_length,
- ChannelClosed_error_ptr,
- ChannelClosed_error_signature,
- ChannelKey_channel_ptr,
- ChannelKey_length,
- ChannelKey_slot_ptr
-} from "./lib/ConduitConstants.sol";
+import { Conduit as CoreConduit } from "seaport-core/src/conduit/Conduit.sol";
/**
* @title Conduit
@@ -34,226 +15,6 @@ import {
* approved ERC20/721/1155 tokens to be taken immediately — be extremely
* cautious with what conduits you give token approvals to!*
*/
-contract Conduit is ConduitInterface, TokenTransferrer {
- // Set deployer as an immutable controller that can update channel statuses.
- address private immutable _controller;
-
- // Track the status of each channel.
- mapping(address => bool) private _channels;
-
- /**
- * @notice Ensure that the caller is currently registered as an open channel
- * on the conduit.
- */
- modifier onlyOpenChannel() {
- // Utilize assembly to access channel storage mapping directly.
- assembly {
- // Write the caller to scratch space.
- mstore(ChannelKey_channel_ptr, caller())
-
- // Write the storage slot for _channels to scratch space.
- mstore(ChannelKey_slot_ptr, _channels.slot)
-
- // Derive the position in storage of _channels[msg.sender]
- // and check if the stored value is zero.
- if iszero(
- sload(keccak256(ChannelKey_channel_ptr, ChannelKey_length))
- ) {
- // The caller is not an open channel; revert with
- // ChannelClosed(caller). First, set error signature in memory.
- mstore(ChannelClosed_error_ptr, ChannelClosed_error_signature)
-
- // Next, set the caller as the argument.
- mstore(ChannelClosed_channel_ptr, caller())
-
- // Finally, revert, returning full custom error with argument
- // data in memory.
- // revert(abi.encodeWithSignature(
- // "ChannelClosed(address)", caller()
- // ))
- revert(ChannelClosed_error_ptr, ChannelClosed_error_length)
- }
- }
-
- // Continue with function execution.
- _;
- }
-
- /**
- * @notice In the constructor, set the deployer as the controller.
- */
- constructor() {
- // Set the deployer as the controller.
- _controller = msg.sender;
- }
-
- /**
- * @notice Execute a sequence of ERC20/721/1155 transfers. Only a caller
- * with an open channel can call this function. Note that channels
- * are expected to implement reentrancy protection if desired, and
- * that cross-channel reentrancy may be possible if the conduit has
- * multiple open channels at once. Also note that channels are
- * expected to implement checks against transferring any zero-amount
- * items if that constraint is desired.
- *
- * @param transfers The ERC20/721/1155 transfers to perform.
- *
- * @return magicValue A magic value indicating that the transfers were
- * performed successfully.
- */
- function execute(
- ConduitTransfer[] calldata transfers
- ) external override onlyOpenChannel returns (bytes4 magicValue) {
- // Retrieve the total number of transfers and place on the stack.
- uint256 totalStandardTransfers = transfers.length;
-
- // Iterate over each transfer.
- for (uint256 i = 0; i < totalStandardTransfers; ) {
- // Retrieve the transfer in question and perform the transfer.
- _transfer(transfers[i]);
-
- // Skip overflow check as for loop is indexed starting at zero.
- unchecked {
- ++i;
- }
- }
-
- // Return a magic value indicating that the transfers were performed.
- magicValue = this.execute.selector;
- }
-
- /**
- * @notice Execute a sequence of batch 1155 item transfers. Only a caller
- * with an open channel can call this function. Note that channels
- * are expected to implement reentrancy protection if desired, and
- * that cross-channel reentrancy may be possible if the conduit has
- * multiple open channels at once. Also note that channels are
- * expected to implement checks against transferring any zero-amount
- * items if that constraint is desired.
- *
- * @param batchTransfers The 1155 batch item transfers to perform.
- *
- * @return magicValue A magic value indicating that the item transfers were
- * performed successfully.
- */
- function executeBatch1155(
- ConduitBatch1155Transfer[] calldata batchTransfers
- ) external override onlyOpenChannel returns (bytes4 magicValue) {
- // Perform 1155 batch transfers. Note that memory should be considered
- // entirely corrupted from this point forward.
- _performERC1155BatchTransfers(batchTransfers);
-
- // Return a magic value indicating that the transfers were performed.
- magicValue = this.executeBatch1155.selector;
- }
-
- /**
- * @notice Execute a sequence of transfers, both single ERC20/721/1155 item
- * transfers as well as batch 1155 item transfers. Only a caller
- * with an open channel can call this function. Note that channels
- * are expected to implement reentrancy protection if desired, and
- * that cross-channel reentrancy may be possible if the conduit has
- * multiple open channels at once. Also note that channels are
- * expected to implement checks against transferring any zero-amount
- * items if that constraint is desired.
- *
- * @param standardTransfers The ERC20/721/1155 item transfers to perform.
- * @param batchTransfers The 1155 batch item transfers to perform.
- *
- * @return magicValue A magic value indicating that the item transfers were
- * performed successfully.
- */
- function executeWithBatch1155(
- ConduitTransfer[] calldata standardTransfers,
- ConduitBatch1155Transfer[] calldata batchTransfers
- ) external override onlyOpenChannel returns (bytes4 magicValue) {
- // Retrieve the total number of transfers and place on the stack.
- uint256 totalStandardTransfers = standardTransfers.length;
-
- // Iterate over each standard transfer.
- for (uint256 i = 0; i < totalStandardTransfers; ) {
- // Retrieve the transfer in question and perform the transfer.
- _transfer(standardTransfers[i]);
-
- // Skip overflow check as for loop is indexed starting at zero.
- unchecked {
- ++i;
- }
- }
-
- // Perform 1155 batch transfers. Note that memory should be considered
- // entirely corrupted from this point forward aside from the free memory
- // pointer having the default value.
- _performERC1155BatchTransfers(batchTransfers);
-
- // Return a magic value indicating that the transfers were performed.
- magicValue = this.executeWithBatch1155.selector;
- }
-
- /**
- * @notice Open or close a given channel. Only callable by the controller.
- *
- * @param channel The channel to open or close.
- * @param isOpen The status of the channel (either open or closed).
- */
- function updateChannel(address channel, bool isOpen) external override {
- // Ensure that the caller is the controller of this contract.
- if (msg.sender != _controller) {
- revert InvalidController();
- }
-
- // Ensure that the channel does not already have the indicated status.
- if (_channels[channel] == isOpen) {
- revert ChannelStatusAlreadySet(channel, isOpen);
- }
-
- // Update the status of the channel.
- _channels[channel] = isOpen;
-
- // Emit a corresponding event.
- emit ChannelUpdated(channel, isOpen);
- }
-
- /**
- * @dev Internal function to transfer a given ERC20/721/1155 item. Note that
- * channels are expected to implement checks against transferring any
- * zero-amount items if that constraint is desired.
- *
- * @param item The ERC20/721/1155 item to transfer.
- */
- function _transfer(ConduitTransfer calldata item) internal {
- // Determine the transfer method based on the respective item type.
- if (item.itemType == ConduitItemType.ERC20) {
- // Transfer ERC20 token. Note that item.identifier is ignored and
- // therefore ERC20 transfer items are potentially malleable — this
- // check should be performed by the calling channel if a constraint
- // on item malleability is desired.
- _performERC20Transfer(item.token, item.from, item.to, item.amount);
- } else if (item.itemType == ConduitItemType.ERC721) {
- // Ensure that exactly one 721 item is being transferred.
- if (item.amount != 1) {
- revert InvalidERC721TransferAmount(item.amount);
- }
+contract LocalConduit is CoreConduit {
- // Transfer ERC721 token.
- _performERC721Transfer(
- item.token,
- item.from,
- item.to,
- item.identifier
- );
- } else if (item.itemType == ConduitItemType.ERC1155) {
- // Transfer ERC1155 token.
- _performERC1155Transfer(
- item.token,
- item.from,
- item.to,
- item.identifier,
- item.amount
- );
- } else {
- // Throw with an error.
- revert InvalidItemType();
- }
- }
}
diff --git a/contracts/conduit/ConduitController.sol b/contracts/conduit/ConduitController.sol
index 1b15fe5c0..ad654f87e 100644
--- a/contracts/conduit/ConduitController.sol
+++ b/contracts/conduit/ConduitController.sol
@@ -2,12 +2,8 @@
pragma solidity ^0.8.13;
import {
- ConduitControllerInterface
-} from "../interfaces/ConduitControllerInterface.sol";
-
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
-
-import { Conduit } from "./Conduit.sol";
+ ConduitController as CoreConduitController
+} from "seaport-core/src/conduit/ConduitController.sol";
/**
* @title ConduitController
@@ -16,489 +12,6 @@ import { Conduit } from "./Conduit.sol";
* contracts that allow registered callers (or open "channels") to
* transfer approved ERC20/721/1155 tokens on their behalf.
*/
-contract ConduitController is ConduitControllerInterface {
- // Register keys, owners, new potential owners, and channels by conduit.
- mapping(address => ConduitProperties) internal _conduits;
-
- // Set conduit creation code and runtime code hashes as immutable arguments.
- bytes32 internal immutable _CONDUIT_CREATION_CODE_HASH;
- bytes32 internal immutable _CONDUIT_RUNTIME_CODE_HASH;
-
- /**
- * @dev Initialize contract by deploying a conduit and setting the creation
- * code and runtime code hashes as immutable arguments.
- */
- constructor() {
- // Derive the conduit creation code hash and set it as an immutable.
- _CONDUIT_CREATION_CODE_HASH = keccak256(type(Conduit).creationCode);
-
- // Deploy a conduit with the zero hash as the salt.
- Conduit zeroConduit = new Conduit{ salt: bytes32(0) }();
-
- // Retrieve the conduit runtime code hash and set it as an immutable.
- _CONDUIT_RUNTIME_CODE_HASH = address(zeroConduit).codehash;
- }
-
- /**
- * @notice Deploy a new conduit using a supplied conduit key and assigning
- * an initial owner for the deployed conduit. Note that the first
- * twenty bytes of the supplied conduit key must match the caller
- * and that a new conduit cannot be created if one has already been
- * deployed using the same conduit key.
- *
- * @param conduitKey The conduit key used to deploy the conduit. Note that
- * the first twenty bytes of the conduit key must match
- * the caller of this contract.
- * @param initialOwner The initial owner to set for the new conduit.
- *
- * @return conduit The address of the newly deployed conduit.
- */
- function createConduit(
- bytes32 conduitKey,
- address initialOwner
- ) external override returns (address conduit) {
- // Ensure that an initial owner has been supplied.
- if (initialOwner == address(0)) {
- revert InvalidInitialOwner();
- }
-
- // If the first 20 bytes of the conduit key do not match the caller...
- if (address(uint160(bytes20(conduitKey))) != msg.sender) {
- // Revert with an error indicating that the creator is invalid.
- revert InvalidCreator();
- }
-
- // Derive address from deployer, conduit key and creation code hash.
- conduit = address(
- uint160(
- uint256(
- keccak256(
- abi.encodePacked(
- bytes1(0xff),
- address(this),
- conduitKey,
- _CONDUIT_CREATION_CODE_HASH
- )
- )
- )
- )
- );
-
- // If derived conduit exists, as evidenced by comparing runtime code...
- if (conduit.codehash == _CONDUIT_RUNTIME_CODE_HASH) {
- // Revert with an error indicating that the conduit already exists.
- revert ConduitAlreadyExists(conduit);
- }
-
- // Deploy the conduit via CREATE2 using the conduit key as the salt.
- new Conduit{ salt: conduitKey }();
-
- // Initialize storage variable referencing conduit properties.
- ConduitProperties storage conduitProperties = _conduits[conduit];
-
- // Set the supplied initial owner as the owner of the conduit.
- conduitProperties.owner = initialOwner;
-
- // Set conduit key used to deploy the conduit to enable reverse lookup.
- conduitProperties.key = conduitKey;
-
- // Emit an event indicating that the conduit has been deployed.
- emit NewConduit(conduit, conduitKey);
-
- // Emit an event indicating that conduit ownership has been assigned.
- emit OwnershipTransferred(conduit, address(0), initialOwner);
- }
-
- /**
- * @notice Open or close a channel on a given conduit, thereby allowing the
- * specified account to execute transfers against that conduit.
- * Extreme care must be taken when updating channels, as malicious
- * or vulnerable channels can transfer any ERC20, ERC721 and ERC1155
- * tokens where the token holder has granted the conduit approval.
- * Only the owner of the conduit in question may call this function.
- *
- * @param conduit The conduit for which to open or close the channel.
- * @param channel The channel to open or close on the conduit.
- * @param isOpen A boolean indicating whether to open or close the channel.
- */
- function updateChannel(
- address conduit,
- address channel,
- bool isOpen
- ) external override {
- // Ensure the caller is the current owner of the conduit in question.
- _assertCallerIsConduitOwner(conduit);
-
- // Call the conduit, updating the channel.
- ConduitInterface(conduit).updateChannel(channel, isOpen);
-
- // Retrieve storage region where channels for the conduit are tracked.
- ConduitProperties storage conduitProperties = _conduits[conduit];
-
- // Retrieve the index, if one currently exists, for the updated channel.
- uint256 channelIndexPlusOne = (
- conduitProperties.channelIndexesPlusOne[channel]
- );
-
- // Determine whether the updated channel is already tracked as open.
- bool channelPreviouslyOpen = channelIndexPlusOne != 0;
-
- // If the channel has been set to open and was previously closed...
- if (isOpen && !channelPreviouslyOpen) {
- // Add the channel to the channels array for the conduit.
- conduitProperties.channels.push(channel);
-
- // Add new open channel length to associated mapping as index + 1.
- conduitProperties.channelIndexesPlusOne[channel] = (
- conduitProperties.channels.length
- );
- } else if (!isOpen && channelPreviouslyOpen) {
- // Set a previously open channel as closed via "swap & pop" method.
- // Decrement located index to get the index of the closed channel.
- uint256 removedChannelIndex;
-
- // Skip underflow check as channelPreviouslyOpen being true ensures
- // that channelIndexPlusOne is nonzero.
- unchecked {
- removedChannelIndex = channelIndexPlusOne - 1;
- }
-
- // Use length of channels array to determine index of last channel.
- uint256 finalChannelIndex = conduitProperties.channels.length - 1;
-
- // If closed channel is not last channel in the channels array...
- if (finalChannelIndex != removedChannelIndex) {
- // Retrieve the final channel and place the value on the stack.
- address finalChannel = (
- conduitProperties.channels[finalChannelIndex]
- );
-
- // Overwrite the removed channel using the final channel value.
- conduitProperties.channels[removedChannelIndex] = finalChannel;
-
- // Update final index in associated mapping to removed index.
- conduitProperties.channelIndexesPlusOne[finalChannel] = (
- channelIndexPlusOne
- );
- }
-
- // Remove the last channel from the channels array for the conduit.
- conduitProperties.channels.pop();
-
- // Remove the closed channel from associated mapping of indexes.
- delete conduitProperties.channelIndexesPlusOne[channel];
- }
- }
-
- /**
- * @notice Initiate conduit ownership transfer by assigning a new potential
- * owner for the given conduit. Once set, the new potential owner
- * may call `acceptOwnership` to claim ownership of the conduit.
- * Only the owner of the conduit in question may call this function.
- *
- * @param conduit The conduit for which to initiate ownership transfer.
- * @param newPotentialOwner The new potential owner of the conduit.
- */
- function transferOwnership(
- address conduit,
- address newPotentialOwner
- ) external override {
- // Ensure the caller is the current owner of the conduit in question.
- _assertCallerIsConduitOwner(conduit);
-
- // Ensure the new potential owner is not an invalid address.
- if (newPotentialOwner == address(0)) {
- revert NewPotentialOwnerIsZeroAddress(conduit);
- }
-
- // Ensure the new potential owner is not already set.
- if (newPotentialOwner == _conduits[conduit].potentialOwner) {
- revert NewPotentialOwnerAlreadySet(conduit, newPotentialOwner);
- }
-
- // Emit an event indicating that the potential owner has been updated.
- emit PotentialOwnerUpdated(newPotentialOwner);
-
- // Set the new potential owner as the potential owner of the conduit.
- _conduits[conduit].potentialOwner = newPotentialOwner;
- }
-
- /**
- * @notice Clear the currently set potential owner, if any, from a conduit.
- * Only the owner of the conduit in question may call this function.
- *
- * @param conduit The conduit for which to cancel ownership transfer.
- */
- function cancelOwnershipTransfer(address conduit) external override {
- // Ensure the caller is the current owner of the conduit in question.
- _assertCallerIsConduitOwner(conduit);
-
- // Ensure that ownership transfer is currently possible.
- if (_conduits[conduit].potentialOwner == address(0)) {
- revert NoPotentialOwnerCurrentlySet(conduit);
- }
-
- // Emit an event indicating that the potential owner has been cleared.
- emit PotentialOwnerUpdated(address(0));
-
- // Clear the current new potential owner from the conduit.
- _conduits[conduit].potentialOwner = address(0);
- }
-
- /**
- * @notice Accept ownership of a supplied conduit. Only accounts that the
- * current owner has set as the new potential owner may call this
- * function.
- *
- * @param conduit The conduit for which to accept ownership.
- */
- function acceptOwnership(address conduit) external override {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // If caller does not match current potential owner of the conduit...
- if (msg.sender != _conduits[conduit].potentialOwner) {
- // Revert, indicating that caller is not current potential owner.
- revert CallerIsNotNewPotentialOwner(conduit);
- }
-
- // Emit an event indicating that the potential owner has been cleared.
- emit PotentialOwnerUpdated(address(0));
-
- // Clear the current new potential owner from the conduit.
- _conduits[conduit].potentialOwner = address(0);
-
- // Emit an event indicating conduit ownership has been transferred.
- emit OwnershipTransferred(
- conduit,
- _conduits[conduit].owner,
- msg.sender
- );
-
- // Set the caller as the owner of the conduit.
- _conduits[conduit].owner = msg.sender;
- }
-
- /**
- * @notice Retrieve the current owner of a deployed conduit.
- *
- * @param conduit The conduit for which to retrieve the associated owner.
- *
- * @return owner The owner of the supplied conduit.
- */
- function ownerOf(
- address conduit
- ) external view override returns (address owner) {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // Retrieve the current owner of the conduit in question.
- owner = _conduits[conduit].owner;
- }
-
- /**
- * @notice Retrieve the conduit key for a deployed conduit via reverse
- * lookup.
- *
- * @param conduit The conduit for which to retrieve the associated conduit
- * key.
- *
- * @return conduitKey The conduit key used to deploy the supplied conduit.
- */
- function getKey(
- address conduit
- ) external view override returns (bytes32 conduitKey) {
- // Attempt to retrieve a conduit key for the conduit in question.
- conduitKey = _conduits[conduit].key;
-
- // Revert if no conduit key was located.
- if (conduitKey == bytes32(0)) {
- revert NoConduit();
- }
- }
-
- /**
- * @notice Derive the conduit associated with a given conduit key and
- * determine whether that conduit exists (i.e. whether it has been
- * deployed).
- *
- * @param conduitKey The conduit key used to derive the conduit.
- *
- * @return conduit The derived address of the conduit.
- * @return exists A boolean indicating whether the derived conduit has been
- * deployed or not.
- */
- function getConduit(
- bytes32 conduitKey
- ) external view override returns (address conduit, bool exists) {
- // Derive address from deployer, conduit key and creation code hash.
- conduit = address(
- uint160(
- uint256(
- keccak256(
- abi.encodePacked(
- bytes1(0xff),
- address(this),
- conduitKey,
- _CONDUIT_CREATION_CODE_HASH
- )
- )
- )
- )
- );
-
- // Determine whether conduit exists by retrieving its runtime code.
- exists = (conduit.codehash == _CONDUIT_RUNTIME_CODE_HASH);
- }
-
- /**
- * @notice Retrieve the potential owner, if any, for a given conduit. The
- * current owner may set a new potential owner via
- * `transferOwnership` and that owner may then accept ownership of
- * the conduit in question via `acceptOwnership`.
- *
- * @param conduit The conduit for which to retrieve the potential owner.
- *
- * @return potentialOwner The potential owner, if any, for the conduit.
- */
- function getPotentialOwner(
- address conduit
- ) external view override returns (address potentialOwner) {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // Retrieve the current potential owner of the conduit in question.
- potentialOwner = _conduits[conduit].potentialOwner;
- }
-
- /**
- * @notice Retrieve the status (either open or closed) of a given channel on
- * a conduit.
- *
- * @param conduit The conduit for which to retrieve the channel status.
- * @param channel The channel for which to retrieve the status.
- *
- * @return isOpen The status of the channel on the given conduit.
- */
- function getChannelStatus(
- address conduit,
- address channel
- ) external view override returns (bool isOpen) {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // Retrieve the current channel status for the conduit in question.
- isOpen = _conduits[conduit].channelIndexesPlusOne[channel] != 0;
- }
-
- /**
- * @notice Retrieve the total number of open channels for a given conduit.
- *
- * @param conduit The conduit for which to retrieve the total channel count.
- *
- * @return totalChannels The total number of open channels for the conduit.
- */
- function getTotalChannels(
- address conduit
- ) external view override returns (uint256 totalChannels) {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // Retrieve the total open channel count for the conduit in question.
- totalChannels = _conduits[conduit].channels.length;
- }
-
- /**
- * @notice Retrieve an open channel at a specific index for a given conduit.
- * Note that the index of a channel can change as a result of other
- * channels being closed on the conduit.
- *
- * @param conduit The conduit for which to retrieve the open channel.
- * @param channelIndex The index of the channel in question.
- *
- * @return channel The open channel, if any, at the specified channel index.
- */
- function getChannel(
- address conduit,
- uint256 channelIndex
- ) external view override returns (address channel) {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // Retrieve the total open channel count for the conduit in question.
- uint256 totalChannels = _conduits[conduit].channels.length;
-
- // Ensure that the supplied index is within range.
- if (channelIndex >= totalChannels) {
- revert ChannelOutOfRange(conduit);
- }
-
- // Retrieve the channel at the given index.
- channel = _conduits[conduit].channels[channelIndex];
- }
-
- /**
- * @notice Retrieve all open channels for a given conduit. Note that calling
- * this function for a conduit with many channels will revert with
- * an out-of-gas error.
- *
- * @param conduit The conduit for which to retrieve open channels.
- *
- * @return channels An array of open channels on the given conduit.
- */
- function getChannels(
- address conduit
- ) external view override returns (address[] memory channels) {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // Retrieve all of the open channels on the conduit in question.
- channels = _conduits[conduit].channels;
- }
-
- /**
- * @dev Retrieve the conduit creation code and runtime code hashes.
- */
- function getConduitCodeHashes()
- external
- view
- override
- returns (bytes32 creationCodeHash, bytes32 runtimeCodeHash)
- {
- // Retrieve the conduit creation code hash from runtime.
- creationCodeHash = _CONDUIT_CREATION_CODE_HASH;
-
- // Retrieve the conduit runtime code hash from runtime.
- runtimeCodeHash = _CONDUIT_RUNTIME_CODE_HASH;
- }
-
- /**
- * @dev Private view function to revert if the caller is not the owner of a
- * given conduit.
- *
- * @param conduit The conduit for which to assert ownership.
- */
- function _assertCallerIsConduitOwner(address conduit) private view {
- // Ensure that the conduit in question exists.
- _assertConduitExists(conduit);
-
- // If the caller does not match the current owner of the conduit...
- if (msg.sender != _conduits[conduit].owner) {
- // Revert, indicating that the caller is not the owner.
- revert CallerIsNotOwner(conduit);
- }
- }
+contract LocalConduitController is CoreConduitController {
- /**
- * @dev Private view function to revert if a given conduit does not exist.
- *
- * @param conduit The conduit for which to assert existence.
- */
- function _assertConduitExists(address conduit) private view {
- // Attempt to retrieve a conduit key for the conduit in question.
- if (_conduits[conduit].key == bytes32(0)) {
- // Revert if no conduit key was located.
- revert NoConduit();
- }
- }
}
diff --git a/contracts/conduit/lib/ConduitConstants.sol b/contracts/conduit/lib/ConduitConstants.sol
deleted file mode 100644
index 42197c8e2..000000000
--- a/contracts/conduit/lib/ConduitConstants.sol
+++ /dev/null
@@ -1,18 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-// error ChannelClosed(address channel)
-uint256 constant ChannelClosed_error_signature = (
- 0x93daadf200000000000000000000000000000000000000000000000000000000
-);
-uint256 constant ChannelClosed_error_ptr = 0x00;
-uint256 constant ChannelClosed_channel_ptr = 0x4;
-uint256 constant ChannelClosed_error_length = 0x24;
-
-// For the mapping:
-// mapping(address => bool) channels
-// The position in storage for a particular account is:
-// keccak256(abi.encode(account, channels.slot))
-uint256 constant ChannelKey_channel_ptr = 0x00;
-uint256 constant ChannelKey_slot_ptr = 0x20;
-uint256 constant ChannelKey_length = 0x40;
diff --git a/contracts/conduit/lib/ConduitEnums.sol b/contracts/conduit/lib/ConduitEnums.sol
deleted file mode 100644
index 05a6587f5..000000000
--- a/contracts/conduit/lib/ConduitEnums.sol
+++ /dev/null
@@ -1,9 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-enum ConduitItemType {
- NATIVE, // unused
- ERC20,
- ERC721,
- ERC1155
-}
diff --git a/contracts/conduit/lib/ConduitStructs.sol b/contracts/conduit/lib/ConduitStructs.sol
deleted file mode 100644
index b7fc8322d..000000000
--- a/contracts/conduit/lib/ConduitStructs.sol
+++ /dev/null
@@ -1,30 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import { ConduitItemType } from "./ConduitEnums.sol";
-
-/**
- * @dev A ConduitTransfer is a struct that contains the information needed for a
- * conduit to transfer an item from one address to another.
- */
-struct ConduitTransfer {
- ConduitItemType itemType;
- address token;
- address from;
- address to;
- uint256 identifier;
- uint256 amount;
-}
-
-/**
- * @dev A ConduitBatch1155Transfer is a struct that contains the information
- * needed for a conduit to transfer a batch of ERC-1155 tokens from one
- * address to another.
- */
-struct ConduitBatch1155Transfer {
- address token;
- address from;
- address to;
- uint256[] ids;
- uint256[] amounts;
-}
diff --git a/contracts/helpers/ArrayHelpers.sol b/contracts/helpers/ArrayHelpers.sol
index 008eeaa1c..99bb3bfa2 100644
--- a/contracts/helpers/ArrayHelpers.sol
+++ b/contracts/helpers/ArrayHelpers.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import "./PointerLibraries.sol";
+import "seaport-types/src/helpers/PointerLibraries.sol";
/**
* @author d1ll0n
diff --git a/contracts/helpers/PointerLibraries.sol b/contracts/helpers/PointerLibraries.sol
deleted file mode 100644
index 298d6c032..000000000
--- a/contracts/helpers/PointerLibraries.sol
+++ /dev/null
@@ -1,3122 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-type CalldataPointer is uint256;
-
-type ReturndataPointer is uint256;
-
-type MemoryPointer is uint256;
-
-using CalldataPointerLib for CalldataPointer global;
-using MemoryPointerLib for MemoryPointer global;
-using ReturndataPointerLib for ReturndataPointer global;
-
-using CalldataReaders for CalldataPointer global;
-using ReturndataReaders for ReturndataPointer global;
-using MemoryReaders for MemoryPointer global;
-using MemoryWriters for MemoryPointer global;
-
-CalldataPointer constant CalldataStart = CalldataPointer.wrap(0x04);
-MemoryPointer constant FreeMemoryPPtr = MemoryPointer.wrap(0x40);
-uint256 constant IdentityPrecompileAddress = 0x4;
-uint256 constant OffsetOrLengthMask = 0xffffffff;
-uint256 constant _OneWord = 0x20;
-uint256 constant _FreeMemoryPointerSlot = 0x40;
-
-/// @dev Allocates `size` bytes in memory by increasing the free memory pointer
-/// and returns the memory pointer to the first byte of the allocated region.
-// (Free functions cannot have visibility.)
-// solhint-disable-next-line func-visibility
-function malloc(uint256 size) pure returns (MemoryPointer mPtr) {
- assembly {
- mPtr := mload(_FreeMemoryPointerSlot)
- mstore(_FreeMemoryPointerSlot, add(mPtr, size))
- }
-}
-
-// (Free functions cannot have visibility.)
-// solhint-disable-next-line func-visibility
-function getFreeMemoryPointer() pure returns (MemoryPointer mPtr) {
- mPtr = FreeMemoryPPtr.readMemoryPointer();
-}
-
-// (Free functions cannot have visibility.)
-// solhint-disable-next-line func-visibility
-function setFreeMemoryPointer(MemoryPointer mPtr) pure {
- FreeMemoryPPtr.write(mPtr);
-}
-
-library CalldataPointerLib {
- function lt(
- CalldataPointer a,
- CalldataPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := lt(a, b)
- }
- }
-
- function gt(
- CalldataPointer a,
- CalldataPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := gt(a, b)
- }
- }
-
- function eq(
- CalldataPointer a,
- CalldataPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := eq(a, b)
- }
- }
-
- function isNull(CalldataPointer a) internal pure returns (bool b) {
- assembly {
- b := iszero(a)
- }
- }
-
- /// @dev Resolves an offset stored at `cdPtr + headOffset` to a calldata.
- /// pointer `cdPtr` must point to some parent object with a dynamic
- /// type's head stored at `cdPtr + headOffset`.
- function pptr(
- CalldataPointer cdPtr,
- uint256 headOffset
- ) internal pure returns (CalldataPointer cdPtrChild) {
- cdPtrChild = cdPtr.offset(
- cdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask
- );
- }
-
- /// @dev Resolves an offset stored at `cdPtr` to a calldata pointer.
- /// `cdPtr` must point to some parent object with a dynamic type as its
- /// first member, e.g. `struct { bytes data; }`
- function pptr(
- CalldataPointer cdPtr
- ) internal pure returns (CalldataPointer cdPtrChild) {
- cdPtrChild = cdPtr.offset(cdPtr.readUint256() & OffsetOrLengthMask);
- }
-
- /// @dev Returns the calldata pointer one word after `cdPtr`.
- function next(
- CalldataPointer cdPtr
- ) internal pure returns (CalldataPointer cdPtrNext) {
- assembly {
- cdPtrNext := add(cdPtr, _OneWord)
- }
- }
-
- /// @dev Returns the calldata pointer `_offset` bytes after `cdPtr`.
- function offset(
- CalldataPointer cdPtr,
- uint256 _offset
- ) internal pure returns (CalldataPointer cdPtrNext) {
- assembly {
- cdPtrNext := add(cdPtr, _offset)
- }
- }
-
- /// @dev Copies `size` bytes from calldata starting at `src` to memory at
- /// `dst`.
- function copy(
- CalldataPointer src,
- MemoryPointer dst,
- uint256 size
- ) internal pure {
- assembly {
- calldatacopy(dst, src, size)
- }
- }
-}
-
-library ReturndataPointerLib {
- function lt(
- ReturndataPointer a,
- ReturndataPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := lt(a, b)
- }
- }
-
- function gt(
- ReturndataPointer a,
- ReturndataPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := gt(a, b)
- }
- }
-
- function eq(
- ReturndataPointer a,
- ReturndataPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := eq(a, b)
- }
- }
-
- function isNull(ReturndataPointer a) internal pure returns (bool b) {
- assembly {
- b := iszero(a)
- }
- }
-
- /// @dev Resolves an offset stored at `rdPtr + headOffset` to a returndata
- /// pointer. `rdPtr` must point to some parent object with a dynamic
- /// type's head stored at `rdPtr + headOffset`.
- function pptr(
- ReturndataPointer rdPtr,
- uint256 headOffset
- ) internal pure returns (ReturndataPointer rdPtrChild) {
- rdPtrChild = rdPtr.offset(
- rdPtr.offset(headOffset).readUint256() & OffsetOrLengthMask
- );
- }
-
- /// @dev Resolves an offset stored at `rdPtr` to a returndata pointer.
- /// `rdPtr` must point to some parent object with a dynamic type as its
- /// first member, e.g. `struct { bytes data; }`
- function pptr(
- ReturndataPointer rdPtr
- ) internal pure returns (ReturndataPointer rdPtrChild) {
- rdPtrChild = rdPtr.offset(rdPtr.readUint256() & OffsetOrLengthMask);
- }
-
- /// @dev Returns the returndata pointer one word after `cdPtr`.
- function next(
- ReturndataPointer rdPtr
- ) internal pure returns (ReturndataPointer rdPtrNext) {
- assembly {
- rdPtrNext := add(rdPtr, _OneWord)
- }
- }
-
- /// @dev Returns the returndata pointer `_offset` bytes after `cdPtr`.
- function offset(
- ReturndataPointer rdPtr,
- uint256 _offset
- ) internal pure returns (ReturndataPointer rdPtrNext) {
- assembly {
- rdPtrNext := add(rdPtr, _offset)
- }
- }
-
- /// @dev Copies `size` bytes from returndata starting at `src` to memory at
- /// `dst`.
- function copy(
- ReturndataPointer src,
- MemoryPointer dst,
- uint256 size
- ) internal pure {
- assembly {
- returndatacopy(dst, src, size)
- }
- }
-}
-
-library MemoryPointerLib {
- function copy(
- MemoryPointer src,
- MemoryPointer dst,
- uint256 size
- ) internal view {
- assembly {
- let success := staticcall(
- gas(),
- IdentityPrecompileAddress,
- src,
- size,
- dst,
- size
- )
- if or(iszero(returndatasize()), iszero(success)) {
- revert(0, 0)
- }
- }
- }
-
- function lt(
- MemoryPointer a,
- MemoryPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := lt(a, b)
- }
- }
-
- function gt(
- MemoryPointer a,
- MemoryPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := gt(a, b)
- }
- }
-
- function eq(
- MemoryPointer a,
- MemoryPointer b
- ) internal pure returns (bool c) {
- assembly {
- c := eq(a, b)
- }
- }
-
- function isNull(MemoryPointer a) internal pure returns (bool b) {
- assembly {
- b := iszero(a)
- }
- }
-
- function hash(
- MemoryPointer ptr,
- uint256 length
- ) internal pure returns (bytes32 _hash) {
- assembly {
- _hash := keccak256(ptr, length)
- }
- }
-
- /// @dev Returns the memory pointer one word after `mPtr`.
- function next(
- MemoryPointer mPtr
- ) internal pure returns (MemoryPointer mPtrNext) {
- assembly {
- mPtrNext := add(mPtr, _OneWord)
- }
- }
-
- /// @dev Returns the memory pointer `_offset` bytes after `mPtr`.
- function offset(
- MemoryPointer mPtr,
- uint256 _offset
- ) internal pure returns (MemoryPointer mPtrNext) {
- assembly {
- mPtrNext := add(mPtr, _offset)
- }
- }
-
- /// @dev Resolves a pointer at `mPtr + headOffset` to a memory
- /// pointer. `mPtr` must point to some parent object with a dynamic
- /// type's pointer stored at `mPtr + headOffset`.
- function pptr(
- MemoryPointer mPtr,
- uint256 headOffset
- ) internal pure returns (MemoryPointer mPtrChild) {
- mPtrChild = mPtr.offset(headOffset).readMemoryPointer();
- }
-
- /// @dev Resolves a pointer stored at `mPtr` to a memory pointer.
- /// `mPtr` must point to some parent object with a dynamic type as its
- /// first member, e.g. `struct { bytes data; }`
- function pptr(
- MemoryPointer mPtr
- ) internal pure returns (MemoryPointer mPtrChild) {
- mPtrChild = mPtr.readMemoryPointer();
- }
-}
-
-library CalldataReaders {
- /// @dev Reads the value at `cdPtr` and applies a mask to return only the
- /// last 4 bytes.
- function readMaskedUint256(
- CalldataPointer cdPtr
- ) internal pure returns (uint256 value) {
- value = cdPtr.readUint256() & OffsetOrLengthMask;
- }
-
- /// @dev Reads the bool at `cdPtr` in calldata.
- function readBool(
- CalldataPointer cdPtr
- ) internal pure returns (bool value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the address at `cdPtr` in calldata.
- function readAddress(
- CalldataPointer cdPtr
- ) internal pure returns (address value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes1 at `cdPtr` in calldata.
- function readBytes1(
- CalldataPointer cdPtr
- ) internal pure returns (bytes1 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes2 at `cdPtr` in calldata.
- function readBytes2(
- CalldataPointer cdPtr
- ) internal pure returns (bytes2 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes3 at `cdPtr` in calldata.
- function readBytes3(
- CalldataPointer cdPtr
- ) internal pure returns (bytes3 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes4 at `cdPtr` in calldata.
- function readBytes4(
- CalldataPointer cdPtr
- ) internal pure returns (bytes4 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes5 at `cdPtr` in calldata.
- function readBytes5(
- CalldataPointer cdPtr
- ) internal pure returns (bytes5 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes6 at `cdPtr` in calldata.
- function readBytes6(
- CalldataPointer cdPtr
- ) internal pure returns (bytes6 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes7 at `cdPtr` in calldata.
- function readBytes7(
- CalldataPointer cdPtr
- ) internal pure returns (bytes7 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes8 at `cdPtr` in calldata.
- function readBytes8(
- CalldataPointer cdPtr
- ) internal pure returns (bytes8 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes9 at `cdPtr` in calldata.
- function readBytes9(
- CalldataPointer cdPtr
- ) internal pure returns (bytes9 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes10 at `cdPtr` in calldata.
- function readBytes10(
- CalldataPointer cdPtr
- ) internal pure returns (bytes10 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes11 at `cdPtr` in calldata.
- function readBytes11(
- CalldataPointer cdPtr
- ) internal pure returns (bytes11 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes12 at `cdPtr` in calldata.
- function readBytes12(
- CalldataPointer cdPtr
- ) internal pure returns (bytes12 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes13 at `cdPtr` in calldata.
- function readBytes13(
- CalldataPointer cdPtr
- ) internal pure returns (bytes13 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes14 at `cdPtr` in calldata.
- function readBytes14(
- CalldataPointer cdPtr
- ) internal pure returns (bytes14 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes15 at `cdPtr` in calldata.
- function readBytes15(
- CalldataPointer cdPtr
- ) internal pure returns (bytes15 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes16 at `cdPtr` in calldata.
- function readBytes16(
- CalldataPointer cdPtr
- ) internal pure returns (bytes16 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes17 at `cdPtr` in calldata.
- function readBytes17(
- CalldataPointer cdPtr
- ) internal pure returns (bytes17 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes18 at `cdPtr` in calldata.
- function readBytes18(
- CalldataPointer cdPtr
- ) internal pure returns (bytes18 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes19 at `cdPtr` in calldata.
- function readBytes19(
- CalldataPointer cdPtr
- ) internal pure returns (bytes19 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes20 at `cdPtr` in calldata.
- function readBytes20(
- CalldataPointer cdPtr
- ) internal pure returns (bytes20 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes21 at `cdPtr` in calldata.
- function readBytes21(
- CalldataPointer cdPtr
- ) internal pure returns (bytes21 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes22 at `cdPtr` in calldata.
- function readBytes22(
- CalldataPointer cdPtr
- ) internal pure returns (bytes22 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes23 at `cdPtr` in calldata.
- function readBytes23(
- CalldataPointer cdPtr
- ) internal pure returns (bytes23 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes24 at `cdPtr` in calldata.
- function readBytes24(
- CalldataPointer cdPtr
- ) internal pure returns (bytes24 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes25 at `cdPtr` in calldata.
- function readBytes25(
- CalldataPointer cdPtr
- ) internal pure returns (bytes25 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes26 at `cdPtr` in calldata.
- function readBytes26(
- CalldataPointer cdPtr
- ) internal pure returns (bytes26 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes27 at `cdPtr` in calldata.
- function readBytes27(
- CalldataPointer cdPtr
- ) internal pure returns (bytes27 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes28 at `cdPtr` in calldata.
- function readBytes28(
- CalldataPointer cdPtr
- ) internal pure returns (bytes28 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes29 at `cdPtr` in calldata.
- function readBytes29(
- CalldataPointer cdPtr
- ) internal pure returns (bytes29 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes30 at `cdPtr` in calldata.
- function readBytes30(
- CalldataPointer cdPtr
- ) internal pure returns (bytes30 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes31 at `cdPtr` in calldata.
- function readBytes31(
- CalldataPointer cdPtr
- ) internal pure returns (bytes31 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the bytes32 at `cdPtr` in calldata.
- function readBytes32(
- CalldataPointer cdPtr
- ) internal pure returns (bytes32 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint8 at `cdPtr` in calldata.
- function readUint8(
- CalldataPointer cdPtr
- ) internal pure returns (uint8 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint16 at `cdPtr` in calldata.
- function readUint16(
- CalldataPointer cdPtr
- ) internal pure returns (uint16 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint24 at `cdPtr` in calldata.
- function readUint24(
- CalldataPointer cdPtr
- ) internal pure returns (uint24 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint32 at `cdPtr` in calldata.
- function readUint32(
- CalldataPointer cdPtr
- ) internal pure returns (uint32 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint40 at `cdPtr` in calldata.
- function readUint40(
- CalldataPointer cdPtr
- ) internal pure returns (uint40 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint48 at `cdPtr` in calldata.
- function readUint48(
- CalldataPointer cdPtr
- ) internal pure returns (uint48 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint56 at `cdPtr` in calldata.
- function readUint56(
- CalldataPointer cdPtr
- ) internal pure returns (uint56 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint64 at `cdPtr` in calldata.
- function readUint64(
- CalldataPointer cdPtr
- ) internal pure returns (uint64 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint72 at `cdPtr` in calldata.
- function readUint72(
- CalldataPointer cdPtr
- ) internal pure returns (uint72 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint80 at `cdPtr` in calldata.
- function readUint80(
- CalldataPointer cdPtr
- ) internal pure returns (uint80 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint88 at `cdPtr` in calldata.
- function readUint88(
- CalldataPointer cdPtr
- ) internal pure returns (uint88 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint96 at `cdPtr` in calldata.
- function readUint96(
- CalldataPointer cdPtr
- ) internal pure returns (uint96 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint104 at `cdPtr` in calldata.
- function readUint104(
- CalldataPointer cdPtr
- ) internal pure returns (uint104 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint112 at `cdPtr` in calldata.
- function readUint112(
- CalldataPointer cdPtr
- ) internal pure returns (uint112 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint120 at `cdPtr` in calldata.
- function readUint120(
- CalldataPointer cdPtr
- ) internal pure returns (uint120 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint128 at `cdPtr` in calldata.
- function readUint128(
- CalldataPointer cdPtr
- ) internal pure returns (uint128 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint136 at `cdPtr` in calldata.
- function readUint136(
- CalldataPointer cdPtr
- ) internal pure returns (uint136 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint144 at `cdPtr` in calldata.
- function readUint144(
- CalldataPointer cdPtr
- ) internal pure returns (uint144 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint152 at `cdPtr` in calldata.
- function readUint152(
- CalldataPointer cdPtr
- ) internal pure returns (uint152 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint160 at `cdPtr` in calldata.
- function readUint160(
- CalldataPointer cdPtr
- ) internal pure returns (uint160 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint168 at `cdPtr` in calldata.
- function readUint168(
- CalldataPointer cdPtr
- ) internal pure returns (uint168 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint176 at `cdPtr` in calldata.
- function readUint176(
- CalldataPointer cdPtr
- ) internal pure returns (uint176 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint184 at `cdPtr` in calldata.
- function readUint184(
- CalldataPointer cdPtr
- ) internal pure returns (uint184 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint192 at `cdPtr` in calldata.
- function readUint192(
- CalldataPointer cdPtr
- ) internal pure returns (uint192 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint200 at `cdPtr` in calldata.
- function readUint200(
- CalldataPointer cdPtr
- ) internal pure returns (uint200 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint208 at `cdPtr` in calldata.
- function readUint208(
- CalldataPointer cdPtr
- ) internal pure returns (uint208 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint216 at `cdPtr` in calldata.
- function readUint216(
- CalldataPointer cdPtr
- ) internal pure returns (uint216 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint224 at `cdPtr` in calldata.
- function readUint224(
- CalldataPointer cdPtr
- ) internal pure returns (uint224 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint232 at `cdPtr` in calldata.
- function readUint232(
- CalldataPointer cdPtr
- ) internal pure returns (uint232 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint240 at `cdPtr` in calldata.
- function readUint240(
- CalldataPointer cdPtr
- ) internal pure returns (uint240 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint248 at `cdPtr` in calldata.
- function readUint248(
- CalldataPointer cdPtr
- ) internal pure returns (uint248 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the uint256 at `cdPtr` in calldata.
- function readUint256(
- CalldataPointer cdPtr
- ) internal pure returns (uint256 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int8 at `cdPtr` in calldata.
- function readInt8(
- CalldataPointer cdPtr
- ) internal pure returns (int8 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int16 at `cdPtr` in calldata.
- function readInt16(
- CalldataPointer cdPtr
- ) internal pure returns (int16 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int24 at `cdPtr` in calldata.
- function readInt24(
- CalldataPointer cdPtr
- ) internal pure returns (int24 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int32 at `cdPtr` in calldata.
- function readInt32(
- CalldataPointer cdPtr
- ) internal pure returns (int32 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int40 at `cdPtr` in calldata.
- function readInt40(
- CalldataPointer cdPtr
- ) internal pure returns (int40 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int48 at `cdPtr` in calldata.
- function readInt48(
- CalldataPointer cdPtr
- ) internal pure returns (int48 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int56 at `cdPtr` in calldata.
- function readInt56(
- CalldataPointer cdPtr
- ) internal pure returns (int56 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int64 at `cdPtr` in calldata.
- function readInt64(
- CalldataPointer cdPtr
- ) internal pure returns (int64 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int72 at `cdPtr` in calldata.
- function readInt72(
- CalldataPointer cdPtr
- ) internal pure returns (int72 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int80 at `cdPtr` in calldata.
- function readInt80(
- CalldataPointer cdPtr
- ) internal pure returns (int80 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int88 at `cdPtr` in calldata.
- function readInt88(
- CalldataPointer cdPtr
- ) internal pure returns (int88 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int96 at `cdPtr` in calldata.
- function readInt96(
- CalldataPointer cdPtr
- ) internal pure returns (int96 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int104 at `cdPtr` in calldata.
- function readInt104(
- CalldataPointer cdPtr
- ) internal pure returns (int104 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int112 at `cdPtr` in calldata.
- function readInt112(
- CalldataPointer cdPtr
- ) internal pure returns (int112 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int120 at `cdPtr` in calldata.
- function readInt120(
- CalldataPointer cdPtr
- ) internal pure returns (int120 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int128 at `cdPtr` in calldata.
- function readInt128(
- CalldataPointer cdPtr
- ) internal pure returns (int128 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int136 at `cdPtr` in calldata.
- function readInt136(
- CalldataPointer cdPtr
- ) internal pure returns (int136 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int144 at `cdPtr` in calldata.
- function readInt144(
- CalldataPointer cdPtr
- ) internal pure returns (int144 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int152 at `cdPtr` in calldata.
- function readInt152(
- CalldataPointer cdPtr
- ) internal pure returns (int152 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int160 at `cdPtr` in calldata.
- function readInt160(
- CalldataPointer cdPtr
- ) internal pure returns (int160 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int168 at `cdPtr` in calldata.
- function readInt168(
- CalldataPointer cdPtr
- ) internal pure returns (int168 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int176 at `cdPtr` in calldata.
- function readInt176(
- CalldataPointer cdPtr
- ) internal pure returns (int176 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int184 at `cdPtr` in calldata.
- function readInt184(
- CalldataPointer cdPtr
- ) internal pure returns (int184 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int192 at `cdPtr` in calldata.
- function readInt192(
- CalldataPointer cdPtr
- ) internal pure returns (int192 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int200 at `cdPtr` in calldata.
- function readInt200(
- CalldataPointer cdPtr
- ) internal pure returns (int200 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int208 at `cdPtr` in calldata.
- function readInt208(
- CalldataPointer cdPtr
- ) internal pure returns (int208 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int216 at `cdPtr` in calldata.
- function readInt216(
- CalldataPointer cdPtr
- ) internal pure returns (int216 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int224 at `cdPtr` in calldata.
- function readInt224(
- CalldataPointer cdPtr
- ) internal pure returns (int224 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int232 at `cdPtr` in calldata.
- function readInt232(
- CalldataPointer cdPtr
- ) internal pure returns (int232 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int240 at `cdPtr` in calldata.
- function readInt240(
- CalldataPointer cdPtr
- ) internal pure returns (int240 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int248 at `cdPtr` in calldata.
- function readInt248(
- CalldataPointer cdPtr
- ) internal pure returns (int248 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-
- /// @dev Reads the int256 at `cdPtr` in calldata.
- function readInt256(
- CalldataPointer cdPtr
- ) internal pure returns (int256 value) {
- assembly {
- value := calldataload(cdPtr)
- }
- }
-}
-
-library ReturndataReaders {
- /// @dev Reads value at `rdPtr` & applies a mask to return only last 4 bytes
- function readMaskedUint256(
- ReturndataPointer rdPtr
- ) internal pure returns (uint256 value) {
- value = rdPtr.readUint256() & OffsetOrLengthMask;
- }
-
- /// @dev Reads the bool at `rdPtr` in returndata.
- function readBool(
- ReturndataPointer rdPtr
- ) internal pure returns (bool value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the address at `rdPtr` in returndata.
- function readAddress(
- ReturndataPointer rdPtr
- ) internal pure returns (address value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes1 at `rdPtr` in returndata.
- function readBytes1(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes1 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes2 at `rdPtr` in returndata.
- function readBytes2(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes2 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes3 at `rdPtr` in returndata.
- function readBytes3(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes3 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes4 at `rdPtr` in returndata.
- function readBytes4(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes4 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes5 at `rdPtr` in returndata.
- function readBytes5(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes5 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes6 at `rdPtr` in returndata.
- function readBytes6(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes6 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes7 at `rdPtr` in returndata.
- function readBytes7(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes7 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes8 at `rdPtr` in returndata.
- function readBytes8(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes8 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes9 at `rdPtr` in returndata.
- function readBytes9(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes9 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes10 at `rdPtr` in returndata.
- function readBytes10(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes10 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes11 at `rdPtr` in returndata.
- function readBytes11(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes11 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes12 at `rdPtr` in returndata.
- function readBytes12(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes12 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes13 at `rdPtr` in returndata.
- function readBytes13(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes13 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes14 at `rdPtr` in returndata.
- function readBytes14(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes14 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes15 at `rdPtr` in returndata.
- function readBytes15(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes15 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes16 at `rdPtr` in returndata.
- function readBytes16(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes16 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes17 at `rdPtr` in returndata.
- function readBytes17(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes17 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes18 at `rdPtr` in returndata.
- function readBytes18(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes18 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes19 at `rdPtr` in returndata.
- function readBytes19(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes19 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes20 at `rdPtr` in returndata.
- function readBytes20(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes20 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes21 at `rdPtr` in returndata.
- function readBytes21(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes21 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes22 at `rdPtr` in returndata.
- function readBytes22(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes22 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes23 at `rdPtr` in returndata.
- function readBytes23(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes23 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes24 at `rdPtr` in returndata.
- function readBytes24(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes24 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes25 at `rdPtr` in returndata.
- function readBytes25(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes25 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes26 at `rdPtr` in returndata.
- function readBytes26(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes26 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes27 at `rdPtr` in returndata.
- function readBytes27(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes27 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes28 at `rdPtr` in returndata.
- function readBytes28(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes28 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes29 at `rdPtr` in returndata.
- function readBytes29(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes29 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes30 at `rdPtr` in returndata.
- function readBytes30(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes30 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes31 at `rdPtr` in returndata.
- function readBytes31(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes31 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the bytes32 at `rdPtr` in returndata.
- function readBytes32(
- ReturndataPointer rdPtr
- ) internal pure returns (bytes32 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint8 at `rdPtr` in returndata.
- function readUint8(
- ReturndataPointer rdPtr
- ) internal pure returns (uint8 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint16 at `rdPtr` in returndata.
- function readUint16(
- ReturndataPointer rdPtr
- ) internal pure returns (uint16 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint24 at `rdPtr` in returndata.
- function readUint24(
- ReturndataPointer rdPtr
- ) internal pure returns (uint24 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint32 at `rdPtr` in returndata.
- function readUint32(
- ReturndataPointer rdPtr
- ) internal pure returns (uint32 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint40 at `rdPtr` in returndata.
- function readUint40(
- ReturndataPointer rdPtr
- ) internal pure returns (uint40 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint48 at `rdPtr` in returndata.
- function readUint48(
- ReturndataPointer rdPtr
- ) internal pure returns (uint48 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint56 at `rdPtr` in returndata.
- function readUint56(
- ReturndataPointer rdPtr
- ) internal pure returns (uint56 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint64 at `rdPtr` in returndata.
- function readUint64(
- ReturndataPointer rdPtr
- ) internal pure returns (uint64 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint72 at `rdPtr` in returndata.
- function readUint72(
- ReturndataPointer rdPtr
- ) internal pure returns (uint72 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint80 at `rdPtr` in returndata.
- function readUint80(
- ReturndataPointer rdPtr
- ) internal pure returns (uint80 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint88 at `rdPtr` in returndata.
- function readUint88(
- ReturndataPointer rdPtr
- ) internal pure returns (uint88 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint96 at `rdPtr` in returndata.
- function readUint96(
- ReturndataPointer rdPtr
- ) internal pure returns (uint96 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint104 at `rdPtr` in returndata.
- function readUint104(
- ReturndataPointer rdPtr
- ) internal pure returns (uint104 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint112 at `rdPtr` in returndata.
- function readUint112(
- ReturndataPointer rdPtr
- ) internal pure returns (uint112 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint120 at `rdPtr` in returndata.
- function readUint120(
- ReturndataPointer rdPtr
- ) internal pure returns (uint120 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint128 at `rdPtr` in returndata.
- function readUint128(
- ReturndataPointer rdPtr
- ) internal pure returns (uint128 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint136 at `rdPtr` in returndata.
- function readUint136(
- ReturndataPointer rdPtr
- ) internal pure returns (uint136 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint144 at `rdPtr` in returndata.
- function readUint144(
- ReturndataPointer rdPtr
- ) internal pure returns (uint144 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint152 at `rdPtr` in returndata.
- function readUint152(
- ReturndataPointer rdPtr
- ) internal pure returns (uint152 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint160 at `rdPtr` in returndata.
- function readUint160(
- ReturndataPointer rdPtr
- ) internal pure returns (uint160 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint168 at `rdPtr` in returndata.
- function readUint168(
- ReturndataPointer rdPtr
- ) internal pure returns (uint168 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint176 at `rdPtr` in returndata.
- function readUint176(
- ReturndataPointer rdPtr
- ) internal pure returns (uint176 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint184 at `rdPtr` in returndata.
- function readUint184(
- ReturndataPointer rdPtr
- ) internal pure returns (uint184 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint192 at `rdPtr` in returndata.
- function readUint192(
- ReturndataPointer rdPtr
- ) internal pure returns (uint192 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint200 at `rdPtr` in returndata.
- function readUint200(
- ReturndataPointer rdPtr
- ) internal pure returns (uint200 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint208 at `rdPtr` in returndata.
- function readUint208(
- ReturndataPointer rdPtr
- ) internal pure returns (uint208 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint216 at `rdPtr` in returndata.
- function readUint216(
- ReturndataPointer rdPtr
- ) internal pure returns (uint216 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint224 at `rdPtr` in returndata.
- function readUint224(
- ReturndataPointer rdPtr
- ) internal pure returns (uint224 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint232 at `rdPtr` in returndata.
- function readUint232(
- ReturndataPointer rdPtr
- ) internal pure returns (uint232 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint240 at `rdPtr` in returndata.
- function readUint240(
- ReturndataPointer rdPtr
- ) internal pure returns (uint240 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint248 at `rdPtr` in returndata.
- function readUint248(
- ReturndataPointer rdPtr
- ) internal pure returns (uint248 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the uint256 at `rdPtr` in returndata.
- function readUint256(
- ReturndataPointer rdPtr
- ) internal pure returns (uint256 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int8 at `rdPtr` in returndata.
- function readInt8(
- ReturndataPointer rdPtr
- ) internal pure returns (int8 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int16 at `rdPtr` in returndata.
- function readInt16(
- ReturndataPointer rdPtr
- ) internal pure returns (int16 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int24 at `rdPtr` in returndata.
- function readInt24(
- ReturndataPointer rdPtr
- ) internal pure returns (int24 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int32 at `rdPtr` in returndata.
- function readInt32(
- ReturndataPointer rdPtr
- ) internal pure returns (int32 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int40 at `rdPtr` in returndata.
- function readInt40(
- ReturndataPointer rdPtr
- ) internal pure returns (int40 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int48 at `rdPtr` in returndata.
- function readInt48(
- ReturndataPointer rdPtr
- ) internal pure returns (int48 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int56 at `rdPtr` in returndata.
- function readInt56(
- ReturndataPointer rdPtr
- ) internal pure returns (int56 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int64 at `rdPtr` in returndata.
- function readInt64(
- ReturndataPointer rdPtr
- ) internal pure returns (int64 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int72 at `rdPtr` in returndata.
- function readInt72(
- ReturndataPointer rdPtr
- ) internal pure returns (int72 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int80 at `rdPtr` in returndata.
- function readInt80(
- ReturndataPointer rdPtr
- ) internal pure returns (int80 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int88 at `rdPtr` in returndata.
- function readInt88(
- ReturndataPointer rdPtr
- ) internal pure returns (int88 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int96 at `rdPtr` in returndata.
- function readInt96(
- ReturndataPointer rdPtr
- ) internal pure returns (int96 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int104 at `rdPtr` in returndata.
- function readInt104(
- ReturndataPointer rdPtr
- ) internal pure returns (int104 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int112 at `rdPtr` in returndata.
- function readInt112(
- ReturndataPointer rdPtr
- ) internal pure returns (int112 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int120 at `rdPtr` in returndata.
- function readInt120(
- ReturndataPointer rdPtr
- ) internal pure returns (int120 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int128 at `rdPtr` in returndata.
- function readInt128(
- ReturndataPointer rdPtr
- ) internal pure returns (int128 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int136 at `rdPtr` in returndata.
- function readInt136(
- ReturndataPointer rdPtr
- ) internal pure returns (int136 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int144 at `rdPtr` in returndata.
- function readInt144(
- ReturndataPointer rdPtr
- ) internal pure returns (int144 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int152 at `rdPtr` in returndata.
- function readInt152(
- ReturndataPointer rdPtr
- ) internal pure returns (int152 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int160 at `rdPtr` in returndata.
- function readInt160(
- ReturndataPointer rdPtr
- ) internal pure returns (int160 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int168 at `rdPtr` in returndata.
- function readInt168(
- ReturndataPointer rdPtr
- ) internal pure returns (int168 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int176 at `rdPtr` in returndata.
- function readInt176(
- ReturndataPointer rdPtr
- ) internal pure returns (int176 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int184 at `rdPtr` in returndata.
- function readInt184(
- ReturndataPointer rdPtr
- ) internal pure returns (int184 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int192 at `rdPtr` in returndata.
- function readInt192(
- ReturndataPointer rdPtr
- ) internal pure returns (int192 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int200 at `rdPtr` in returndata.
- function readInt200(
- ReturndataPointer rdPtr
- ) internal pure returns (int200 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int208 at `rdPtr` in returndata.
- function readInt208(
- ReturndataPointer rdPtr
- ) internal pure returns (int208 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int216 at `rdPtr` in returndata.
- function readInt216(
- ReturndataPointer rdPtr
- ) internal pure returns (int216 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int224 at `rdPtr` in returndata.
- function readInt224(
- ReturndataPointer rdPtr
- ) internal pure returns (int224 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int232 at `rdPtr` in returndata.
- function readInt232(
- ReturndataPointer rdPtr
- ) internal pure returns (int232 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int240 at `rdPtr` in returndata.
- function readInt240(
- ReturndataPointer rdPtr
- ) internal pure returns (int240 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int248 at `rdPtr` in returndata.
- function readInt248(
- ReturndataPointer rdPtr
- ) internal pure returns (int248 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-
- /// @dev Reads the int256 at `rdPtr` in returndata.
- function readInt256(
- ReturndataPointer rdPtr
- ) internal pure returns (int256 value) {
- assembly {
- returndatacopy(0, rdPtr, _OneWord)
- value := mload(0)
- }
- }
-}
-
-library MemoryReaders {
- /// @dev Reads the memory pointer at `mPtr` in memory.
- function readMemoryPointer(
- MemoryPointer mPtr
- ) internal pure returns (MemoryPointer value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads value at `mPtr` & applies a mask to return only last 4 bytes
- function readMaskedUint256(
- MemoryPointer mPtr
- ) internal pure returns (uint256 value) {
- value = mPtr.readUint256() & OffsetOrLengthMask;
- }
-
- /// @dev Reads the bool at `mPtr` in memory.
- function readBool(MemoryPointer mPtr) internal pure returns (bool value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the address at `mPtr` in memory.
- function readAddress(
- MemoryPointer mPtr
- ) internal pure returns (address value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes1 at `mPtr` in memory.
- function readBytes1(
- MemoryPointer mPtr
- ) internal pure returns (bytes1 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes2 at `mPtr` in memory.
- function readBytes2(
- MemoryPointer mPtr
- ) internal pure returns (bytes2 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes3 at `mPtr` in memory.
- function readBytes3(
- MemoryPointer mPtr
- ) internal pure returns (bytes3 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes4 at `mPtr` in memory.
- function readBytes4(
- MemoryPointer mPtr
- ) internal pure returns (bytes4 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes5 at `mPtr` in memory.
- function readBytes5(
- MemoryPointer mPtr
- ) internal pure returns (bytes5 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes6 at `mPtr` in memory.
- function readBytes6(
- MemoryPointer mPtr
- ) internal pure returns (bytes6 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes7 at `mPtr` in memory.
- function readBytes7(
- MemoryPointer mPtr
- ) internal pure returns (bytes7 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes8 at `mPtr` in memory.
- function readBytes8(
- MemoryPointer mPtr
- ) internal pure returns (bytes8 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes9 at `mPtr` in memory.
- function readBytes9(
- MemoryPointer mPtr
- ) internal pure returns (bytes9 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes10 at `mPtr` in memory.
- function readBytes10(
- MemoryPointer mPtr
- ) internal pure returns (bytes10 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes11 at `mPtr` in memory.
- function readBytes11(
- MemoryPointer mPtr
- ) internal pure returns (bytes11 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes12 at `mPtr` in memory.
- function readBytes12(
- MemoryPointer mPtr
- ) internal pure returns (bytes12 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes13 at `mPtr` in memory.
- function readBytes13(
- MemoryPointer mPtr
- ) internal pure returns (bytes13 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes14 at `mPtr` in memory.
- function readBytes14(
- MemoryPointer mPtr
- ) internal pure returns (bytes14 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes15 at `mPtr` in memory.
- function readBytes15(
- MemoryPointer mPtr
- ) internal pure returns (bytes15 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes16 at `mPtr` in memory.
- function readBytes16(
- MemoryPointer mPtr
- ) internal pure returns (bytes16 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes17 at `mPtr` in memory.
- function readBytes17(
- MemoryPointer mPtr
- ) internal pure returns (bytes17 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes18 at `mPtr` in memory.
- function readBytes18(
- MemoryPointer mPtr
- ) internal pure returns (bytes18 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes19 at `mPtr` in memory.
- function readBytes19(
- MemoryPointer mPtr
- ) internal pure returns (bytes19 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes20 at `mPtr` in memory.
- function readBytes20(
- MemoryPointer mPtr
- ) internal pure returns (bytes20 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes21 at `mPtr` in memory.
- function readBytes21(
- MemoryPointer mPtr
- ) internal pure returns (bytes21 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes22 at `mPtr` in memory.
- function readBytes22(
- MemoryPointer mPtr
- ) internal pure returns (bytes22 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes23 at `mPtr` in memory.
- function readBytes23(
- MemoryPointer mPtr
- ) internal pure returns (bytes23 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes24 at `mPtr` in memory.
- function readBytes24(
- MemoryPointer mPtr
- ) internal pure returns (bytes24 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes25 at `mPtr` in memory.
- function readBytes25(
- MemoryPointer mPtr
- ) internal pure returns (bytes25 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes26 at `mPtr` in memory.
- function readBytes26(
- MemoryPointer mPtr
- ) internal pure returns (bytes26 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes27 at `mPtr` in memory.
- function readBytes27(
- MemoryPointer mPtr
- ) internal pure returns (bytes27 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes28 at `mPtr` in memory.
- function readBytes28(
- MemoryPointer mPtr
- ) internal pure returns (bytes28 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes29 at `mPtr` in memory.
- function readBytes29(
- MemoryPointer mPtr
- ) internal pure returns (bytes29 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes30 at `mPtr` in memory.
- function readBytes30(
- MemoryPointer mPtr
- ) internal pure returns (bytes30 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes31 at `mPtr` in memory.
- function readBytes31(
- MemoryPointer mPtr
- ) internal pure returns (bytes31 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the bytes32 at `mPtr` in memory.
- function readBytes32(
- MemoryPointer mPtr
- ) internal pure returns (bytes32 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint8 at `mPtr` in memory.
- function readUint8(MemoryPointer mPtr) internal pure returns (uint8 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint16 at `mPtr` in memory.
- function readUint16(
- MemoryPointer mPtr
- ) internal pure returns (uint16 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint24 at `mPtr` in memory.
- function readUint24(
- MemoryPointer mPtr
- ) internal pure returns (uint24 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint32 at `mPtr` in memory.
- function readUint32(
- MemoryPointer mPtr
- ) internal pure returns (uint32 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint40 at `mPtr` in memory.
- function readUint40(
- MemoryPointer mPtr
- ) internal pure returns (uint40 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint48 at `mPtr` in memory.
- function readUint48(
- MemoryPointer mPtr
- ) internal pure returns (uint48 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint56 at `mPtr` in memory.
- function readUint56(
- MemoryPointer mPtr
- ) internal pure returns (uint56 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint64 at `mPtr` in memory.
- function readUint64(
- MemoryPointer mPtr
- ) internal pure returns (uint64 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint72 at `mPtr` in memory.
- function readUint72(
- MemoryPointer mPtr
- ) internal pure returns (uint72 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint80 at `mPtr` in memory.
- function readUint80(
- MemoryPointer mPtr
- ) internal pure returns (uint80 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint88 at `mPtr` in memory.
- function readUint88(
- MemoryPointer mPtr
- ) internal pure returns (uint88 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint96 at `mPtr` in memory.
- function readUint96(
- MemoryPointer mPtr
- ) internal pure returns (uint96 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint104 at `mPtr` in memory.
- function readUint104(
- MemoryPointer mPtr
- ) internal pure returns (uint104 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint112 at `mPtr` in memory.
- function readUint112(
- MemoryPointer mPtr
- ) internal pure returns (uint112 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint120 at `mPtr` in memory.
- function readUint120(
- MemoryPointer mPtr
- ) internal pure returns (uint120 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint128 at `mPtr` in memory.
- function readUint128(
- MemoryPointer mPtr
- ) internal pure returns (uint128 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint136 at `mPtr` in memory.
- function readUint136(
- MemoryPointer mPtr
- ) internal pure returns (uint136 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint144 at `mPtr` in memory.
- function readUint144(
- MemoryPointer mPtr
- ) internal pure returns (uint144 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint152 at `mPtr` in memory.
- function readUint152(
- MemoryPointer mPtr
- ) internal pure returns (uint152 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint160 at `mPtr` in memory.
- function readUint160(
- MemoryPointer mPtr
- ) internal pure returns (uint160 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint168 at `mPtr` in memory.
- function readUint168(
- MemoryPointer mPtr
- ) internal pure returns (uint168 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint176 at `mPtr` in memory.
- function readUint176(
- MemoryPointer mPtr
- ) internal pure returns (uint176 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint184 at `mPtr` in memory.
- function readUint184(
- MemoryPointer mPtr
- ) internal pure returns (uint184 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint192 at `mPtr` in memory.
- function readUint192(
- MemoryPointer mPtr
- ) internal pure returns (uint192 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint200 at `mPtr` in memory.
- function readUint200(
- MemoryPointer mPtr
- ) internal pure returns (uint200 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint208 at `mPtr` in memory.
- function readUint208(
- MemoryPointer mPtr
- ) internal pure returns (uint208 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint216 at `mPtr` in memory.
- function readUint216(
- MemoryPointer mPtr
- ) internal pure returns (uint216 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint224 at `mPtr` in memory.
- function readUint224(
- MemoryPointer mPtr
- ) internal pure returns (uint224 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint232 at `mPtr` in memory.
- function readUint232(
- MemoryPointer mPtr
- ) internal pure returns (uint232 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint240 at `mPtr` in memory.
- function readUint240(
- MemoryPointer mPtr
- ) internal pure returns (uint240 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint248 at `mPtr` in memory.
- function readUint248(
- MemoryPointer mPtr
- ) internal pure returns (uint248 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the uint256 at `mPtr` in memory.
- function readUint256(
- MemoryPointer mPtr
- ) internal pure returns (uint256 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int8 at `mPtr` in memory.
- function readInt8(MemoryPointer mPtr) internal pure returns (int8 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int16 at `mPtr` in memory.
- function readInt16(MemoryPointer mPtr) internal pure returns (int16 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int24 at `mPtr` in memory.
- function readInt24(MemoryPointer mPtr) internal pure returns (int24 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int32 at `mPtr` in memory.
- function readInt32(MemoryPointer mPtr) internal pure returns (int32 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int40 at `mPtr` in memory.
- function readInt40(MemoryPointer mPtr) internal pure returns (int40 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int48 at `mPtr` in memory.
- function readInt48(MemoryPointer mPtr) internal pure returns (int48 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int56 at `mPtr` in memory.
- function readInt56(MemoryPointer mPtr) internal pure returns (int56 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int64 at `mPtr` in memory.
- function readInt64(MemoryPointer mPtr) internal pure returns (int64 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int72 at `mPtr` in memory.
- function readInt72(MemoryPointer mPtr) internal pure returns (int72 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int80 at `mPtr` in memory.
- function readInt80(MemoryPointer mPtr) internal pure returns (int80 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int88 at `mPtr` in memory.
- function readInt88(MemoryPointer mPtr) internal pure returns (int88 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int96 at `mPtr` in memory.
- function readInt96(MemoryPointer mPtr) internal pure returns (int96 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int104 at `mPtr` in memory.
- function readInt104(
- MemoryPointer mPtr
- ) internal pure returns (int104 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int112 at `mPtr` in memory.
- function readInt112(
- MemoryPointer mPtr
- ) internal pure returns (int112 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int120 at `mPtr` in memory.
- function readInt120(
- MemoryPointer mPtr
- ) internal pure returns (int120 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int128 at `mPtr` in memory.
- function readInt128(
- MemoryPointer mPtr
- ) internal pure returns (int128 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int136 at `mPtr` in memory.
- function readInt136(
- MemoryPointer mPtr
- ) internal pure returns (int136 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int144 at `mPtr` in memory.
- function readInt144(
- MemoryPointer mPtr
- ) internal pure returns (int144 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int152 at `mPtr` in memory.
- function readInt152(
- MemoryPointer mPtr
- ) internal pure returns (int152 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int160 at `mPtr` in memory.
- function readInt160(
- MemoryPointer mPtr
- ) internal pure returns (int160 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int168 at `mPtr` in memory.
- function readInt168(
- MemoryPointer mPtr
- ) internal pure returns (int168 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int176 at `mPtr` in memory.
- function readInt176(
- MemoryPointer mPtr
- ) internal pure returns (int176 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int184 at `mPtr` in memory.
- function readInt184(
- MemoryPointer mPtr
- ) internal pure returns (int184 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int192 at `mPtr` in memory.
- function readInt192(
- MemoryPointer mPtr
- ) internal pure returns (int192 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int200 at `mPtr` in memory.
- function readInt200(
- MemoryPointer mPtr
- ) internal pure returns (int200 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int208 at `mPtr` in memory.
- function readInt208(
- MemoryPointer mPtr
- ) internal pure returns (int208 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int216 at `mPtr` in memory.
- function readInt216(
- MemoryPointer mPtr
- ) internal pure returns (int216 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int224 at `mPtr` in memory.
- function readInt224(
- MemoryPointer mPtr
- ) internal pure returns (int224 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int232 at `mPtr` in memory.
- function readInt232(
- MemoryPointer mPtr
- ) internal pure returns (int232 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int240 at `mPtr` in memory.
- function readInt240(
- MemoryPointer mPtr
- ) internal pure returns (int240 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int248 at `mPtr` in memory.
- function readInt248(
- MemoryPointer mPtr
- ) internal pure returns (int248 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-
- /// @dev Reads the int256 at `mPtr` in memory.
- function readInt256(
- MemoryPointer mPtr
- ) internal pure returns (int256 value) {
- assembly {
- value := mload(mPtr)
- }
- }
-}
-
-library MemoryWriters {
- /// @dev Writes `valuePtr` to memory at `mPtr`.
- function write(MemoryPointer mPtr, MemoryPointer valuePtr) internal pure {
- assembly {
- mstore(mPtr, valuePtr)
- }
- }
-
- /// @dev Writes a boolean `value` to `mPtr` in memory.
- function write(MemoryPointer mPtr, bool value) internal pure {
- assembly {
- mstore(mPtr, value)
- }
- }
-
- /// @dev Writes an address `value` to `mPtr` in memory.
- function write(MemoryPointer mPtr, address value) internal pure {
- assembly {
- mstore(mPtr, value)
- }
- }
-
- /// @dev Writes a bytes32 `value` to `mPtr` in memory.
- /// Separate name to disambiguate literal write parameters.
- function writeBytes32(MemoryPointer mPtr, bytes32 value) internal pure {
- assembly {
- mstore(mPtr, value)
- }
- }
-
- /// @dev Writes a uint256 `value` to `mPtr` in memory.
- function write(MemoryPointer mPtr, uint256 value) internal pure {
- assembly {
- mstore(mPtr, value)
- }
- }
-
- /// @dev Writes an int256 `value` to `mPtr` in memory.
- /// Separate name to disambiguate literal write parameters.
- function writeInt(MemoryPointer mPtr, int256 value) internal pure {
- assembly {
- mstore(mPtr, value)
- }
- }
-}
diff --git a/contracts/helpers/SeaportRouter.sol b/contracts/helpers/SeaportRouter.sol
index c02b0e6f6..9b1920695 100644
--- a/contracts/helpers/SeaportRouter.sol
+++ b/contracts/helpers/SeaportRouter.sol
@@ -3,18 +3,20 @@ pragma solidity ^0.8.13;
import {
SeaportRouterInterface
-} from "../interfaces/SeaportRouterInterface.sol";
+} from "seaport-types/src/interfaces/SeaportRouterInterface.sol";
-import { SeaportInterface } from "../interfaces/SeaportInterface.sol";
+import {
+ SeaportInterface
+} from "seaport-types/src/interfaces/SeaportInterface.sol";
-import { ReentrancyGuard } from "../lib/ReentrancyGuard.sol";
+import { ReentrancyGuard } from "seaport-core/src/lib/ReentrancyGuard.sol";
import {
AdvancedOrder,
CriteriaResolver,
Execution,
FulfillmentComponent
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
/**
* @title SeaportRouter
diff --git a/contracts/helpers/TransferHelper.sol b/contracts/helpers/TransferHelper.sol
index b08ec405e..aa60a3308 100644
--- a/contracts/helpers/TransferHelper.sol
+++ b/contracts/helpers/TransferHelper.sol
@@ -1,28 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { IERC721Receiver } from "../interfaces/IERC721Receiver.sol";
+import {
+ IERC721Receiver
+} from "seaport-types/src/interfaces/IERC721Receiver.sol";
import {
TransferHelperItem,
TransferHelperItemsWithRecipient
-} from "./TransferHelperStructs.sol";
+} from "seaport-types/src/helpers/TransferHelperStructs.sol";
-import { ConduitItemType } from "../conduit/lib/ConduitEnums.sol";
+import {
+ ConduitItemType
+} from "seaport-types/src/conduit/lib/ConduitEnums.sol";
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
+import {
+ ConduitInterface
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
import {
ConduitControllerInterface
-} from "../interfaces/ConduitControllerInterface.sol";
+} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";
-import { ConduitTransfer } from "../conduit/lib/ConduitStructs.sol";
+import {
+ ConduitTransfer
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
import {
TransferHelperInterface
-} from "../interfaces/TransferHelperInterface.sol";
+} from "seaport-types/src/interfaces/TransferHelperInterface.sol";
-import { TransferHelperErrors } from "../interfaces/TransferHelperErrors.sol";
+import {
+ TransferHelperErrors
+} from "seaport-types/src/interfaces/TransferHelperErrors.sol";
/**
* @title TransferHelper
@@ -118,11 +128,14 @@ contract TransferHelper is TransferHelperInterface, TransferHelperErrors {
)
);
- // Declare a variable to store the sum of all items across transfers.
- uint256 sumOfItemsAcrossAllTransfers;
+ // Declare a new array in memory to track each conduit transfer.
+ ConduitTransfer[] memory conduitTransfers;
// Skip overflow checks: all for loops are indexed starting at zero.
unchecked {
+ // Declare a variable to store sum of all items across transfers.
+ uint256 sumOfItemsAcrossAllTransfers;
+
// Iterate over each transfer.
for (uint256 i = 0; i < numTransfers; ++i) {
// Retrieve the transfer in question.
@@ -133,85 +146,21 @@ contract TransferHelper is TransferHelperInterface, TransferHelperErrors {
// Increment totalItems by the number of items in the transfer.
sumOfItemsAcrossAllTransfers += transfer.items.length;
}
+
+ // Assign length totalItems to populate with each conduit transfer.
+ conduitTransfers = new ConduitTransfer[](
+ sumOfItemsAcrossAllTransfers
+ );
}
- // Declare a new array in memory with length totalItems to populate with
- // each conduit transfer.
- ConduitTransfer[] memory conduitTransfers = new ConduitTransfer[](
- sumOfItemsAcrossAllTransfers
+ // Process the conduit transfers and prepare to execute them.
+ _processConduitTransfers(
+ conduitTransfers,
+ transfers,
+ conduit,
+ numTransfers
);
- // Declare an index for storing ConduitTransfers in conduitTransfers.
- uint256 itemIndex;
-
- // Skip overflow checks: all for loops are indexed starting at zero.
- unchecked {
- // Iterate over each transfer.
- for (uint256 i = 0; i < numTransfers; ++i) {
- // Retrieve the transfer in question.
- TransferHelperItemsWithRecipient calldata transfer = transfers[
- i
- ];
-
- // Retrieve the items of the transfer in question.
- TransferHelperItem[] calldata transferItems = transfer.items;
-
- // Ensure recipient is not the zero address.
- _checkRecipientIsNotZeroAddress(transfer.recipient);
-
- // Create a boolean indicating whether validateERC721Receiver
- // is true and recipient is a contract.
- bool callERC721Receiver = transfer.validateERC721Receiver &&
- transfer.recipient.code.length != 0;
-
- // Retrieve the total number of items in the transfer and
- // place on stack.
- uint256 numItemsInTransfer = transferItems.length;
-
- // Iterate over each item in the transfer to create a
- // corresponding ConduitTransfer.
- for (uint256 j = 0; j < numItemsInTransfer; ++j) {
- // Retrieve the item from the transfer.
- TransferHelperItem calldata item = transferItems[j];
-
- if (item.itemType == ConduitItemType.ERC20) {
- // Ensure that the identifier of an ERC20 token is 0.
- if (item.identifier != 0) {
- revert InvalidERC20Identifier();
- }
- }
-
- // If the item is an ERC721 token and
- // callERC721Receiver is true...
- if (item.itemType == ConduitItemType.ERC721) {
- if (callERC721Receiver) {
- // Check if the recipient implements
- // onERC721Received for the given tokenId.
- _checkERC721Receiver(
- conduit,
- transfer.recipient,
- item.identifier
- );
- }
- }
-
- // Create a ConduitTransfer corresponding to each
- // TransferHelperItem.
- conduitTransfers[itemIndex] = ConduitTransfer(
- item.itemType,
- item.token,
- msg.sender,
- transfer.recipient,
- item.identifier,
- item.amount
- );
-
- // Increment the index for storing ConduitTransfers.
- ++itemIndex;
- }
- }
- }
-
// Attempt the external call to transfer tokens via the derived conduit.
try ConduitInterface(conduit).execute(conduitTransfers) returns (
bytes4 conduitMagicValue
@@ -329,6 +278,113 @@ contract TransferHelper is TransferHelperInterface, TransferHelperErrors {
}
}
+ /**
+ * @notice An internal function that prepares conduit transfers.
+ *
+ * @param conduitTransfers The allocated conduit transfers array.
+ * @param transfers The transfers in question.
+ * @param conduit The conduit in question.
+ * @param numTransfers The total number of transfers.
+ */
+ function _processConduitTransfers(
+ ConduitTransfer[] memory conduitTransfers,
+ TransferHelperItemsWithRecipient[] calldata transfers,
+ address conduit,
+ uint256 numTransfers
+ ) internal {
+ // Skip overflow checks: all for loops are indexed starting at zero.
+ unchecked {
+ // Declare index to store ConduitTransfers in conduitTransfers.
+ uint256 itemIndex;
+
+ // Iterate over each transfer.
+ for (uint256 i = 0; i < numTransfers; ++i) {
+ // Retrieve the transfer in question.
+ TransferHelperItemsWithRecipient calldata transfer = transfers[
+ i
+ ];
+
+ // Retrieve the items of the transfer in question.
+ TransferHelperItem[] calldata transferItems = transfer.items;
+
+ // Ensure recipient is not the zero address.
+ _checkRecipientIsNotZeroAddress(transfer.recipient);
+
+ // Create a boolean indicating whether validateERC721Receiver
+ // is true and recipient is a contract.
+ bool callERC721Receiver = transfer.validateERC721Receiver &&
+ transfer.recipient.code.length != 0;
+
+ // Retrieve the total number of items in the transfer and
+ // place on stack.
+ uint256 numItemsInTransfer = transferItems.length;
+
+ // Iterate over each item in the transfer to create a
+ // corresponding ConduitTransfer.
+ for (uint256 j = 0; j < numItemsInTransfer; ++j) {
+ // Retrieve the item from the transfer.
+ TransferHelperItem calldata item = transferItems[j];
+
+ if (item.itemType == ConduitItemType.ERC20) {
+ // Ensure that the identifier of an ERC20 token is 0.
+ if (item.identifier != 0) {
+ revert InvalidERC20Identifier();
+ }
+ }
+
+ // If the item is an ERC721 token and
+ // callERC721Receiver is true...
+ if (item.itemType == ConduitItemType.ERC721) {
+ if (callERC721Receiver) {
+ // Check if the recipient implements
+ // onERC721Received for the given tokenId.
+ _checkERC721Receiver(
+ conduit,
+ transfer.recipient,
+ item.identifier
+ );
+ }
+ }
+
+ // Create a ConduitTransfer corresponding to each
+ // TransferHelperItem.
+ conduitTransfers[itemIndex] = _createConduitTransfer(
+ item,
+ transfer
+ );
+
+ // Increment the index for storing ConduitTransfers.
+ ++itemIndex;
+ }
+ }
+ }
+ }
+
+ /**
+ * @notice Internal view function to create a ConduitTransfer from a
+ * TransferHelperItem and a TransferHelperItemsWithRecipient.
+ *
+ * @param item The item to transfer.
+ * @param transfer The transfer to create a ConduitTransfer from.
+ *
+ * @return conduitTransfer The ConduitTransfer created from the item and
+ * transfer.
+ */
+ function _createConduitTransfer(
+ TransferHelperItem calldata item,
+ TransferHelperItemsWithRecipient calldata transfer
+ ) internal view returns (ConduitTransfer memory conduitTransfer) {
+ return
+ ConduitTransfer(
+ item.itemType,
+ item.token,
+ msg.sender,
+ transfer.recipient,
+ item.identifier,
+ item.amount
+ );
+ }
+
/**
* @notice An internal function that reverts if the passed-in recipient
* is the zero address.
diff --git a/contracts/helpers/TransferHelperStructs.sol b/contracts/helpers/TransferHelperStructs.sol
deleted file mode 100644
index b58bee2c4..000000000
--- a/contracts/helpers/TransferHelperStructs.sol
+++ /dev/null
@@ -1,29 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import { ConduitItemType } from "../conduit/lib/ConduitEnums.sol";
-
-/**
- * @dev A TransferHelperItem specifies the itemType (ERC20/ERC721/ERC1155),
- * token address, token identifier, and amount of the token to be
- * transferred via the TransferHelper. For ERC20 tokens, identifier
- * must be 0. For ERC721 tokens, amount must be 1.
- */
-struct TransferHelperItem {
- ConduitItemType itemType;
- address token;
- uint256 identifier;
- uint256 amount;
-}
-
-/**
- * @dev A TransferHelperItemsWithRecipient specifies the tokens to transfer
- * via the TransferHelper, their intended recipient, and a boolean flag
- * indicating whether onERC721Received should be called on a recipient
- * contract.
- */
-struct TransferHelperItemsWithRecipient {
- TransferHelperItem[] items;
- address recipient;
- bool validateERC721Receiver;
-}
diff --git a/contracts/helpers/navigator/SeaportNavigator.sol b/contracts/helpers/navigator/SeaportNavigator.sol
new file mode 100644
index 000000000..c8aae71e9
--- /dev/null
+++ b/contracts/helpers/navigator/SeaportNavigator.sol
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+import {
+ SeaportValidatorInterface
+} from "../order-validator/SeaportValidator.sol";
+
+import { NavigatorContextLib } from "./lib/NavigatorContextLib.sol";
+
+import { CriteriaHelperLib } from "./lib/CriteriaHelperLib.sol";
+
+import {
+ NavigatorContext,
+ NavigatorRequest,
+ NavigatorResponse
+} from "./lib/SeaportNavigatorTypes.sol";
+
+import { SeaportNavigatorInterface } from "./lib/SeaportNavigatorInterface.sol";
+
+import { HelperInterface } from "./lib/HelperInterface.sol";
+
+/**
+ * @notice SeaportNavigator is a helper contract that generates additional
+ * information useful for fulfilling Seaport orders. Given an array of
+ * orders and external parameters like caller, recipient, and native
+ * tokens supplied, SeaportNavigator will validate the orders and
+ * return associated errors and warnings, recommend a fulfillment
+ * method, suggest fulfillments, provide execution and order details,
+ * and optionally generate criteria resolvers from provided token IDs.
+ */
+contract SeaportNavigator is SeaportNavigatorInterface {
+ using CriteriaHelperLib for uint256[];
+ using NavigatorContextLib for NavigatorContext;
+
+ HelperInterface public immutable criteriaHelper;
+ HelperInterface public immutable executionsHelper;
+ HelperInterface public immutable fulfillmentsHelper;
+ HelperInterface public immutable orderDetailsHelper;
+ HelperInterface public immutable requestValidator;
+ HelperInterface public immutable suggestedActionHelper;
+ HelperInterface public immutable validatorHelper;
+
+ HelperInterface[] public helpers;
+
+ constructor(
+ address _requestValidator,
+ address _criteriaHelper,
+ address _validatorHelper,
+ address _orderDetailsHelper,
+ address _fulfillmentsHelper,
+ address _suggestedActionHelper,
+ address _executionsHelper
+ ) {
+ requestValidator = HelperInterface(_requestValidator);
+ helpers.push(requestValidator);
+
+ criteriaHelper = HelperInterface(_criteriaHelper);
+ helpers.push(criteriaHelper);
+
+ validatorHelper = HelperInterface(_validatorHelper);
+ helpers.push(validatorHelper);
+
+ orderDetailsHelper = HelperInterface(_orderDetailsHelper);
+ helpers.push(orderDetailsHelper);
+
+ fulfillmentsHelper = HelperInterface(_fulfillmentsHelper);
+ helpers.push(fulfillmentsHelper);
+
+ suggestedActionHelper = HelperInterface(_suggestedActionHelper);
+ helpers.push(suggestedActionHelper);
+
+ executionsHelper = HelperInterface(_executionsHelper);
+ helpers.push(executionsHelper);
+ }
+
+ function prepare(
+ NavigatorRequest calldata request
+ ) public view returns (NavigatorResponse memory) {
+ NavigatorContext memory context = NavigatorContextLib
+ .from(request)
+ .withEmptyResponse();
+
+ for (uint256 i; i < helpers.length; i++) {
+ context = helpers[i].prepare(context);
+ }
+
+ return context.response;
+ }
+
+ /**
+ * @notice Generate a criteria merkle root from an array of `tokenIds`. Use
+ * this helper to construct an order item's `identifierOrCriteria`.
+ *
+ * @param tokenIds An array of integer token IDs to be converted to a merkle
+ * root.
+ *
+ * @return The bytes32 merkle root of a criteria tree containing the given
+ * token IDs.
+ */
+ function criteriaRoot(
+ uint256[] memory tokenIds
+ ) external pure returns (bytes32) {
+ return tokenIds.criteriaRoot();
+ }
+
+ /**
+ * @notice Generate a criteria merkle proof that `id` is a member of
+ * `tokenIds`. Reverts if `id` is not a member of `tokenIds`. Use
+ * this helper to construct proof data for criteria resolvers.
+ *
+ * @param tokenIds An array of integer token IDs.
+ * @param id The integer token ID to generate a proof for.
+ *
+ * @return Merkle proof that the given token ID is amember of the criteria
+ * tree containing the given token IDs.
+ */
+ function criteriaProof(
+ uint256[] memory tokenIds,
+ uint256 id
+ ) external pure returns (bytes32[] memory) {
+ return tokenIds.criteriaProof(id);
+ }
+}
diff --git a/contracts/helpers/navigator/lib/CriteriaHelper.sol b/contracts/helpers/navigator/lib/CriteriaHelper.sol
new file mode 100644
index 000000000..8cc64945a
--- /dev/null
+++ b/contracts/helpers/navigator/lib/CriteriaHelper.sol
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ NavigatorCriteriaResolverLib
+} from "./NavigatorCriteriaResolverLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { HelperInterface } from "./HelperInterface.sol";
+
+contract CriteriaHelper is HelperInterface {
+ using NavigatorCriteriaResolverLib for NavigatorContext;
+
+ function prepare(
+ NavigatorContext memory context
+ ) public pure returns (NavigatorContext memory) {
+ return context.withCriteria();
+ }
+}
diff --git a/contracts/helpers/navigator/lib/CriteriaHelperLib.sol b/contracts/helpers/navigator/lib/CriteriaHelperLib.sol
new file mode 100644
index 000000000..6cd661724
--- /dev/null
+++ b/contracts/helpers/navigator/lib/CriteriaHelperLib.sol
@@ -0,0 +1,167 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { MerkleLib } from "./MerkleLib.sol";
+
+error TokenIdNotFound();
+
+struct HashAndIntTuple {
+ uint256 num;
+ bytes32 hash;
+}
+
+/**
+ * @notice Helper library for calculating criteria resolver Merkle roots and
+ * proofs from integer token ids.
+ */
+library CriteriaHelperLib {
+ error CannotDeriveRootForSingleTokenId();
+ error CannotDeriveProofForSingleTokenId();
+
+ /**
+ * @notice Calculate the Merkle root of a criteria tree containing the given
+ * integer token ids.
+ */
+ function criteriaRoot(
+ uint256[] memory tokenIds
+ ) internal pure returns (bytes32) {
+ if (tokenIds.length == 0) {
+ return bytes32(0);
+ } else if (tokenIds.length == 1) {
+ revert CannotDeriveRootForSingleTokenId();
+ } else {
+ return
+ MerkleLib.getRoot(
+ toSortedHashes(tokenIds),
+ MerkleLib.merkleHash
+ );
+ }
+ }
+
+ /**
+ * @notice Calculate the Merkle proof that the given token id is a member of
+ * the criteria tree containing the provided tokenIds.
+ */
+ function criteriaProof(
+ uint256[] memory tokenIds,
+ uint256 id
+ ) internal pure returns (bytes32[] memory) {
+ if (tokenIds.length == 0) {
+ return new bytes32[](0);
+ } else if (tokenIds.length == 1) {
+ revert CannotDeriveProofForSingleTokenId();
+ } else {
+ bytes32 idHash = keccak256(abi.encode(id));
+ uint256 idx;
+ bool found;
+ bytes32[] memory idHashes = toSortedHashes(tokenIds);
+ for (; idx < idHashes.length; idx++) {
+ if (idHashes[idx] == idHash) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) revert TokenIdNotFound();
+ return MerkleLib.getProof(idHashes, idx, MerkleLib.merkleHash);
+ }
+ }
+
+ /**
+ * @notice Sort an array of integer token ids by their hashed values.
+ */
+ function sortByHash(
+ uint256[] memory tokenIds
+ ) internal pure returns (uint256[] memory sortedIds) {
+ // Instantiate a new array of HashAndIntTuple structs.
+ HashAndIntTuple[] memory toSort = new HashAndIntTuple[](
+ tokenIds.length
+ );
+
+ // Populate the array of HashAndIntTuple structs.
+ for (uint256 i = 0; i < tokenIds.length; i++) {
+ toSort[i] = HashAndIntTuple(
+ tokenIds[i],
+ keccak256(abi.encode(tokenIds[i]))
+ );
+ }
+
+ // Sort the array of HashAndIntTuple structs.
+ _quickSort(toSort, 0, int256(toSort.length - 1));
+
+ // Populate the sortedIds array with the sorted token ids.
+ sortedIds = new uint256[](tokenIds.length);
+ for (uint256 i = 0; i < tokenIds.length; i++) {
+ sortedIds[i] = toSort[i].num;
+ }
+ }
+
+ /**
+ * @notice Convert an array of integer token ids to a sorted array of
+ * their hashed values.
+ */
+ function toSortedHashes(
+ uint256[] memory tokenIds
+ ) internal pure returns (bytes32[] memory hashes) {
+ // Instantiate a new array of hashes.
+ hashes = new bytes32[](tokenIds.length);
+
+ // Sort the token ids by their hashes.
+ uint256[] memory ids = sortByHash(tokenIds);
+
+ // Hash each token id and store it in the hashes array.
+ for (uint256 i; i < ids.length; ++i) {
+ hashes[i] = keccak256(abi.encode(ids[i]));
+ }
+ }
+
+ /**
+ * @dev This function performs the quick sort algorithm to sort an array of
+ * HashAndIntTuple structs.
+ *
+ * @param arr The array of HashAndIntTuple structs to be sorted.
+ * @param left The starting index of the segment to be sorted.
+ * @param right The ending index of the segment to be sorted.
+ */
+ function _quickSort(
+ HashAndIntTuple[] memory arr,
+ int256 left,
+ int256 right
+ ) internal pure {
+ // Initialize pointers i and j to the left and right ends of the array
+ // segment.
+ int256 i = left;
+ int256 j = right;
+
+ // If the segment has one element or none, it's already sorted.
+ if (i == j) return;
+
+ // Pick a 'pivot' element from the middle of the list.
+ bytes32 pivot = arr[uint256(left + (right - left) / 2)].hash;
+
+ // The main loop to rearrange elements around the pivot.
+ while (i <= j) {
+ // Find an element larger than or equal to the pivot from the left.
+ while (arr[uint256(i)].hash < pivot) i++;
+
+ // Find an element smaller than or equal to the pivot from the
+ // right.
+ while (pivot < arr[uint256(j)].hash) j--;
+
+ // Swap the elements at i and j if needed.
+ if (i <= j) {
+ (arr[uint256(i)], arr[uint256(j)]) = (
+ arr[uint256(j)],
+ arr[uint256(i)]
+ );
+ i++;
+ j--;
+ }
+ }
+
+ // Recursively sort the segment before 'j'.
+ if (left < j) _quickSort(arr, left, j);
+
+ // Recursively sort the segment after 'i'.
+ if (i < right) _quickSort(arr, i, right);
+ }
+}
diff --git a/contracts/helpers/navigator/lib/ExecutionsHelper.sol b/contracts/helpers/navigator/lib/ExecutionsHelper.sol
new file mode 100644
index 000000000..cdfc88413
--- /dev/null
+++ b/contracts/helpers/navigator/lib/ExecutionsHelper.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { NavigatorExecutionsLib } from "./NavigatorExecutionsLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { HelperInterface } from "./HelperInterface.sol";
+
+contract ExecutionsHelper is HelperInterface {
+ using NavigatorExecutionsLib for NavigatorContext;
+
+ function prepare(
+ NavigatorContext memory context
+ ) public pure returns (NavigatorContext memory) {
+ return context.withExecutions();
+ }
+}
diff --git a/contracts/helpers/navigator/lib/FulfillmentsHelper.sol b/contracts/helpers/navigator/lib/FulfillmentsHelper.sol
new file mode 100644
index 000000000..0109cdeeb
--- /dev/null
+++ b/contracts/helpers/navigator/lib/FulfillmentsHelper.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { NavigatorFulfillmentsLib } from "./NavigatorFulfillmentsLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { HelperInterface } from "./HelperInterface.sol";
+
+contract FulfillmentsHelper is HelperInterface {
+ using NavigatorFulfillmentsLib for NavigatorContext;
+
+ function prepare(
+ NavigatorContext memory context
+ ) public pure returns (NavigatorContext memory) {
+ return context.withFulfillments();
+ }
+}
diff --git a/contracts/helpers/navigator/lib/HelperInterface.sol b/contracts/helpers/navigator/lib/HelperInterface.sol
new file mode 100644
index 000000000..34f4f8312
--- /dev/null
+++ b/contracts/helpers/navigator/lib/HelperInterface.sol
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+interface HelperInterface {
+ function prepare(
+ NavigatorContext memory context
+ ) external view returns (NavigatorContext memory);
+}
diff --git a/contracts/helpers/navigator/lib/HelperItemLib.sol b/contracts/helpers/navigator/lib/HelperItemLib.sol
new file mode 100644
index 000000000..c381856aa
--- /dev/null
+++ b/contracts/helpers/navigator/lib/HelperItemLib.sol
@@ -0,0 +1,194 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { ItemType } from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ NavigatorOfferItem,
+ NavigatorConsiderationItem
+} from "./SeaportNavigatorTypes.sol";
+
+library HelperItemLib {
+ error InvalidIdentifier(uint256 identifier, uint256[] candidateIdentifiers);
+ error InvalidItemTypeForCandidateIdentifiers();
+
+ /**
+ * @dev Internal error: Could not convert item type.
+ */
+ error UnknownItemType();
+
+ /**
+ * @dev Normalizes the type of a NavigatorOfferItem based on the presence of
+ * criteria. This originated in the context of the fuzz tests in
+ * ./test/foundry/new, where an item might be assigned a pseudorandom
+ * type and a pseudorandom criteria. In this context, it will just
+ * correct an incorrect item type. If the item has criteria, ERC721 and
+ * ERC1155 items will be normalized to ERC721_WITH_CRITERIA and
+ * ERC1155_WITH_CRITERIA, respectively. Reverts with UnknownItemType if
+ * the item type is neither ERC721, ERC721_WITH_CRITERIA, ERC1155, nor
+ * ERC1155_WITH_CRITERIA.
+ *
+ * @param item The NavigatorOfferItem to normalize.
+ *
+ * @return ItemType The normalized item type.
+ */
+ function normalizeType(
+ NavigatorOfferItem memory item
+ ) internal pure returns (ItemType) {
+ ItemType itemType = item.itemType;
+ if (hasCriteria(item)) {
+ if (
+ itemType == ItemType.ERC721 ||
+ itemType == ItemType.ERC721_WITH_CRITERIA
+ ) {
+ return ItemType.ERC721_WITH_CRITERIA;
+ } else if (
+ itemType == ItemType.ERC1155 ||
+ itemType == ItemType.ERC1155_WITH_CRITERIA
+ ) {
+ return ItemType.ERC1155_WITH_CRITERIA;
+ } else {
+ revert UnknownItemType();
+ }
+ } else {
+ return itemType;
+ }
+ }
+
+ /**
+ * @dev Normalizes the type of a NavigatorConsiderationItem based on the
+ * presence of criteria. This originated in the context of the fuzz
+ * tests in ./test/foundry/new, where an item might be assigned a
+ * pseudorandom type and a pseudorandom criteriaOrIdentifier. In this
+ * context, it will just correct an incorrect item type. If the item
+ * has criteria, ERC721 and ERC1155 items will be normalized to
+ * ERC721_WITH_CRITERIA and ERC1155_WITH_CRITERIA, respectively.
+ *
+ * @param item The NavigatorConsiderationItem to normalize.
+ *
+ * @return ItemType The normalized item type.
+ */
+ function normalizeType(
+ NavigatorConsiderationItem memory item
+ ) internal pure returns (ItemType) {
+ ItemType itemType = item.itemType;
+ if (hasCriteria(item)) {
+ if (
+ itemType == ItemType.ERC721 ||
+ itemType == ItemType.ERC721_WITH_CRITERIA
+ ) {
+ return ItemType.ERC721_WITH_CRITERIA;
+ } else if (
+ itemType == ItemType.ERC1155 ||
+ itemType == ItemType.ERC1155_WITH_CRITERIA
+ ) {
+ return ItemType.ERC1155_WITH_CRITERIA;
+ } else {
+ revert UnknownItemType();
+ }
+ } else {
+ return itemType;
+ }
+ }
+
+ function hasCriteria(
+ NavigatorOfferItem memory item
+ ) internal pure returns (bool) {
+ // Candidate identifiers are passed in by the caller as an array of
+ // uint256s and converted by Navigator.
+ return item.candidateIdentifiers.length > 0;
+ }
+
+ function hasCriteria(
+ NavigatorConsiderationItem memory item
+ ) internal pure returns (bool) {
+ // Candidate identifiers are passed in by the caller as an array of
+ // uint256s and converted by Navigator.
+ return item.candidateIdentifiers.length > 0;
+ }
+
+ function validate(NavigatorOfferItem memory item) internal pure {
+ ItemType itemType = item.itemType;
+
+ // If the item has criteria, the item type must be ERC721 or ERC1155.
+ if (itemType == ItemType.ERC20 || itemType == ItemType.NATIVE) {
+ if (hasCriteria(item)) {
+ revert InvalidItemTypeForCandidateIdentifiers();
+ } else {
+ return;
+ }
+ }
+
+ // If the item has no candidate identifiers, the item identifier must be
+ // non-zero.
+ //
+ // NOTE: This is only called after `item.hasCriteria()` checks
+ // which ensure that `item.candidateIdentifiers.length > 0` but if it
+ // were used in other contexts, this would prohibit the use of
+ // legitimate 0 identifiers.
+ if (item.candidateIdentifiers.length == 0 && item.identifier == 0) {
+ revert InvalidIdentifier(
+ item.identifier,
+ item.candidateIdentifiers
+ );
+ }
+
+ // If the item has candidate identifiers, the item identifier must be
+ // zero or wildcard for one of the candidates.
+ if (item.candidateIdentifiers.length > 0) {
+ bool identifierFound;
+ for (uint256 i; i < item.candidateIdentifiers.length; i++) {
+ if (item.candidateIdentifiers[i] == item.identifier) {
+ identifierFound = true;
+ break;
+ }
+ }
+ if (!identifierFound && item.identifier != 0) {
+ revert InvalidIdentifier(
+ item.identifier,
+ item.candidateIdentifiers
+ );
+ }
+ }
+ }
+
+ function validate(NavigatorConsiderationItem memory item) internal pure {
+ ItemType itemType = item.itemType;
+
+ // If the item has criteria, the item type must be ERC721 or ERC1155.
+ if (itemType == ItemType.ERC20 || itemType == ItemType.NATIVE) {
+ if (hasCriteria(item)) {
+ revert InvalidItemTypeForCandidateIdentifiers();
+ } else {
+ return;
+ }
+ }
+
+ // If the item has no candidate identifiers, the item identifier must be
+ // non-zero.
+ if (item.candidateIdentifiers.length == 0 && item.identifier == 0) {
+ revert InvalidIdentifier(
+ item.identifier,
+ item.candidateIdentifiers
+ );
+ }
+
+ // If the item has candidate identifiers, the item identifier must be
+ // zero or wildcard for one of the candidates.
+ if (hasCriteria(item)) {
+ bool identifierFound;
+ for (uint256 i; i < item.candidateIdentifiers.length; i++) {
+ if (item.candidateIdentifiers[i] == item.identifier) {
+ identifierFound = true;
+ break;
+ }
+ }
+ if (!identifierFound && item.identifier != 0) {
+ revert InvalidIdentifier(
+ item.identifier,
+ item.candidateIdentifiers
+ );
+ }
+ }
+ }
+}
diff --git a/contracts/helpers/navigator/lib/MerkleLib.sol b/contracts/helpers/navigator/lib/MerkleLib.sol
new file mode 100644
index 000000000..26a19edb3
--- /dev/null
+++ b/contracts/helpers/navigator/lib/MerkleLib.sol
@@ -0,0 +1,250 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+/**
+ * @notice A pure library for generating Merkle trees/proofs, adapted from
+ * Murky: https://github.com/dmfxyz/murky
+ */
+library MerkleLib {
+ /**
+ * @dev Computes the Merkle tree hash of two child nodes.
+ *
+ * @param left The hash of the left child node.
+ * @param right The hash of the right child node.
+ *
+ * @return _hash The Merkle tree hash of the two input hashes.
+ */
+ function merkleHash(
+ bytes32 left,
+ bytes32 right
+ ) internal pure returns (bytes32 _hash) {
+ assembly {
+ // Compare the left and right hash to order them lt(left, right)
+ // returns true if left is less than right
+ switch lt(left, right)
+ // If left is not less than right, switch the order.
+ case 0 {
+ mstore(0x0, right)
+ mstore(0x20, left)
+ }
+ // If left is less than right, keep the order.
+ default {
+ mstore(0x0, left)
+ mstore(0x20, right)
+ }
+
+ // Compute the keccak256 hash of the 64-byte input (two concatenated
+ // 32-byte hashes) The result is stored in '_hash'
+ _hash := keccak256(0x0, 0x40)
+ }
+ }
+
+ /**
+ * @dev Verifies a Merkle proof.
+ *
+ * @param root The root of the Merkle tree.
+ * @param proof An array containing the Merkle proof hashes.
+ * @param valueToProve The leaf node value to prove membership for.
+ * @param hashLeafPairs A function to hash pairs of leaf nodes.
+ *
+ * @return True if the proof is valid, otherwise false.
+ */
+ function verifyProof(
+ bytes32 root,
+ bytes32[] memory proof,
+ bytes32 valueToProve,
+ function(bytes32, bytes32) internal pure returns (bytes32) hashLeafPairs
+ ) internal pure returns (bool) {
+ // Proof length must be less than max array size.
+ bytes32 rollingHash = valueToProve;
+ uint256 length = proof.length;
+
+ // Loop through each proof element to compute the rolling hash.
+ unchecked {
+ for (uint i = 0; i < length; ++i) {
+ rollingHash = hashLeafPairs(rollingHash, proof[i]);
+ }
+ }
+
+ // The final rolling hash must equal the Merkle root for the proof to be
+ // valid
+ return root == rollingHash;
+ }
+
+ /**
+ * @dev Computes the Merkle root from an array of leaf node hashes.
+ *
+ * @param data An array containing the leaf node hashes.
+ * @param hashLeafPairs A function to hash pairs of leaf nodes.
+ *
+ * @return The Merkle root.
+ */
+ function getRoot(
+ bytes32[] memory data,
+ function(bytes32, bytes32) internal pure returns (bytes32) hashLeafPairs
+ ) internal pure returns (bytes32) {
+ require(data.length > 1, "won't generate root for single leaf");
+
+ // Loop until only the Merkle root remains.
+ while (data.length > 1) {
+ data = hashLevel(data, hashLeafPairs);
+ }
+
+ // Return the computed Merkle root.
+ return data[0];
+ }
+
+ function getProof(
+ bytes32[] memory data,
+ uint256 node,
+ function(bytes32, bytes32) internal pure returns (bytes32) hashLeafPairs
+ ) internal pure returns (bytes32[] memory) {
+ require(data.length > 1, "won't generate proof for single leaf");
+ // The size of the proof is equal to the ceiling of log2(numLeaves)
+ bytes32[] memory result = new bytes32[](log2ceilBitMagic(data.length));
+ uint256 pos = 0;
+
+ // Two overflow risks: node, pos
+ // node: max array size is 2**256-1. Largest index in the array will be 1 less than that. Also,
+ // for dynamic arrays, size is limited to 2**64-1
+ // pos: pos is bounded by log2(data.length), which should be less than type(uint256).max
+ while (data.length > 1) {
+ unchecked {
+ if (node & 0x1 == 1) {
+ result[pos] = data[node - 1];
+ } else if (node + 1 == data.length) {
+ result[pos] = bytes32(0);
+ } else {
+ result[pos] = data[node + 1];
+ }
+ ++pos;
+ node /= 2;
+ }
+ data = hashLevel(data, hashLeafPairs);
+ }
+ return result;
+ }
+
+ ///@dev function is private to prevent unsafe data from being passed
+ function hashLevel(
+ bytes32[] memory data,
+ function(bytes32, bytes32) internal pure returns (bytes32) hashLeafPairs
+ ) private pure returns (bytes32[] memory) {
+ bytes32[] memory result;
+
+ // Function is private, and all internal callers check that data.length >=2.
+ // Underflow is not possible as lowest possible value for data/result index is 1
+ // overflow should be safe as length is / 2 always.
+ unchecked {
+ uint256 length = data.length;
+ if (length & 0x1 == 1) {
+ result = new bytes32[](length / 2 + 1);
+ result[result.length - 1] = hashLeafPairs(
+ data[length - 1],
+ bytes32(0)
+ );
+ } else {
+ result = new bytes32[](length / 2);
+ }
+ // pos is upper bounded by data.length / 2, so safe even if array is at max size
+ uint256 pos = 0;
+ for (uint256 i = 0; i < length - 1; i += 2) {
+ result[pos] = hashLeafPairs(data[i], data[i + 1]);
+ ++pos;
+ }
+ }
+ return result;
+ }
+
+ /******************
+ * MATH "LIBRARY" *
+ ******************/
+
+ /// @dev Note that x is assumed > 0
+ function log2ceil(uint256 x) internal pure returns (uint256) {
+ uint256 ceil = 0;
+ uint pOf2;
+ // If x is a power of 2, then this function will return a ceiling
+ // that is 1 greater than the actual ceiling. So we need to check if
+ // x is a power of 2, and subtract one from ceil if so.
+ assembly {
+ // we check by seeing if x == (~x + 1) & x. This applies a mask
+ // to find the lowest set bit of x and then checks it for equality
+ // with x. If they are equal, then x is a power of 2.
+
+ /* Example
+ x has single bit set
+ x := 0000_1000
+ (~x + 1) = (1111_0111) + 1 = 1111_1000
+ (1111_1000 & 0000_1000) = 0000_1000 == x
+
+ x has multiple bits set
+ x := 1001_0010
+ (~x + 1) = (0110_1101 + 1) = 0110_1110
+ (0110_1110 & x) = 0000_0010 != x
+ */
+
+ // we do some assembly magic to treat the bool as an integer later on
+ pOf2 := eq(and(add(not(x), 1), x), x)
+ }
+
+ // if x == type(uint256).max, than ceil is capped at 256
+ // if x == 0, then pO2 == 0, so ceil won't underflow
+ unchecked {
+ while (x > 0) {
+ x >>= 1;
+ ceil++;
+ }
+ ceil -= pOf2; // see above
+ }
+ return ceil;
+ }
+
+ /// Original bitmagic adapted from https://github.com/paulrberg/prb-math/blob/main/contracts/PRBMath.sol
+ /// @dev Note that x assumed > 1
+ function log2ceilBitMagic(uint256 x) internal pure returns (uint256) {
+ if (x <= 1) {
+ return 0;
+ }
+ uint256 msb = 0;
+ uint256 _x = x;
+ if (x >= 2 ** 128) {
+ x >>= 128;
+ msb += 128;
+ }
+ if (x >= 2 ** 64) {
+ x >>= 64;
+ msb += 64;
+ }
+ if (x >= 2 ** 32) {
+ x >>= 32;
+ msb += 32;
+ }
+ if (x >= 2 ** 16) {
+ x >>= 16;
+ msb += 16;
+ }
+ if (x >= 2 ** 8) {
+ x >>= 8;
+ msb += 8;
+ }
+ if (x >= 2 ** 4) {
+ x >>= 4;
+ msb += 4;
+ }
+ if (x >= 2 ** 2) {
+ x >>= 2;
+ msb += 2;
+ }
+ if (x >= 2 ** 1) {
+ msb += 1;
+ }
+
+ uint256 lsb = (~_x + 1) & _x;
+ if ((lsb == _x) && (msb > 0)) {
+ return msb;
+ } else {
+ return msb + 1;
+ }
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorAdvancedOrderLib.sol b/contracts/helpers/navigator/lib/NavigatorAdvancedOrderLib.sol
new file mode 100644
index 000000000..548a07c84
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorAdvancedOrderLib.sol
@@ -0,0 +1,300 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ AdvancedOrder,
+ CriteriaResolver,
+ OfferItem,
+ ConsiderationItem,
+ OrderParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+import { CriteriaHelperLib } from "./CriteriaHelperLib.sol";
+
+import { HelperItemLib } from "./HelperItemLib.sol";
+
+import {
+ NavigatorAdvancedOrder,
+ NavigatorConsiderationItem,
+ NavigatorOfferItem,
+ NavigatorOrderParameters
+} from "./SeaportNavigatorTypes.sol";
+
+library NavigatorAdvancedOrderLib {
+ using CriteriaHelperLib for uint256[];
+ using HelperItemLib for NavigatorConsiderationItem;
+ using HelperItemLib for NavigatorOfferItem;
+
+ /*
+ * @dev Converts an array of AdvancedOrders to an array of
+ * NavigatorAdvancedOrders.
+ */
+ function fromAdvancedOrders(
+ AdvancedOrder[] memory orders
+ ) internal pure returns (NavigatorAdvancedOrder[] memory) {
+ NavigatorAdvancedOrder[]
+ memory helperOrders = new NavigatorAdvancedOrder[](orders.length);
+ for (uint256 i; i < orders.length; i++) {
+ helperOrders[i] = fromAdvancedOrder(orders[i]);
+ }
+ return helperOrders;
+ }
+
+ /*
+ * @dev Converts an AdvancedOrder to a NavigatorAdvancedOrder.
+ */
+ function fromAdvancedOrder(
+ AdvancedOrder memory order
+ ) internal pure returns (NavigatorAdvancedOrder memory) {
+ // Copy over the offer items.
+ NavigatorOfferItem[] memory offerItems = new NavigatorOfferItem[](
+ order.parameters.offer.length
+ );
+ for (uint256 i; i < order.parameters.offer.length; i++) {
+ OfferItem memory item = order.parameters.offer[i];
+ offerItems[i] = NavigatorOfferItem({
+ itemType: item.itemType,
+ token: item.token,
+ identifier: item.identifierOrCriteria,
+ startAmount: item.startAmount,
+ endAmount: item.endAmount,
+ candidateIdentifiers: new uint256[](0)
+ });
+ }
+
+ // Copy over the consideration items.
+ NavigatorConsiderationItem[]
+ memory considerationItems = new NavigatorConsiderationItem[](
+ order.parameters.consideration.length
+ );
+ for (uint256 i; i < order.parameters.consideration.length; i++) {
+ ConsiderationItem memory item = order.parameters.consideration[i];
+ considerationItems[i] = NavigatorConsiderationItem({
+ itemType: item.itemType,
+ token: item.token,
+ identifier: item.identifierOrCriteria,
+ startAmount: item.startAmount,
+ endAmount: item.endAmount,
+ recipient: item.recipient,
+ candidateIdentifiers: new uint256[](0)
+ });
+ }
+ return
+ NavigatorAdvancedOrder({
+ parameters: NavigatorOrderParameters({
+ offerer: order.parameters.offerer,
+ zone: order.parameters.zone,
+ offer: offerItems,
+ consideration: considerationItems,
+ orderType: order.parameters.orderType,
+ startTime: order.parameters.startTime,
+ endTime: order.parameters.endTime,
+ zoneHash: order.parameters.zoneHash,
+ salt: order.parameters.salt,
+ conduitKey: order.parameters.conduitKey,
+ totalOriginalConsiderationItems: order
+ .parameters
+ .totalOriginalConsiderationItems
+ }),
+ numerator: order.numerator,
+ denominator: order.denominator,
+ signature: order.signature,
+ extraData: order.extraData
+ });
+ }
+
+ /*
+ * @dev Converts an array of NavigatorAdvancedOrders to an array of
+ * AdvancedOrders and an array of CriteriaResolvers.
+ */
+ function toAdvancedOrder(
+ NavigatorAdvancedOrder memory order,
+ uint256 orderIndex
+ ) internal pure returns (AdvancedOrder memory, CriteriaResolver[] memory) {
+ // Create an array of CriteriaResolvers to be populated in the for loop
+ // below. It might be longer than it needs to be, but it gets trimmed in
+ // the assembly block below.
+ CriteriaResolver[] memory criteriaResolvers = new CriteriaResolver[](
+ order.parameters.offer.length +
+ order.parameters.consideration.length
+ );
+ uint256 criteriaResolverLen;
+
+ // Copy over the offer items, converting candidate identifiers to a
+ // criteria root if necessary and populating the criteria resolvers
+ // array.
+ OfferItem[] memory offer = new OfferItem[](
+ order.parameters.offer.length
+ );
+ for (uint256 i; i < order.parameters.offer.length; i++) {
+ NavigatorOfferItem memory item = order.parameters.offer[i];
+ if (item.hasCriteria()) {
+ item.validate();
+ offer[i] = OfferItem({
+ itemType: item.normalizeType(),
+ token: item.token,
+ identifierOrCriteria: uint256(
+ item.candidateIdentifiers.criteriaRoot()
+ ),
+ startAmount: item.startAmount,
+ endAmount: item.endAmount
+ });
+ criteriaResolvers[criteriaResolverLen] = CriteriaResolver({
+ orderIndex: orderIndex,
+ side: Side.OFFER,
+ index: i,
+ identifier: item.identifier,
+ criteriaProof: item.candidateIdentifiers.criteriaProof(
+ item.identifier
+ )
+ });
+ criteriaResolverLen++;
+ } else {
+ offer[i] = OfferItem({
+ itemType: item.itemType,
+ token: item.token,
+ identifierOrCriteria: item.identifier,
+ startAmount: item.startAmount,
+ endAmount: item.endAmount
+ });
+ }
+ }
+
+ // Copy over the consideration items, converting candidate identifiers
+ // to a criteria root if necessary and populating the criteria resolvers
+ // array.
+ ConsiderationItem[] memory consideration = new ConsiderationItem[](
+ order.parameters.consideration.length
+ );
+ for (uint256 i; i < order.parameters.consideration.length; i++) {
+ NavigatorConsiderationItem memory item = order
+ .parameters
+ .consideration[i];
+ if (item.hasCriteria()) {
+ item.validate();
+ consideration[i] = ConsiderationItem({
+ itemType: item.normalizeType(),
+ token: item.token,
+ identifierOrCriteria: uint256(
+ item.candidateIdentifiers.criteriaRoot()
+ ),
+ startAmount: item.startAmount,
+ endAmount: item.endAmount,
+ recipient: item.recipient
+ });
+ criteriaResolvers[criteriaResolverLen] = CriteriaResolver({
+ orderIndex: orderIndex,
+ side: Side.CONSIDERATION,
+ index: i,
+ identifier: item.identifier,
+ criteriaProof: item.candidateIdentifiers.criteriaProof(
+ item.identifier
+ )
+ });
+ criteriaResolverLen++;
+ } else {
+ consideration[i] = ConsiderationItem({
+ itemType: item.itemType,
+ token: item.token,
+ identifierOrCriteria: item.identifier,
+ startAmount: item.startAmount,
+ endAmount: item.endAmount,
+ recipient: item.recipient
+ });
+ }
+ }
+
+ // This just encodes the length of the array that we gradually built up
+ // above. It's just a way of creating an array of arbitrary length. It's
+ // initialized to its longest possible length at the top, then populated
+ // partially or fully in the for loop above. Finally, the length is set
+ // here surgically.
+ assembly {
+ mstore(criteriaResolvers, criteriaResolverLen)
+ }
+
+ return (
+ AdvancedOrder({
+ parameters: OrderParameters({
+ offerer: order.parameters.offerer,
+ zone: order.parameters.zone,
+ offer: offer,
+ consideration: consideration,
+ orderType: order.parameters.orderType,
+ startTime: order.parameters.startTime,
+ endTime: order.parameters.endTime,
+ zoneHash: order.parameters.zoneHash,
+ salt: order.parameters.salt,
+ conduitKey: order.parameters.conduitKey,
+ totalOriginalConsiderationItems: order
+ .parameters
+ .totalOriginalConsiderationItems
+ }),
+ numerator: order.numerator,
+ denominator: order.denominator,
+ signature: order.signature,
+ extraData: order.extraData
+ }),
+ criteriaResolvers
+ );
+ }
+
+ /*
+ * @dev Converts an array of NavigatorAdvancedOrders to an array of
+ * AdvancedOrders and an array of CriteriaResolvers.
+ */
+ function toAdvancedOrders(
+ NavigatorAdvancedOrder[] memory orders
+ )
+ internal
+ pure
+ returns (AdvancedOrder[] memory, CriteriaResolver[] memory)
+ {
+ // Create an array of AdvancedOrders to be populated in the for loop
+ // below.
+ AdvancedOrder[] memory advancedOrders = new AdvancedOrder[](
+ orders.length
+ );
+
+ // Create an array of CriteriaResolvers to be populated in the for loop
+ // below. It might be longer than it needs to be, but it gets trimmed in
+ // the assembly block below.
+ uint256 maxCriteriaResolvers;
+ for (uint256 i; i < orders.length; i++) {
+ NavigatorOrderParameters memory parameters = orders[i].parameters;
+ maxCriteriaResolvers += (parameters.offer.length +
+ parameters.consideration.length);
+ }
+ uint256 criteriaResolverIndex;
+ CriteriaResolver[] memory criteriaResolvers = new CriteriaResolver[](
+ maxCriteriaResolvers
+ );
+
+ // Copy over the NavigatorAdvancedOrder[] orders to the AdvancedOrder[]
+ // array, converting and populating the criteria resolvers array.
+ for (uint256 i = 0; i < orders.length; i++) {
+ (
+ AdvancedOrder memory order,
+ CriteriaResolver[] memory orderResolvers
+ ) = toAdvancedOrder(orders[i], i);
+ advancedOrders[i] = order;
+ for (uint256 j; j < orderResolvers.length; j++) {
+ criteriaResolvers[criteriaResolverIndex] = orderResolvers[j];
+ criteriaResolverIndex++;
+ }
+ }
+
+ // This just encodes the length of the array that we gradually built up
+ // above. It's just a way of creating an array of arbitrary length. It's
+ // initialized to its longest possible length at the top, then populated
+ // partially or fully in the for loop above. Finally, the length is set
+ // here surgically.
+ assembly {
+ mstore(criteriaResolvers, criteriaResolverIndex)
+ }
+
+ return (advancedOrders, criteriaResolvers);
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorContextLib.sol b/contracts/helpers/navigator/lib/NavigatorContextLib.sol
new file mode 100644
index 000000000..5b0fd351c
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorContextLib.sol
@@ -0,0 +1,64 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ MatchComponent
+} from "seaport-sol/src/lib/types/MatchComponentType.sol";
+
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
+
+import {
+ AdvancedOrder,
+ CriteriaResolver,
+ Execution,
+ Fulfillment,
+ FulfillmentComponent
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ NavigatorContext,
+ NavigatorRequest,
+ NavigatorResponse
+} from "./SeaportNavigatorTypes.sol";
+
+import { ErrorsAndWarnings } from "../../order-validator/SeaportValidator.sol";
+
+library NavigatorContextLib {
+ /**
+ * @dev Creates a new NavigatorContext from a NavigatorRequest, which just
+ * means slotting the request into the context's request field and
+ * ignoring the response field.
+ */
+ function from(
+ NavigatorRequest memory request
+ ) internal pure returns (NavigatorContext memory context) {
+ context.request = request;
+ }
+
+ /**
+ * @dev Adds an empty response to the context.
+ */
+ function withEmptyResponse(
+ NavigatorContext memory context
+ ) internal pure returns (NavigatorContext memory) {
+ context.response = NavigatorResponse({
+ orders: new AdvancedOrder[](0),
+ criteriaResolvers: new CriteriaResolver[](0),
+ suggestedActionName: "",
+ suggestedCallData: hex"",
+ validationErrors: new ErrorsAndWarnings[](0),
+ orderDetails: new OrderDetails[](0),
+ offerFulfillments: new FulfillmentComponent[][](0),
+ considerationFulfillments: new FulfillmentComponent[][](0),
+ fulfillments: new Fulfillment[](0),
+ unspentOfferComponents: new MatchComponent[](0),
+ unmetConsiderationComponents: new MatchComponent[](0),
+ explicitExecutions: new Execution[](0),
+ implicitExecutions: new Execution[](0),
+ implicitExecutionsPre: new Execution[](0),
+ implicitExecutionsPost: new Execution[](0),
+ nativeTokensReturned: 0
+ });
+ return context;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorCriteriaResolverLib.sol b/contracts/helpers/navigator/lib/NavigatorCriteriaResolverLib.sol
new file mode 100644
index 000000000..4198760aa
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorCriteriaResolverLib.sol
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ AdvancedOrder,
+ CriteriaResolver
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ NavigatorAdvancedOrder,
+ NavigatorContext
+} from "./SeaportNavigatorTypes.sol";
+
+import { NavigatorAdvancedOrderLib } from "./NavigatorAdvancedOrderLib.sol";
+
+library NavigatorCriteriaResolverLib {
+ using NavigatorAdvancedOrderLib for NavigatorAdvancedOrder[];
+
+ /**
+ * @dev Calculate criteria resolvers, merkle proofs, and criteria merkle
+ * roots for the provided orders and criteria constraints. Modifies
+ * orders in place to add criteria merkle roots to the appropriate
+ * offer/consdieration items. Adds calculated criteria resolvers to
+ * the NavigatorResponse.
+ */
+ function withCriteria(
+ NavigatorContext memory context
+ ) internal pure returns (NavigatorContext memory) {
+ (
+ AdvancedOrder[] memory orders,
+ CriteriaResolver[] memory resolvers
+ ) = context.request.orders.toAdvancedOrders();
+ context.response.orders = orders;
+ if (context.request.criteriaResolvers.length > 0) {
+ context.response.criteriaResolvers = context
+ .request
+ .criteriaResolvers;
+ return context;
+ } else {
+ context.response.criteriaResolvers = resolvers;
+ return context;
+ }
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorDetailsLib.sol b/contracts/helpers/navigator/lib/NavigatorDetailsLib.sol
new file mode 100644
index 000000000..9d05155d1
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorDetailsLib.sol
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
+
+import { AdvancedOrder } from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { AdvancedOrderLib } from "seaport-sol/src/lib/AdvancedOrderLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { OrderAvailabilityLib } from "./OrderAvailabilityLib.sol";
+
+library NavigatorDetailsLib {
+ using AdvancedOrderLib for AdvancedOrder[];
+ using OrderAvailabilityLib for AdvancedOrder[];
+
+ /**
+ * @dev Calculate OrderDetails for each order and add them to the NavigatorResponse.
+ */
+ function withDetails(
+ NavigatorContext memory context
+ ) internal view returns (NavigatorContext memory) {
+ UnavailableReason[] memory unavailableReasons = context
+ .response
+ .orders
+ .unavailableReasons(
+ context.request.maximumFulfilled,
+ context.request.seaport
+ );
+ bytes32[] memory orderHashes = context.response.orders.getOrderHashes(
+ address(context.request.seaport)
+ );
+ context.response.orderDetails = context.response.orders.getOrderDetails(
+ context.response.criteriaResolvers,
+ orderHashes,
+ unavailableReasons
+ );
+ return context;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorExecutionsLib.sol b/contracts/helpers/navigator/lib/NavigatorExecutionsLib.sol
new file mode 100644
index 000000000..72b8c0123
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorExecutionsLib.sol
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+import { Execution } from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ FulfillmentDetails
+} from "seaport-sol/src/fulfillments/lib/Structs.sol";
+
+import {
+ ExecutionHelper
+} from "seaport-sol/src/executions/ExecutionHelper.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+library NavigatorExecutionsLib {
+ using ExecutionHelper for FulfillmentDetails;
+
+ /**
+ * @dev Internal error: Could not select a fulfillment method for the provided
+ * orders.
+ */
+ error UnknownAction();
+
+ /**
+ * @dev Calculate executions for the provided orders and add them to the
+ * NavigatorResponse.
+ */
+ function withExecutions(
+ NavigatorContext memory context
+ ) internal pure returns (NavigatorContext memory) {
+ // Extract the suggested action from the response.
+ bytes memory callData = context.response.suggestedCallData;
+ bytes4 _suggestedAction = bytes4(callData);
+
+ // Create a struct to hold details necessary for fulfillment, populated
+ // from the context.
+ FulfillmentDetails memory fulfillmentDetails = FulfillmentDetails({
+ orders: context.response.orderDetails,
+ recipient: payable(context.request.recipient),
+ fulfiller: payable(context.request.caller),
+ nativeTokensSupplied: context.request.nativeTokensSupplied,
+ fulfillerConduitKey: context.request.fulfillerConduitKey,
+ seaport: address(context.request.seaport)
+ });
+
+ // Initialize the execution arrays.
+ Execution[] memory explicitExecutions;
+ Execution[] memory implicitExecutions;
+ Execution[] memory implicitExecutionsPre;
+ Execution[] memory implicitExecutionsPost;
+ uint256 nativeTokensReturned;
+
+ // Call the appropriate method on the FulfillmentDetails struct to get
+ // the executions.
+ if (
+ _suggestedAction ==
+ ConsiderationInterface.fulfillAvailableOrders.selector ||
+ _suggestedAction ==
+ ConsiderationInterface.fulfillAvailableAdvancedOrders.selector
+ ) {
+ (
+ explicitExecutions,
+ implicitExecutionsPre,
+ implicitExecutionsPost,
+ nativeTokensReturned
+ ) = fulfillmentDetails.getFulfillAvailableExecutions(
+ context.response.offerFulfillments,
+ context.response.considerationFulfillments,
+ context.response.orderDetails
+ );
+ } else if (
+ _suggestedAction == ConsiderationInterface.matchOrders.selector ||
+ _suggestedAction ==
+ ConsiderationInterface.matchAdvancedOrders.selector
+ ) {
+ (
+ explicitExecutions,
+ implicitExecutionsPre,
+ implicitExecutionsPost,
+ nativeTokensReturned
+ ) = fulfillmentDetails.getMatchExecutions(
+ context.response.fulfillments
+ );
+ } else if (
+ _suggestedAction == ConsiderationInterface.fulfillOrder.selector ||
+ _suggestedAction ==
+ ConsiderationInterface.fulfillAdvancedOrder.selector
+ ) {
+ (implicitExecutions, nativeTokensReturned) = fulfillmentDetails
+ .getStandardExecutions();
+ } else if (
+ _suggestedAction ==
+ ConsiderationInterface.fulfillBasicOrder.selector ||
+ _suggestedAction ==
+ ConsiderationInterface.fulfillBasicOrder_efficient_6GL6yc.selector
+ ) {
+ (implicitExecutions, nativeTokensReturned) = fulfillmentDetails
+ .getBasicExecutions();
+ } else {
+ revert UnknownAction();
+ }
+
+ // Add the executions to the response.
+ context.response.explicitExecutions = explicitExecutions;
+ context.response.implicitExecutions = implicitExecutions;
+ context.response.implicitExecutionsPre = implicitExecutionsPre;
+ context.response.implicitExecutionsPost = implicitExecutionsPost;
+ context.response.nativeTokensReturned = nativeTokensReturned;
+ return context;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorFulfillmentsLib.sol b/contracts/helpers/navigator/lib/NavigatorFulfillmentsLib.sol
new file mode 100644
index 000000000..1cc18a603
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorFulfillmentsLib.sol
@@ -0,0 +1,51 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { Fulfillment } from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ FulfillmentGeneratorLib
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
+
+import {
+ FulfillmentComponent,
+ MatchComponent,
+ OrderDetails
+} from "seaport-sol/src/fulfillments/lib/Structs.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+library NavigatorFulfillmentsLib {
+ using FulfillmentGeneratorLib for OrderDetails[];
+
+ /**
+ * @dev Calculate fulfillments and match components for the provided orders
+ * and add them to the NavigatorResponse.
+ */
+ function withFulfillments(
+ NavigatorContext memory context
+ ) internal pure returns (NavigatorContext memory) {
+ (
+ ,
+ FulfillmentComponent[][] memory offerFulfillments,
+ FulfillmentComponent[][] memory considerationFulfillments,
+ Fulfillment[] memory fulfillments,
+ MatchComponent[] memory unspentOfferComponents,
+ MatchComponent[] memory unmetConsiderationComponents
+ ) = context.response.orderDetails.getFulfillments(
+ context.request.fulfillmentStrategy,
+ context.request.recipient,
+ context.request.caller,
+ context.request.seed
+ );
+
+ context.response.offerFulfillments = offerFulfillments;
+ context.response.considerationFulfillments = considerationFulfillments;
+ context.response.fulfillments = fulfillments;
+ context.response.unspentOfferComponents = unspentOfferComponents;
+ context
+ .response
+ .unmetConsiderationComponents = unmetConsiderationComponents;
+ return context;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorRequestValidatorLib.sol b/contracts/helpers/navigator/lib/NavigatorRequestValidatorLib.sol
new file mode 100644
index 000000000..60b192029
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorRequestValidatorLib.sol
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { AdvancedOrder } from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { Type, OrderStructureLib } from "./OrderStructureLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+library NavigatorRequestValidatorLib {
+ using OrderStructureLib for AdvancedOrder;
+
+ /**
+ * @dev Bad request error: provided orders include at least one contract order.
+ * The order helper does not currently support contract orders.
+ */
+ error ContractOrdersNotSupported();
+
+ /**
+ * @dev Validate the provided orders. Checks that none of the provided orders
+ * are contract orders and applies basic criteria constraint validations.
+ */
+ function validate(
+ NavigatorContext memory context
+ ) internal pure returns (NavigatorContext memory) {
+ validateNoContractOrders(context);
+ return context;
+ }
+
+ /**
+ * @dev Checks that none of the provided orders are contract orders.
+ */
+ function validateNoContractOrders(
+ NavigatorContext memory context
+ ) internal pure returns (NavigatorContext memory) {
+ for (uint256 i; i < context.response.orders.length; i++) {
+ AdvancedOrder memory order = context.response.orders[i];
+ if (order.getType() == Type.CONTRACT) {
+ revert ContractOrdersNotSupported();
+ }
+ }
+ return context;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorSeaportValidatorLib.sol b/contracts/helpers/navigator/lib/NavigatorSeaportValidatorLib.sol
new file mode 100644
index 000000000..bb8b47597
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorSeaportValidatorLib.sol
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { AdvancedOrder } from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { AdvancedOrderLib } from "seaport-sol/src/lib/AdvancedOrderLib.sol";
+
+import { ErrorsAndWarnings } from "../../order-validator/SeaportValidator.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+library NavigatorSeaportValidatorLib {
+ using AdvancedOrderLib for AdvancedOrder;
+
+ /**
+ * @dev Validate each order using SeaportValidator and add the results to
+ * the NavigatorResponse.
+ */
+ function withErrors(
+ NavigatorContext memory context
+ ) internal view returns (NavigatorContext memory) {
+ AdvancedOrder[] memory orders = context.response.orders;
+
+ ErrorsAndWarnings[] memory errors = new ErrorsAndWarnings[](
+ orders.length
+ );
+ for (uint256 i; i < orders.length; i++) {
+ errors[i] = context.request.validator.isValidOrder(
+ orders[i].toOrder(),
+ address(context.request.seaport)
+ );
+ }
+ context.response.validationErrors = errors;
+ return context;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/NavigatorSuggestedActionLib.sol b/contracts/helpers/navigator/lib/NavigatorSuggestedActionLib.sol
new file mode 100644
index 000000000..56d3c6a2b
--- /dev/null
+++ b/contracts/helpers/navigator/lib/NavigatorSuggestedActionLib.sol
@@ -0,0 +1,434 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+import {
+ AdvancedOrder,
+ ReceivedItem,
+ SpentItem
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
+
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
+
+import { AdvancedOrderLib } from "seaport-sol/src/lib/AdvancedOrderLib.sol";
+
+import { Family, OrderStructureLib, Structure } from "./OrderStructureLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+library NavigatorSuggestedActionLib {
+ using AdvancedOrderLib for AdvancedOrder;
+ using AdvancedOrderLib for AdvancedOrder[];
+ using OrderStructureLib for AdvancedOrder;
+ using OrderStructureLib for AdvancedOrder[];
+
+ /**
+ * @dev Bad request error: provided orders cannot be fulfilled.
+ */
+ error CannotFulfillProvidedCombinedOrder();
+
+ /**
+ * @dev Bad request error: provided orders include an invalid combination of
+ * native tokens and unavailable orders.
+ */
+ error InvalidNativeTokenUnavailableCombination();
+
+ /**
+ * @dev Internal error: Could not find selector for the suggested action.
+ */
+ error UnknownSelector();
+
+ /**
+ * @dev Choose a suggested fulfillment method based on the structure of the
+ * orders and add it to the NavigatorResponse.
+ */
+ function withSuggestedAction(
+ NavigatorContext memory context
+ ) internal view returns (NavigatorContext memory) {
+ bytes memory callData = suggestedCallData(context);
+ bytes4 selector = bytes4(callData);
+ context.response.suggestedActionName = actionName(selector);
+ context.response.suggestedCallData = callData;
+ return context;
+ }
+
+ /**
+ * @dev Add the human-readable name of the selected fulfillment method to
+ * the NavigatorResponse.
+ */
+ function actionName(bytes4 selector) internal pure returns (string memory) {
+ if (selector == 0xe7acab24) return "fulfillAdvancedOrder";
+ if (selector == 0x87201b41) return "fulfillAvailableAdvancedOrders";
+ if (selector == 0xed98a574) return "fulfillAvailableOrders";
+ if (selector == 0xfb0f3ee1) return "fulfillBasicOrder";
+ if (selector == 0x00000000) return "fulfillBasicOrder_efficient_6GL6yc";
+ if (selector == 0xb3a34c4c) return "fulfillOrder";
+ if (selector == 0xf2d12b12) return "matchAdvancedOrders";
+ if (selector == 0xa8174404) return "matchOrders";
+
+ revert UnknownSelector();
+ }
+
+ /**
+ * @dev Choose a suggested fulfillment method based on the structure of the
+ * orders.
+ */
+ function suggestedCallData(
+ NavigatorContext memory context
+ ) internal view returns (bytes memory) {
+ // Get the family of the orders (single or combined).
+ Family family = context.response.orders.getFamily();
+
+ // `mustUseMatch` returns true if the orders require the use of one of
+ // the match* methods. `mustUseMatch` checks for two things: 1) the
+ // presence of a native token in the offer of one of the orders, and 2)
+ // the presence of an ERC721 in the offer of one of the orders that is
+ // also in the consideration of another order. So,
+ // `containsOrderThatDemandsMatch` means that there's an offer item that
+ // can't be part of a standing order.
+ bool containsOrderThatDemandsMatch = mustUseMatch(context);
+
+ // Get the structure of the orders (basic, standard, or advanced).
+ Structure structure = context.response.orders.getStructure(
+ address(context.request.seaport)
+ );
+
+ bool contextHasExcessOrders = context.response.orders.length >
+ context.request.maximumFulfilled;
+
+ bool contextHasUnavailableOrders;
+
+ // Iterate through the orders and check if any of the orders has an
+ // unavailable reason.
+ for (uint256 i = 0; i < context.response.orderDetails.length; ++i) {
+ if (
+ context.response.orderDetails[i].unavailableReason !=
+ UnavailableReason.AVAILABLE
+ ) {
+ contextHasUnavailableOrders = true;
+ break;
+ }
+ }
+
+ // The match* methods are only an option if everything is going to find
+ // a partner (the first half of the if statement below) and if there are
+ // no unavailable orders (the second half of the if statement below).
+ bool cannotMatch = (context
+ .response
+ .unmetConsiderationComponents
+ .length !=
+ 0 ||
+ contextHasExcessOrders);
+
+ bool contextHasExcessOrUnavailableOrders = contextHasExcessOrders ||
+ contextHasUnavailableOrders;
+
+ // If there are excess or unavailable orders, follow this branch.
+ if (contextHasExcessOrUnavailableOrders) {
+ // If there are excess or unavailable orders and the orders could
+ // only be fulfilled using match*, it's a no-go, because every order
+ // must find a partner in the match* methods.
+ if (containsOrderThatDemandsMatch) {
+ revert InvalidNativeTokenUnavailableCombination();
+ }
+
+ // If there are excess or unavailable orders and the orders are
+ // advanced, use fulfillAvailableAdvancedOrders.
+ if (structure == Structure.ADVANCED) {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.fulfillAvailableAdvancedOrders,
+ (
+ context.response.orders,
+ context.response.criteriaResolvers,
+ context.response.offerFulfillments,
+ context.response.considerationFulfillments,
+ context.request.fulfillerConduitKey,
+ context.request.recipient,
+ context.request.maximumFulfilled
+ )
+ );
+ } else {
+ // If there are excess or unavailable orders and the orders are
+ // not advanced, use fulfillAvailableOrders.
+ return
+ abi.encodeCall(
+ ConsiderationInterface.fulfillAvailableOrders,
+ (
+ context.response.orders.toOrders(),
+ context.response.offerFulfillments,
+ context.response.considerationFulfillments,
+ context.request.fulfillerConduitKey,
+ context.request.maximumFulfilled
+ )
+ );
+ }
+ }
+
+ // If there are no excess or unavailable orders, follow this branch.
+
+ // If the order family is single (just one being fulfilled) and it
+ // doesn't require using match*, use the appropriate fulfill* method.
+ if (family == Family.SINGLE && !containsOrderThatDemandsMatch) {
+ // If the order structure is basic, use
+ // fulfillBasicOrder_efficient_6GL6yc for maximum gas efficiency.
+ if (structure == Structure.BASIC) {
+ AdvancedOrder memory order = context.response.orders[0];
+ return
+ abi.encodeCall(
+ ConsiderationInterface
+ .fulfillBasicOrder_efficient_6GL6yc,
+ (
+ order.toBasicOrderParameters(
+ order.getBasicOrderType()
+ )
+ )
+ );
+ }
+
+ // If the order structure is standard, use fulfillOrder.
+ if (structure == Structure.STANDARD) {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.fulfillOrder,
+ (
+ context.response.orders[0].toOrder(),
+ context.request.fulfillerConduitKey
+ )
+ );
+ }
+
+ // If the order structure is advanced, use fulfillAdvancedOrder.
+ if (structure == Structure.ADVANCED) {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.fulfillAdvancedOrder,
+ (
+ context.response.orders[0],
+ context.response.criteriaResolvers,
+ context.request.fulfillerConduitKey,
+ context.request.recipient
+ )
+ );
+ }
+ }
+
+ // This is like saying "if it's not possible to use match* but it's
+ // mandatory to use match*, revert."
+ if (cannotMatch && containsOrderThatDemandsMatch) {
+ revert CannotFulfillProvidedCombinedOrder();
+ }
+
+ // If it's not possible to use match*, use fulfillAvailable*.
+ if (cannotMatch) {
+ if (structure == Structure.ADVANCED) {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.fulfillAvailableAdvancedOrders,
+ (
+ context.response.orders,
+ context.response.criteriaResolvers,
+ context.response.offerFulfillments,
+ context.response.considerationFulfillments,
+ context.request.fulfillerConduitKey,
+ context.request.recipient,
+ context.request.maximumFulfilled
+ )
+ );
+ } else {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.fulfillAvailableOrders,
+ (
+ context.response.orders.toOrders(),
+ context.response.offerFulfillments,
+ context.response.considerationFulfillments,
+ context.request.fulfillerConduitKey,
+ context.request.maximumFulfilled
+ )
+ );
+ }
+ } else if (containsOrderThatDemandsMatch) {
+ // Here, matching is an option and "containsOrderThatDemandsMatch"
+ // means that match is mandatory, so pick the appropriate match*
+ // method based on structure.
+ if (structure == Structure.ADVANCED) {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.matchAdvancedOrders,
+ (
+ context.response.orders,
+ context.response.criteriaResolvers,
+ context.response.fulfillments,
+ context.request.recipient
+ )
+ );
+ } else {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.matchOrders,
+ (
+ context.response.orders.toOrders(),
+ context.response.fulfillments
+ )
+ );
+ }
+ } else {
+ // If match* is an option and there are no excess or unavailable
+ // offer items, follow this branch.
+ //
+ // If the structure is advanced, use matchAdvancedOrders or use
+ // fulfillAvailableAdvancedOrders depending on the caller's
+ // preference.
+ if (structure == Structure.ADVANCED) {
+ if (context.request.preferMatch) {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.matchAdvancedOrders,
+ (
+ context.response.orders,
+ context.response.criteriaResolvers,
+ context.response.fulfillments,
+ context.request.recipient
+ )
+ );
+ } else {
+ return
+ abi.encodeCall(
+ ConsiderationInterface
+ .fulfillAvailableAdvancedOrders,
+ (
+ context.response.orders,
+ context.response.criteriaResolvers,
+ context.response.offerFulfillments,
+ context.response.considerationFulfillments,
+ context.request.fulfillerConduitKey,
+ context.request.recipient,
+ context.request.maximumFulfilled
+ )
+ );
+ }
+ } else {
+ // If the structure is not advanced, use matchOrders or
+ // fulfillAvailableOrders depending on the caller's preference.
+ if (context.request.preferMatch) {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.matchOrders,
+ (
+ context.response.orders.toOrders(),
+ context.response.fulfillments
+ )
+ );
+ } else {
+ return
+ abi.encodeCall(
+ ConsiderationInterface.fulfillAvailableOrders,
+ (
+ context.response.orders.toOrders(),
+ context.response.offerFulfillments,
+ context.response.considerationFulfillments,
+ context.request.fulfillerConduitKey,
+ context.request.maximumFulfilled
+ )
+ );
+ }
+ }
+ }
+ }
+
+ /**
+ * @dev Return whether the provided orders must be matched using matchOrders
+ * or matchAdvancedOrders.
+ */
+ function mustUseMatch(
+ NavigatorContext memory context
+ ) internal pure returns (bool) {
+ OrderDetails[] memory orders = context.response.orderDetails;
+
+ // Iterate through the orders and check if any of the non-contract
+ // orders has a native token in the offer.
+ for (uint256 i = 0; i < orders.length; ++i) {
+ OrderDetails memory order = orders[i];
+
+ // Skip contract orders.
+ if (order.isContract) {
+ continue;
+ }
+
+ // If the order has a native token in the offer, must use match. If
+ // an order is being passed in that has a native token on the offer
+ // side, then all the fulfill* methods are ruled out, because it's
+ // not possible to create a standing order that offers ETH (WETH
+ // would be required). If an order with native tokens is passed in,
+ // then it necessarily must be coming from a caller who's passing in
+ // a bookend order.
+ for (uint256 j = 0; j < order.offer.length; ++j) {
+ if (order.offer[j].itemType == ItemType.NATIVE) {
+ return true;
+ }
+ }
+ }
+
+ // If the caller is the recipient, it's never necessary to use match.
+ if (context.request.caller == context.request.recipient) {
+ return false;
+ }
+
+ // This basically checks if there's an ERC721 in the offer of one order
+ // that is also in the consideration of another order. If yes, must use
+ // match.
+ for (uint256 i = 0; i < orders.length; ++i) {
+ // Get the order.
+ OrderDetails memory order = orders[i];
+
+ // Iterate over the offer items.
+ for (uint256 j = 0; j < order.offer.length; ++j) {
+ // Get the item.
+ SpentItem memory item = order.offer[j];
+
+ // If the item is not an ERC721, skip it.
+ if (item.itemType != ItemType.ERC721) {
+ continue;
+ }
+
+ // Iterate over the orders again.
+ for (uint256 k = 0; k < orders.length; ++k) {
+ // Get an order to compare `orders[i]` against.
+ OrderDetails memory comparisonOrder = orders[k];
+
+ // Iterate over the consideration items.
+ for (
+ uint256 l = 0;
+ l < comparisonOrder.consideration.length;
+ ++l
+ ) {
+ // Get the consideration item.
+ ReceivedItem memory considerationItem = comparisonOrder
+ .consideration[l];
+
+ // If the consideration item is an ERC721, and the ID is
+ // the same as the offer item, and the token address is
+ // the same as the offer item, must use match.
+ if (
+ considerationItem.itemType == ItemType.ERC721 &&
+ considerationItem.identifier == item.identifier &&
+ considerationItem.token == item.token
+ ) {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/OrderAvailabilityLib.sol b/contracts/helpers/navigator/lib/OrderAvailabilityLib.sol
new file mode 100644
index 000000000..02f9aebf1
--- /dev/null
+++ b/contracts/helpers/navigator/lib/OrderAvailabilityLib.sol
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+import { AdvancedOrder } from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
+
+import { OrderStructureLib, State } from "./OrderStructureLib.sol";
+
+/**
+ * @notice Helper library for determining order availability.
+ */
+library OrderAvailabilityLib {
+ using OrderStructureLib for AdvancedOrder;
+
+ /**
+ * @notice Returns true if the order is available for fulfillment.
+ */
+ function isAvailable(
+ AdvancedOrder memory order,
+ ConsiderationInterface seaport
+ ) internal view returns (bool) {
+ return unavailableReason(order, seaport) == UnavailableReason.AVAILABLE;
+ }
+
+ /**
+ * @notice Returns the order's UnavailableReason. Available orders will
+ * return UnavailableReason.AVAILABLE to indicate that they are
+ * available for fulfillment.
+ */
+ function unavailableReason(
+ AdvancedOrder memory order,
+ ConsiderationInterface seaport
+ ) internal view returns (UnavailableReason) {
+ if (order.parameters.endTime <= block.timestamp) {
+ return UnavailableReason.EXPIRED;
+ }
+ if (order.parameters.startTime > block.timestamp) {
+ return UnavailableReason.STARTS_IN_FUTURE;
+ }
+ if (order.getState(seaport) == State.CANCELLED) {
+ return UnavailableReason.CANCELLED;
+ }
+ if (order.getState(seaport) == State.FULLY_FILLED) {
+ return UnavailableReason.ALREADY_FULFILLED;
+ }
+ return UnavailableReason.AVAILABLE;
+ }
+
+ /**
+ * @notice Return an array of UnavailableReasons for the provided orders.
+ */
+ function unavailableReasons(
+ AdvancedOrder[] memory orders,
+ uint256 maximumFulfilled,
+ ConsiderationInterface seaport
+ ) internal view returns (UnavailableReason[] memory) {
+ UnavailableReason[] memory reasons = new UnavailableReason[](
+ orders.length
+ );
+ uint256 totalAvailable;
+ UnavailableReason reason;
+ for (uint256 i = 0; i < orders.length; i++) {
+ if (totalAvailable < maximumFulfilled) {
+ reason = unavailableReason(orders[i], seaport);
+ } else {
+ reason = UnavailableReason.MAX_FULFILLED_SATISFIED;
+ }
+ reasons[i] = reason;
+ if (reason == UnavailableReason.AVAILABLE) {
+ totalAvailable++;
+ }
+ }
+ return reasons;
+ }
+}
diff --git a/contracts/helpers/navigator/lib/OrderDetailsHelper.sol b/contracts/helpers/navigator/lib/OrderDetailsHelper.sol
new file mode 100644
index 000000000..b2c108dc0
--- /dev/null
+++ b/contracts/helpers/navigator/lib/OrderDetailsHelper.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { NavigatorDetailsLib } from "./NavigatorDetailsLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { HelperInterface } from "./HelperInterface.sol";
+
+contract OrderDetailsHelper is HelperInterface {
+ using NavigatorDetailsLib for NavigatorContext;
+
+ function prepare(
+ NavigatorContext memory context
+ ) public view returns (NavigatorContext memory) {
+ return context.withDetails();
+ }
+}
diff --git a/contracts/helpers/navigator/lib/OrderStructureLib.sol b/contracts/helpers/navigator/lib/OrderStructureLib.sol
new file mode 100644
index 000000000..d176f0060
--- /dev/null
+++ b/contracts/helpers/navigator/lib/OrderStructureLib.sol
@@ -0,0 +1,519 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ AdvancedOrderLib,
+ ConsiderationItemLib,
+ OfferItemLib,
+ OrderComponentsLib,
+ OrderLib,
+ OrderParametersLib
+} from "seaport-sol/src/SeaportSol.sol";
+
+import {
+ AdvancedOrder,
+ ConsiderationItem,
+ OfferItem,
+ Order,
+ OrderComponents,
+ OrderParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ BasicOrderRouteType,
+ BasicOrderType,
+ ItemType,
+ OrderType
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+error TypeNotFound();
+
+/**
+ * @dev The "structure" of the order.
+ * - BASIC: adheres to basic construction rules.
+ * - STANDARD: does not adhere to basic construction rules.
+ * - ADVANCED: requires criteria resolution, partial fulfillment, and/or
+ * extraData.
+ */
+enum Structure {
+ BASIC,
+ STANDARD,
+ ADVANCED
+}
+
+/**
+ * @dev The "type" of the order.
+ * - OPEN: FULL_OPEN or PARTIAL_OPEN orders.
+ * - RESTRICTED: FULL_RESTRICTED or PARTIAL_RESTRICTED orders.
+ * - CONTRACT: CONTRACT orders
+ */
+enum Type {
+ OPEN,
+ RESTRICTED,
+ CONTRACT
+}
+
+/**
+ * @dev The "family" of method that can fulfill the order.
+ * - SINGLE: methods that accept a single order.
+ * (fulfillOrder, fulfillAdvancedOrder, fulfillBasicOrder,
+ * fulfillBasicOrder_efficient_6GL6yc)
+ * - COMBINED: methods that accept multiple orders.
+ * (fulfillAvailableOrders, fulfillAvailableAdvancedOrders, matchOrders,
+ * matchAdvancedOrders, cancel, validate)
+ */
+enum Family {
+ SINGLE,
+ COMBINED
+}
+
+/**
+ * @dev The "state" of the order.
+ * - UNUSED: New, not validated, cancelled, or partially/fully filled.
+ * - VALIDATED: Order has been validated, but not cancelled or filled.
+ * - CANCELLED: Order has been cancelled.
+ * - PARTIALLY_FILLED: Order is partially filled.
+ * - FULLY_FILLED: Order is fully filled.
+ */
+enum State {
+ UNUSED,
+ VALIDATED,
+ CANCELLED,
+ PARTIALLY_FILLED,
+ FULLY_FILLED
+}
+
+/**
+ * @notice Helper library for classifying an order's structure. This is helpful
+ * for determining which fulfillment method to use.
+ */
+library OrderStructureLib {
+ using AdvancedOrderLib for AdvancedOrder;
+ using AdvancedOrderLib for AdvancedOrder[];
+ using ConsiderationItemLib for ConsiderationItem[];
+ using OfferItemLib for OfferItem[];
+ using OrderComponentsLib for OrderComponents;
+ using OrderLib for Order;
+ using OrderParametersLib for OrderParameters;
+
+ function getQuantity(
+ AdvancedOrder[] memory orders
+ ) internal pure returns (uint256) {
+ return orders.length;
+ }
+
+ function getFamily(
+ AdvancedOrder[] memory orders
+ ) internal pure returns (Family) {
+ uint256 quantity = getQuantity(orders);
+ if (quantity > 1) {
+ return Family.COMBINED;
+ }
+ return Family.SINGLE;
+ }
+
+ function getState(
+ AdvancedOrder memory order,
+ ConsiderationInterface seaport
+ ) internal view returns (State) {
+ // Get the counter for the offerer.
+ uint256 counter = seaport.getCounter(order.parameters.offerer);
+
+ // Use the counter to get the order hash.
+ bytes32 orderHash = seaport.getOrderHash(
+ order.parameters.toOrderComponents(counter)
+ );
+
+ // Use the order hash to get the order status.
+ (
+ bool isValidated,
+ bool isCancelled,
+ uint256 totalFilled,
+ uint256 totalSize
+ ) = seaport.getOrderStatus(orderHash);
+
+ if (totalFilled != 0 && totalSize != 0 && totalFilled == totalSize) {
+ return State.FULLY_FILLED;
+ }
+ if (totalFilled != 0 && totalSize != 0) {
+ return State.PARTIALLY_FILLED;
+ }
+ if (isCancelled) {
+ return State.CANCELLED;
+ }
+ if (isValidated) {
+ return State.VALIDATED;
+ }
+ return State.UNUSED;
+ }
+
+ function getType(AdvancedOrder memory order) internal pure returns (Type) {
+ OrderType orderType = order.parameters.orderType;
+ if (
+ orderType == OrderType.FULL_OPEN ||
+ orderType == OrderType.PARTIAL_OPEN
+ ) {
+ return Type.OPEN;
+ } else if (
+ orderType == OrderType.FULL_RESTRICTED ||
+ orderType == OrderType.PARTIAL_RESTRICTED
+ ) {
+ return Type.RESTRICTED;
+ } else if (orderType == OrderType.CONTRACT) {
+ return Type.CONTRACT;
+ } else {
+ revert TypeNotFound();
+ }
+ }
+
+ function getStructure(
+ AdvancedOrder memory order,
+ address seaport
+ ) internal view returns (Structure) {
+ // If the order has extraData, it's advanced
+ if (order.extraData.length > 0) return Structure.ADVANCED;
+
+ // If the order has numerator or denominator, it's advanced
+ if (order.numerator != 0 || order.denominator != 0) {
+ if (order.numerator < order.denominator) {
+ return Structure.ADVANCED;
+ }
+ }
+
+ (bool hasCriteria, bool hasNonzeroCriteria) = _checkCriteria(order);
+ bool isContractOrder = order.parameters.orderType == OrderType.CONTRACT;
+
+ // If any non-contract item has criteria, it's advanced,
+ if (hasCriteria) {
+ // Unless it's a contract order
+ if (isContractOrder) {
+ // And the contract order's critera are all zero
+ if (hasNonzeroCriteria) {
+ return Structure.ADVANCED;
+ }
+ } else {
+ return Structure.ADVANCED;
+ }
+ }
+
+ if (getBasicOrderTypeEligibility(order, seaport)) {
+ return Structure.BASIC;
+ }
+
+ return Structure.STANDARD;
+ }
+
+ function getStructure(
+ AdvancedOrder[] memory orders,
+ address seaport
+ ) internal view returns (Structure) {
+ if (orders.length == 1) {
+ return getStructure(orders[0], seaport);
+ }
+
+ for (uint256 i; i < orders.length; i++) {
+ Structure structure = getStructure(orders[i], seaport);
+ if (structure == Structure.ADVANCED) {
+ return Structure.ADVANCED;
+ }
+ }
+
+ return Structure.STANDARD;
+ }
+
+ function getBasicOrderTypeEligibility(
+ AdvancedOrder memory order,
+ address seaport
+ ) internal view returns (bool) {
+ uint256 i;
+ ConsiderationItem[] memory consideration = order
+ .parameters
+ .consideration;
+ OfferItem[] memory offer = order.parameters.offer;
+
+ // Order must contain exactly one offer item and one or more
+ // consideration items.
+ if (offer.length != 1) {
+ return false;
+ }
+ if (
+ consideration.length == 0 ||
+ order.parameters.totalOriginalConsiderationItems == 0
+ ) {
+ return false;
+ }
+
+ // The order cannot have a contract order type.
+ if (order.parameters.orderType == OrderType.CONTRACT) {
+ return false;
+
+ // Note: the order type is combined with the “route” into a single
+ // BasicOrderType with a value between 0 and 23; there are 4
+ // supported order types (full open, partial open, full restricted,
+ // partial restricted) and 6 routes (ETH ⇒ ERC721, ETH ⇒ ERC1155,
+ // ERC20 ⇒ ERC721, ERC20 ⇒ ERC1155, ERC721 ⇒ ERC20, ERC1155 ⇒ ERC20)
+ }
+
+ // Order cannot specify a partial fraction to fill.
+ if (order.denominator > 1 && (order.numerator < order.denominator)) {
+ return false;
+ }
+
+ // Order cannot be partially filled.
+ ConsiderationInterface seaportInterface = ConsiderationInterface(
+ seaport
+ );
+ uint256 counter = seaportInterface.getCounter(order.parameters.offerer);
+ OrderComponents memory orderComponents = order
+ .parameters
+ .toOrderComponents(counter);
+ bytes32 orderHash = seaportInterface.getOrderHash(orderComponents);
+ (, , uint256 totalFilled, uint256 totalSize) = seaportInterface
+ .getOrderStatus(orderHash);
+
+ if (totalFilled != totalSize) {
+ return false;
+ }
+
+ // Order cannot contain any criteria-based items.
+ for (i = 0; i < consideration.length; ++i) {
+ if (
+ consideration[i].itemType == ItemType.ERC721_WITH_CRITERIA ||
+ consideration[i].itemType == ItemType.ERC1155_WITH_CRITERIA
+ ) {
+ return false;
+ }
+ }
+
+ if (
+ offer[0].itemType == ItemType.ERC721_WITH_CRITERIA ||
+ offer[0].itemType == ItemType.ERC1155_WITH_CRITERIA
+ ) {
+ return false;
+ }
+
+ // Order cannot contain any extraData.
+ if (order.extraData.length != 0) {
+ return false;
+ }
+
+ // Order must contain exactly one NFT item.
+ uint256 totalNFTs;
+ if (
+ offer[0].itemType == ItemType.ERC721 ||
+ offer[0].itemType == ItemType.ERC1155
+ ) {
+ totalNFTs += 1;
+ }
+ for (i = 0; i < consideration.length; ++i) {
+ if (
+ consideration[i].itemType == ItemType.ERC721 ||
+ consideration[i].itemType == ItemType.ERC1155
+ ) {
+ totalNFTs += 1;
+ }
+ }
+
+ if (totalNFTs != 1) {
+ return false;
+ }
+
+ // The one NFT must appear either as the offer item or as the first
+ // consideration item.
+ if (
+ offer[0].itemType != ItemType.ERC721 &&
+ offer[0].itemType != ItemType.ERC1155 &&
+ consideration[0].itemType != ItemType.ERC721 &&
+ consideration[0].itemType != ItemType.ERC1155
+ ) {
+ return false;
+ }
+
+ // All items that are not the NFT must share the same item type and
+ // token (and the identifier must be zero).
+ if (
+ offer[0].itemType == ItemType.ERC721 ||
+ offer[0].itemType == ItemType.ERC1155
+ ) {
+ ItemType expectedItemType = consideration[0].itemType;
+ address expectedToken = consideration[0].token;
+
+ for (i = 0; i < consideration.length; ++i) {
+ if (consideration[i].itemType != expectedItemType) {
+ return false;
+ }
+
+ if (consideration[i].token != expectedToken) {
+ return false;
+ }
+
+ if (consideration[i].identifierOrCriteria != 0) {
+ return false;
+ }
+ }
+ }
+
+ if (
+ consideration[0].itemType == ItemType.ERC721 ||
+ consideration[0].itemType == ItemType.ERC1155
+ ) {
+ if (consideration.length >= 2) {
+ ItemType expectedItemType = offer[0].itemType;
+ address expectedToken = offer[0].token;
+ for (i = 1; i < consideration.length; ++i) {
+ if (consideration[i].itemType != expectedItemType) {
+ return false;
+ }
+
+ if (consideration[i].token != expectedToken) {
+ return false;
+ }
+
+ if (consideration[i].identifierOrCriteria != 0) {
+ return false;
+ }
+ }
+ }
+ }
+
+ // The offerer must be the recipient of the first consideration item.
+ if (consideration[0].recipient != order.parameters.offerer) {
+ return false;
+ }
+
+ // If the NFT is the first consideration item, the sum of the amounts of
+ // all the other consideration items cannot exceed the amount of the
+ // offer item.
+ if (
+ consideration[0].itemType == ItemType.ERC721 ||
+ consideration[0].itemType == ItemType.ERC1155
+ ) {
+ uint256 totalConsiderationAmount;
+ for (i = 1; i < consideration.length; ++i) {
+ totalConsiderationAmount += consideration[i].startAmount;
+ }
+
+ if (totalConsiderationAmount > offer[0].startAmount) {
+ return false;
+ }
+
+ // Note: these cases represent a “bid” for an NFT, and the non-NFT
+ // consideration items (i.e. the “payment tokens”) are sent directly
+ // from the offerer to each recipient; this means that the fulfiller
+ // accepting the bid does not need to have approval set for the
+ // payment tokens.
+ }
+
+ // All items must have startAmount == endAmount
+ if (offer[0].startAmount != offer[0].endAmount) {
+ return false;
+ }
+ for (i = 0; i < consideration.length; ++i) {
+ if (consideration[i].startAmount != consideration[i].endAmount) {
+ return false;
+ }
+ }
+
+ // The offer item cannot have a native token type.
+ if (offer[0].itemType == ItemType.NATIVE) {
+ return false;
+ }
+
+ return true;
+ }
+
+ function getBasicOrderType(
+ AdvancedOrder memory order
+ ) internal pure returns (BasicOrderType basicOrderType) {
+ // Get the route (ETH ⇒ ERC721, etc.) for the order.
+ BasicOrderRouteType route = getBasicOrderRouteType(order);
+
+ // Get the order type (restricted, etc.) for the order.
+ OrderType orderType = order.parameters.orderType;
+
+ // Multiply the route by 4 and add the order type to get the
+ // BasicOrderType.
+ assembly {
+ basicOrderType := add(orderType, mul(route, 4))
+ }
+ }
+
+ function getBasicOrderRouteType(
+ AdvancedOrder memory order
+ ) internal pure returns (BasicOrderRouteType route) {
+ // Get the route (ETH ⇒ ERC721, etc.) for the order.
+ ItemType providingItemType = order.parameters.consideration[0].itemType;
+ ItemType offeredItemType = order.parameters.offer[0].itemType;
+
+ if (providingItemType == ItemType.NATIVE) {
+ if (offeredItemType == ItemType.ERC721) {
+ route = BasicOrderRouteType.ETH_TO_ERC721;
+ } else if (offeredItemType == ItemType.ERC1155) {
+ route = BasicOrderRouteType.ETH_TO_ERC1155;
+ }
+ } else if (providingItemType == ItemType.ERC20) {
+ if (offeredItemType == ItemType.ERC721) {
+ route = BasicOrderRouteType.ERC20_TO_ERC721;
+ } else if (offeredItemType == ItemType.ERC1155) {
+ route = BasicOrderRouteType.ERC20_TO_ERC1155;
+ }
+ } else if (providingItemType == ItemType.ERC721) {
+ if (offeredItemType == ItemType.ERC20) {
+ route = BasicOrderRouteType.ERC721_TO_ERC20;
+ }
+ } else if (providingItemType == ItemType.ERC1155) {
+ if (offeredItemType == ItemType.ERC20) {
+ route = BasicOrderRouteType.ERC1155_TO_ERC20;
+ }
+ }
+ }
+
+ /**
+ * @dev Check all offer and consideration items for criteria.
+ *
+ * @param order The advanced order.
+ *
+ * @return hasCriteria Whether any offer or consideration item has
+ * criteria.
+ * @return hasNonzeroCriteria Whether any offer or consideration item has
+ * nonzero criteria.
+ */
+ function _checkCriteria(
+ AdvancedOrder memory order
+ ) internal pure returns (bool hasCriteria, bool hasNonzeroCriteria) {
+ // Check if any offer item has criteria
+ OfferItem[] memory offer = order.parameters.offer;
+ for (uint256 i; i < offer.length; ++i) {
+ OfferItem memory offerItem = offer[i];
+ ItemType itemType = offerItem.itemType;
+ hasCriteria = (itemType == ItemType.ERC721_WITH_CRITERIA ||
+ itemType == ItemType.ERC1155_WITH_CRITERIA);
+ if (hasCriteria) {
+ return (hasCriteria, offerItem.identifierOrCriteria != 0);
+ }
+ }
+
+ // Check if any consideration item has criteria
+ ConsiderationItem[] memory consideration = order
+ .parameters
+ .consideration;
+ for (uint256 i; i < consideration.length; ++i) {
+ ConsiderationItem memory considerationItem = consideration[i];
+ ItemType itemType = considerationItem.itemType;
+ hasCriteria = (itemType == ItemType.ERC721_WITH_CRITERIA ||
+ itemType == ItemType.ERC1155_WITH_CRITERIA);
+ if (hasCriteria) {
+ return (
+ hasCriteria,
+ considerationItem.identifierOrCriteria != 0
+ );
+ }
+ }
+
+ return (false, false);
+ }
+}
diff --git a/contracts/helpers/navigator/lib/RequestValidator.sol b/contracts/helpers/navigator/lib/RequestValidator.sol
new file mode 100644
index 000000000..767e9f4a3
--- /dev/null
+++ b/contracts/helpers/navigator/lib/RequestValidator.sol
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ NavigatorRequestValidatorLib
+} from "./NavigatorRequestValidatorLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { HelperInterface } from "./HelperInterface.sol";
+
+contract RequestValidator is HelperInterface {
+ using NavigatorRequestValidatorLib for NavigatorContext;
+
+ function prepare(
+ NavigatorContext memory context
+ ) public pure returns (NavigatorContext memory) {
+ return context.validate();
+ }
+}
diff --git a/contracts/helpers/navigator/lib/SeaportNavigatorInterface.sol b/contracts/helpers/navigator/lib/SeaportNavigatorInterface.sol
new file mode 100644
index 000000000..645930e28
--- /dev/null
+++ b/contracts/helpers/navigator/lib/SeaportNavigatorInterface.sol
@@ -0,0 +1,43 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ NavigatorRequest,
+ NavigatorResponse
+} from "./SeaportNavigatorTypes.sol";
+
+interface SeaportNavigatorInterface {
+ function prepare(
+ NavigatorRequest memory request
+ ) external view returns (NavigatorResponse memory);
+
+ /**
+ * @notice Generate a criteria merkle root from an array of `tokenIds`. Use
+ * this helper to construct an order item's `identifierOrCriteria`.
+ *
+ * @param tokenIds An array of integer token IDs to be converted to a merkle
+ * root.
+ *
+ * @return The bytes32 merkle root of a criteria tree containing the given
+ * token IDs.
+ */
+ function criteriaRoot(
+ uint256[] memory tokenIds
+ ) external pure returns (bytes32);
+
+ /**
+ * @notice Generate a criteria merkle proof that `id` is a member of
+ * `tokenIds`. Reverts if `id` is not a member of `tokenIds`. Use
+ * this helper to construct proof data for criteria resolvers.
+ *
+ * @param tokenIds An array of integer token IDs.
+ * @param id The integer token ID to generate a proof for.
+ *
+ * @return Merkle proof that the given token ID is amember of the criteria
+ * tree containing the given token IDs.
+ */
+ function criteriaProof(
+ uint256[] memory tokenIds,
+ uint256 id
+ ) external pure returns (bytes32[] memory);
+}
diff --git a/contracts/helpers/navigator/lib/SeaportNavigatorTypes.sol b/contracts/helpers/navigator/lib/SeaportNavigatorTypes.sol
new file mode 100644
index 000000000..fa87d827f
--- /dev/null
+++ b/contracts/helpers/navigator/lib/SeaportNavigatorTypes.sol
@@ -0,0 +1,160 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+import {
+ AdvancedOrder,
+ CriteriaResolver,
+ Execution,
+ Fulfillment,
+ FulfillmentComponent
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ ItemType,
+ OrderType
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+import {
+ MatchComponent
+} from "seaport-sol/src/lib/types/MatchComponentType.sol";
+
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
+
+import {
+ FulfillmentStrategy
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
+
+import {
+ SeaportValidatorInterface,
+ ErrorsAndWarnings
+} from "../../order-validator/SeaportValidator.sol";
+
+struct NavigatorAdvancedOrder {
+ NavigatorOrderParameters parameters;
+ uint120 numerator;
+ uint120 denominator;
+ bytes signature;
+ bytes extraData;
+}
+
+struct NavigatorOrderParameters {
+ address offerer;
+ address zone;
+ NavigatorOfferItem[] offer;
+ NavigatorConsiderationItem[] consideration;
+ OrderType orderType;
+ uint256 startTime;
+ uint256 endTime;
+ bytes32 zoneHash;
+ uint256 salt;
+ bytes32 conduitKey;
+ uint256 totalOriginalConsiderationItems;
+}
+
+struct NavigatorOfferItem {
+ ItemType itemType;
+ address token;
+ uint256 identifier;
+ uint256 startAmount;
+ uint256 endAmount;
+ uint256[] candidateIdentifiers;
+}
+
+struct NavigatorConsiderationItem {
+ ItemType itemType;
+ address token;
+ uint256 identifier;
+ uint256 startAmount;
+ uint256 endAmount;
+ address payable recipient;
+ uint256[] candidateIdentifiers;
+}
+
+/**
+ * @dev Context struct for NavigatorContextLib. Includes context information
+ * necessary for fulfillment, like the caller and recipient addresses,
+ * and Seaport and SeaportValidator interfaces.
+ */
+struct NavigatorContext {
+ NavigatorRequest request;
+ NavigatorResponse response;
+}
+
+struct NavigatorRequest {
+ ConsiderationInterface seaport;
+ SeaportValidatorInterface validator;
+ NavigatorAdvancedOrder[] orders;
+ address caller;
+ address recipient;
+ uint256 nativeTokensSupplied;
+ uint256 maximumFulfilled;
+ bytes32 fulfillerConduitKey;
+ uint256 seed;
+ FulfillmentStrategy fulfillmentStrategy;
+ CriteriaResolver[] criteriaResolvers;
+ bool preferMatch;
+}
+
+struct NavigatorResponse {
+ /**
+ * @dev The provided orders. If the caller provides explicit criteria
+ * resolvers, the orders will not be modified. If the caller provides
+ * criteria constraints, the returned offer/consideration items will be
+ * updated with calculated merkle roots as their `identifierOrCriteria`
+ */
+ AdvancedOrder[] orders;
+ /**
+ * @dev The provided or calculated criteria resolvers. If the caller
+ * provides criteria constraints rather than explicit criteria
+ * resolvers, criteria resolvers and merkle proofs will be calculated
+ * based on provided criteria constraints.
+ */
+ CriteriaResolver[] criteriaResolvers;
+ /**
+ * @dev Human-readable name of the suggested Seaport fulfillment method for
+ * the provided orders.
+ */
+ string suggestedActionName;
+ /**
+ * @dev Encoded calldata for the suggested Seaport fulfillment method,
+ * provided orders, and context args.
+ */
+ bytes suggestedCallData;
+ /**
+ * @dev Array of errors and warnings returned by SeaportValidator for the
+ * provided orders, by order index in the orders array.
+ */
+ ErrorsAndWarnings[] validationErrors;
+ /**
+ * @dev Calculated OrderDetails structs for the provided orders, by order
+ * index. Includes offerer, conduit key, spent and received items,
+ * order hash, and unavailable reason.
+ */
+ OrderDetails[] orderDetails;
+ /**
+ * @dev Calculated fulfillment components and combined Fullfiilments.
+ */
+ FulfillmentComponent[][] offerFulfillments;
+ FulfillmentComponent[][] considerationFulfillments;
+ Fulfillment[] fulfillments;
+ /**
+ * @dev Calculated match components for matchable orders.
+ */
+ MatchComponent[] unspentOfferComponents;
+ MatchComponent[] unmetConsiderationComponents;
+ /**
+ * @dev Calculated explicit and implicit executions.
+ */
+ Execution[] explicitExecutions;
+ Execution[] implicitExecutions;
+ Execution[] implicitExecutionsPre;
+ Execution[] implicitExecutionsPost;
+ /**
+ * @dev Quantity of native tokens returned to caller.
+ */
+ uint256 nativeTokensReturned;
+}
diff --git a/contracts/helpers/navigator/lib/SuggestedActionHelper.sol b/contracts/helpers/navigator/lib/SuggestedActionHelper.sol
new file mode 100644
index 000000000..858ce6c3b
--- /dev/null
+++ b/contracts/helpers/navigator/lib/SuggestedActionHelper.sol
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { NavigatorSuggestedActionLib } from "./NavigatorSuggestedActionLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { HelperInterface } from "./HelperInterface.sol";
+
+contract SuggestedActionHelper is HelperInterface {
+ using NavigatorSuggestedActionLib for NavigatorContext;
+
+ function prepare(
+ NavigatorContext memory context
+ ) public view returns (NavigatorContext memory) {
+ return context.withSuggestedAction();
+ }
+}
diff --git a/contracts/helpers/navigator/lib/ValidatorHelper.sol b/contracts/helpers/navigator/lib/ValidatorHelper.sol
new file mode 100644
index 000000000..526fb88b2
--- /dev/null
+++ b/contracts/helpers/navigator/lib/ValidatorHelper.sol
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ NavigatorSeaportValidatorLib
+} from "./NavigatorSeaportValidatorLib.sol";
+
+import { NavigatorContext } from "./SeaportNavigatorTypes.sol";
+
+import { HelperInterface } from "./HelperInterface.sol";
+
+contract ValidatorHelper is HelperInterface {
+ using NavigatorSeaportValidatorLib for NavigatorContext;
+
+ function prepare(
+ NavigatorContext memory context
+ ) public view returns (NavigatorContext memory) {
+ return context.withErrors();
+ }
+}
diff --git a/contracts/helpers/order-validator/SeaportValidator.sol b/contracts/helpers/order-validator/SeaportValidator.sol
index 0b6ab3489..d0f57c310 100644
--- a/contracts/helpers/order-validator/SeaportValidator.sol
+++ b/contracts/helpers/order-validator/SeaportValidator.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { ItemType } from "../../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
Order,
OrderParameters,
@@ -10,28 +10,30 @@ import {
ConsiderationItem,
Schema,
ZoneParameters
-} from "../../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ConsiderationTypeHashes } from "./lib/ConsiderationTypeHashes.sol";
import {
ConsiderationInterface
-} from "../../interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
ConduitControllerInterface
-} from "../../interfaces/ConduitControllerInterface.sol";
+} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";
import {
ContractOffererInterface
-} from "../../interfaces/ContractOffererInterface.sol";
-import { ZoneInterface } from "../../interfaces/ZoneInterface.sol";
-import { GettersAndDerivers } from "../../lib/GettersAndDerivers.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
+import {
+ GettersAndDerivers
+} from "seaport-core/src/lib/GettersAndDerivers.sol";
import { SeaportValidatorInterface } from "./lib/SeaportValidatorInterface.sol";
-import { ZoneInterface } from "../../interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../../interfaces/AbridgedTokenInterfaces.sol";
-import { IERC165 } from "../../interfaces/IERC165.sol";
-import { IERC2981 } from "../../interfaces/IERC2981.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
+import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
+import { IERC2981 } from "@openzeppelin/contracts/interfaces/IERC2981.sol";
import {
ErrorsAndWarnings,
ErrorsAndWarningsLib
@@ -57,7 +59,8 @@ import {
GenericIssue,
ConsiderationItemConfiguration
} from "./lib/SeaportValidatorTypes.sol";
-import { Verifiers } from "../../lib/Verifiers.sol";
+import { Verifiers } from "seaport-core/src/lib/Verifiers.sol";
+import { ReadOnlyOrderValidator } from "./lib/ReadOnlyOrderValidator.sol";
import { SeaportValidatorHelper } from "./lib/SeaportValidatorHelper.sol";
/**
@@ -78,6 +81,8 @@ contract SeaportValidator is
SeaportValidatorHelper private immutable _helper;
+ ReadOnlyOrderValidator private immutable _readOnlyOrderValidator;
+
bytes4 public constant ERC20_INTERFACE_ID = 0x36372b07;
bytes4 public constant ERC721_INTERFACE_ID = 0x80ac58cd;
@@ -89,9 +94,13 @@ contract SeaportValidator is
bytes4 public constant ZONE_INTERFACE_ID = 0x3839be19;
constructor(
+ address readOnlyOrderValidatorAddress,
address seaportValidatorHelperAddress,
address conduitControllerAddress
) {
+ _readOnlyOrderValidator = ReadOnlyOrderValidator(
+ readOnlyOrderValidatorAddress
+ );
_helper = SeaportValidatorHelper(seaportValidatorHelperAddress);
_conduitController = ConduitControllerInterface(
conduitControllerAddress
@@ -115,31 +124,9 @@ contract SeaportValidator is
function isValidOrder(
Order calldata order,
address seaportAddress
- ) external returns (ErrorsAndWarnings memory errorsAndWarnings) {
- return
- isValidOrderWithConfiguration(
- ValidationConfiguration(
- seaportAddress,
- address(0),
- 0,
- false,
- false,
- 30 minutes,
- 26 weeks
- ),
- order
- );
- }
-
- /**
- * @notice Same as `isValidOrder` but does not modify state.
- */
- function isValidOrderReadOnly(
- Order calldata order,
- address seaportAddress
) external view returns (ErrorsAndWarnings memory errorsAndWarnings) {
return
- isValidOrderWithConfigurationReadOnly(
+ isValidOrderWithConfiguration(
ValidationConfiguration(
seaportAddress,
address(0),
@@ -161,7 +148,7 @@ contract SeaportValidator is
function isValidOrderWithConfiguration(
ValidationConfiguration memory validationConfiguration,
Order memory order
- ) public returns (ErrorsAndWarnings memory errorsAndWarnings) {
+ ) public view returns (ErrorsAndWarnings memory errorsAndWarnings) {
errorsAndWarnings = ErrorsAndWarnings(new uint16[](0), new uint16[](0));
// Concatenates errorsAndWarnings with the returned errorsAndWarnings
@@ -208,58 +195,6 @@ contract SeaportValidator is
}
}
- /**
- * @notice Same as `isValidOrderWithConfiguration` but doesn't call `validate` on Seaport.
- * If `skipStrictValidation` is set order logic validation is not carried out: fees are not
- * checked and there may be more than one offer item as well as any number of consideration items.
- */
- function isValidOrderWithConfigurationReadOnly(
- ValidationConfiguration memory validationConfiguration,
- Order memory order
- ) public view returns (ErrorsAndWarnings memory errorsAndWarnings) {
- errorsAndWarnings = ErrorsAndWarnings(new uint16[](0), new uint16[](0));
-
- // Concatenates errorsAndWarnings with the returned errorsAndWarnings
- errorsAndWarnings.concat(
- validateTime(
- order.parameters,
- validationConfiguration.shortOrderDuration,
- validationConfiguration.distantOrderExpiration
- )
- );
- errorsAndWarnings.concat(
- validateOrderStatus(
- order.parameters,
- validationConfiguration.seaport
- )
- );
- errorsAndWarnings.concat(
- validateOfferItems(
- order.parameters,
- validationConfiguration.seaport
- )
- );
- errorsAndWarnings.concat(
- validateConsiderationItems(
- order.parameters,
- validationConfiguration.seaport
- )
- );
- errorsAndWarnings.concat(isValidZone(order.parameters));
-
- // Skip strict validation if requested
- if (!validationConfiguration.skipStrictValidation) {
- errorsAndWarnings.concat(
- validateStrictLogic(
- order.parameters,
- validationConfiguration.primaryFeeRecipient,
- validationConfiguration.primaryFeeBips,
- validationConfiguration.checkCreatorFee
- )
- );
- }
- }
-
/**
* @notice Strict validation operates under tight assumptions. It validates primary
* fee, creator fee, private sale consideration, and overall order format.
@@ -398,7 +333,7 @@ contract SeaportValidator is
function validateSignature(
Order memory order,
address seaportAddress
- ) public returns (ErrorsAndWarnings memory errorsAndWarnings) {
+ ) public view returns (ErrorsAndWarnings memory errorsAndWarnings) {
// Pull current counter from seaport
uint256 currentCounter = ConsiderationInterface(seaportAddress)
.getCounter(order.parameters.offerer);
@@ -415,7 +350,7 @@ contract SeaportValidator is
Order memory order,
uint256 counter,
address seaportAddress
- ) public returns (ErrorsAndWarnings memory errorsAndWarnings) {
+ ) public view returns (ErrorsAndWarnings memory errorsAndWarnings) {
errorsAndWarnings = ErrorsAndWarnings(new uint16[](0), new uint16[](0));
// Typecast Seaport address to ConsiderationInterface
@@ -459,7 +394,7 @@ contract SeaportValidator is
try
// Call validate on Seaport
- seaport.validate(orderArray)
+ _readOnlyOrderValidator.canValidate(seaportAddress, orderArray)
returns (bool success) {
if (!success) {
// Call was unsuccessful, so signature is invalid
diff --git a/contracts/helpers/order-validator/lib/ConsiderationTypeHashes.sol b/contracts/helpers/order-validator/lib/ConsiderationTypeHashes.sol
index 3b987d018..fc266232d 100644
--- a/contracts/helpers/order-validator/lib/ConsiderationTypeHashes.sol
+++ b/contracts/helpers/order-validator/lib/ConsiderationTypeHashes.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
-import "../../../lib/ConsiderationStructs.sol";
+import "seaport-types/src/lib/ConsiderationStructs.sol";
uint256 constant EIP712_Order_size = 0x180;
uint256 constant EIP712_OfferItem_size = 0xc0;
diff --git a/contracts/helpers/order-validator/lib/Murky.sol b/contracts/helpers/order-validator/lib/Murky.sol
index d49675a3c..123e3cd3b 100644
--- a/contracts/helpers/order-validator/lib/Murky.sol
+++ b/contracts/helpers/order-validator/lib/Murky.sol
@@ -35,11 +35,10 @@ contract Murky {
********************/
/// ascending sort and concat prior to hashing
- function _hashLeafPairs(bytes32 left, bytes32 right)
- internal
- pure
- returns (bytes32 _hash)
- {
+ function _hashLeafPairs(
+ bytes32 left,
+ bytes32 right
+ ) internal pure returns (bytes32 _hash) {
assembly {
switch lt(left, right)
case 0 {
@@ -58,7 +57,9 @@ contract Murky {
* PROOF GENERATION *
********************/
- function _getRoot(uint256[] memory data)
+ function _getRoot(
+ uint256[] memory data
+ )
internal
pure
returns (bytes32 result, ErrorsAndWarnings memory errorsAndWarnings)
@@ -159,7 +160,10 @@ contract Murky {
}
}
- function _getProof(uint256[] memory data, uint256 node)
+ function _getProof(
+ uint256[] memory data,
+ uint256 node
+ )
internal
pure
returns (
@@ -316,11 +320,9 @@ contract Murky {
/**
* Hashes each element of the input array in place using keccak256
*/
- function _processInput(uint256[] memory data)
- private
- pure
- returns (bool sorted)
- {
+ function _processInput(
+ uint256[] memory data
+ ) private pure returns (bool sorted) {
sorted = true;
// Hash inputs with keccak256
@@ -352,11 +354,9 @@ contract Murky {
bytes32 hash;
}
- function _sortUint256ByHash(uint256[] memory values)
- internal
- pure
- returns (uint256[] memory sortedValues)
- {
+ function _sortUint256ByHash(
+ uint256[] memory values
+ ) internal pure returns (uint256[] memory sortedValues) {
HashAndIntTuple[] memory toSort = new HashAndIntTuple[](values.length);
for (uint256 i = 0; i < values.length; i++) {
toSort[i] = HashAndIntTuple(
diff --git a/contracts/helpers/order-validator/lib/ReadOnlyOrderValidator.sol b/contracts/helpers/order-validator/lib/ReadOnlyOrderValidator.sol
new file mode 100644
index 000000000..81e6f770c
--- /dev/null
+++ b/contracts/helpers/order-validator/lib/ReadOnlyOrderValidator.sol
@@ -0,0 +1,722 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.24;
+
+import { OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+import {
+ Order,
+ OrderComponents,
+ OrderParameters,
+ OrderStatus
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ _revertConsiderationLengthNotEqualToTotalOriginal,
+ _revertMissingOriginalConsiderationItems
+} from "seaport-types/src/lib/ConsiderationErrors.sol";
+
+import {
+ SignatureVerification
+} from "seaport-core/src/lib/SignatureVerification.sol";
+
+import {
+ _revertOrderAlreadyFilled,
+ _revertOrderIsCancelled,
+ _revertOrderPartiallyFilled
+} from "seaport-types/src/lib/ConsiderationErrors.sol";
+
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
+
+import {
+ BulkOrder_Typehash_Height_One,
+ BulkOrder_Typehash_Height_Two,
+ BulkOrder_Typehash_Height_Three,
+ BulkOrder_Typehash_Height_Four,
+ BulkOrder_Typehash_Height_Five,
+ BulkOrder_Typehash_Height_Six,
+ BulkOrder_Typehash_Height_Seven,
+ BulkOrder_Typehash_Height_Eight,
+ BulkOrder_Typehash_Height_Nine,
+ BulkOrder_Typehash_Height_Ten,
+ BulkOrder_Typehash_Height_Eleven,
+ BulkOrder_Typehash_Height_Twelve,
+ BulkOrder_Typehash_Height_Thirteen,
+ BulkOrder_Typehash_Height_Fourteen,
+ BulkOrder_Typehash_Height_Fifteen,
+ BulkOrder_Typehash_Height_Sixteen,
+ BulkOrder_Typehash_Height_Seventeen,
+ BulkOrder_Typehash_Height_Eighteen,
+ BulkOrder_Typehash_Height_Nineteen,
+ BulkOrder_Typehash_Height_Twenty,
+ BulkOrder_Typehash_Height_TwentyOne,
+ BulkOrder_Typehash_Height_TwentyTwo,
+ BulkOrder_Typehash_Height_TwentyThree,
+ BulkOrder_Typehash_Height_TwentyFour,
+ BulkOrderProof_keyShift,
+ BulkOrderProof_keySize,
+ BulkOrderProof_lengthAdjustmentBeforeMask,
+ BulkOrderProof_lengthRangeAfterMask,
+ BulkOrderProof_minSize,
+ BulkOrderProof_rangeSize,
+ ECDSA_MaxLength,
+ EIP_712_PREFIX,
+ EIP712_DigestPayload_size,
+ EIP712_DomainSeparator_offset,
+ EIP712_OrderHash_offset,
+ OneWord,
+ OneWordShift,
+ ThirtyOneBytes,
+ TwoWords
+} from "seaport-types/src/lib/ConsiderationConstants.sol";
+
+contract ReadOnlyOrderValidator is SignatureVerification {
+ function canValidate(
+ address seaport,
+ Order[] memory orders
+ ) external view returns (bool) {
+ return _validate(orders, SeaportInterface(seaport));
+ }
+
+ /**
+ * @dev Internal function to validate an arbitrary number of orders, thereby
+ * registering their signatures as valid and allowing the fulfiller to
+ * skip signature verification on fulfillment. Note that validated
+ * orders may still be unfulfillable due to invalid item amounts or
+ * other factors; callers should determine whether validated orders are
+ * fulfillable by simulating the fulfillment call prior to execution.
+ * Also note that anyone can validate a signed order, but only the
+ * offerer can validate an order without supplying a signature.
+ *
+ * @param orders The orders to validate.
+ *
+ * @return validated A boolean indicating whether the supplied orders were
+ * successfully validated.
+ */
+ function _validate(
+ Order[] memory orders,
+ SeaportInterface seaport
+ ) internal view returns (bool validated) {
+ (, bytes32 domainSeparator, ) = seaport.information();
+
+ // Declare variables outside of the loop.
+ OrderStatus memory orderStatus;
+ bytes32 orderHash;
+ address offerer;
+
+ // Skip overflow check as for loop is indexed starting at zero.
+ unchecked {
+ // Read length of the orders array from memory and place on stack.
+ uint256 totalOrders = orders.length;
+
+ // Iterate over each order.
+ for (uint256 i = 0; i < totalOrders; ++i) {
+ // Retrieve the order.
+ Order memory order = orders[i];
+
+ // Retrieve the order parameters.
+ OrderParameters memory orderParameters = order.parameters;
+
+ // Skip contract orders.
+ if (orderParameters.orderType == OrderType.CONTRACT) {
+ continue;
+ }
+
+ // Move offerer from memory to the stack.
+ offerer = orderParameters.offerer;
+
+ // Get current counter & use it w/ params to derive order hash.
+ orderHash = _assertConsiderationLengthAndGetOrderHash(
+ orderParameters,
+ seaport
+ );
+
+ {
+ // Retrieve the order status using the derived order hash.
+ (
+ bool isValidated,
+ bool isCancelled,
+ uint256 totalFilled,
+ uint256 totalSize
+ ) = seaport.getOrderStatus(orderHash);
+ orderStatus = OrderStatus(
+ isValidated,
+ isCancelled,
+ uint120(totalFilled),
+ uint120(totalSize)
+ );
+ }
+
+ // Ensure order is fillable and retrieve the filled amount.
+ _verifyOrderStatus(
+ orderHash,
+ orderStatus,
+ false, // Signifies that partially filled orders are valid.
+ true // Signifies to revert if the order is invalid.
+ );
+
+ // If the order has not already been validated...
+ if (!orderStatus.isValidated) {
+ // Ensure that consideration array length is equal to the
+ // total original consideration items value.
+ if (
+ orderParameters.consideration.length !=
+ orderParameters.totalOriginalConsiderationItems
+ ) {
+ _revertConsiderationLengthNotEqualToTotalOriginal();
+ }
+
+ // Verify the supplied signature.
+ _verifySignature(
+ offerer,
+ orderHash,
+ order.signature,
+ domainSeparator
+ );
+
+ // Update order status to mark the order as valid.
+ // orderStatus.isValidated = true;
+
+ // Emit an event signifying the order has been validated.
+ // emit OrderValidated(orderHash, orderParameters);
+ }
+ }
+ }
+
+ // Return a boolean indicating that orders were successfully validated.
+ validated = true;
+ }
+
+ /**
+ * @dev Internal view function to validate that a given order is fillable
+ * and not cancelled based on the order status.
+ *
+ * @param orderHash The order hash.
+ * @param orderStatus The status of the order, including whether it has
+ * been cancelled and the fraction filled.
+ * @param onlyAllowUnused A boolean flag indicating whether partial fills
+ * are supported by the calling function.
+ * @param revertOnInvalid A boolean indicating whether to revert if the
+ * order has been cancelled or filled beyond the
+ * allowable amount.
+ *
+ * @return valid A boolean indicating whether the order is valid.
+ */
+ function _verifyOrderStatus(
+ bytes32 orderHash,
+ OrderStatus memory orderStatus,
+ bool onlyAllowUnused,
+ bool revertOnInvalid
+ ) internal pure returns (bool valid) {
+ // Ensure that the order has not been cancelled.
+ if (orderStatus.isCancelled) {
+ // Only revert if revertOnInvalid has been supplied as true.
+ if (revertOnInvalid) {
+ _revertOrderIsCancelled(orderHash);
+ }
+
+ // Return false as the order status is invalid.
+ return false;
+ }
+
+ // Read order status numerator and place on stack.
+ uint256 orderStatusNumerator = orderStatus.numerator;
+
+ // If the order is not entirely unused...
+ if (orderStatusNumerator != 0) {
+ // ensure the order has not been partially filled when not allowed.
+ if (onlyAllowUnused) {
+ // Always revert on partial fills when onlyAllowUnused is true.
+ _revertOrderPartiallyFilled(orderHash);
+ }
+ // Otherwise, ensure that order has not been entirely filled.
+ else if (orderStatusNumerator >= orderStatus.denominator) {
+ // Only revert if revertOnInvalid has been supplied as true.
+ if (revertOnInvalid) {
+ _revertOrderAlreadyFilled(orderHash);
+ }
+
+ // Return false as the order status is invalid.
+ return false;
+ }
+ }
+
+ // Return true as the order status is valid.
+ valid = true;
+ }
+
+ /**
+ * @dev Internal view function to verify the signature of an order. An
+ * ERC-1271 fallback will be attempted if either the signature length
+ * is not 64 or 65 bytes or if the recovered signer does not match the
+ * supplied offerer. Note that in cases where a 64 or 65 byte signature
+ * is supplied, only standard ECDSA signatures that recover to a
+ * non-zero address are supported.
+ *
+ * @param offerer The offerer for the order.
+ * @param orderHash The order hash.
+ * @param signature A signature from the offerer indicating that the order
+ * has been approved.
+ */
+ function _verifySignature(
+ address offerer,
+ bytes32 orderHash,
+ bytes memory signature,
+ bytes32 domainSeparator
+ ) internal view {
+ // Determine whether the offerer is the caller.
+ bool offererIsCaller;
+ assembly {
+ offererIsCaller := eq(offerer, caller())
+ }
+
+ // Skip signature verification if the offerer is the caller.
+ if (offererIsCaller) {
+ return;
+ }
+
+ // Derive original EIP-712 digest using domain separator and order hash.
+ bytes32 originalDigest = _deriveEIP712Digest(
+ domainSeparator,
+ orderHash
+ );
+
+ // Read the length of the signature from memory and place on the stack.
+ uint256 originalSignatureLength = signature.length;
+
+ // Determine effective digest if signature has a valid bulk order size.
+ bytes32 digest;
+ if (_isValidBulkOrderSize(originalSignatureLength)) {
+ // Rederive order hash and digest using bulk order proof.
+ (orderHash) = _computeBulkOrderProof(signature, orderHash);
+ digest = _deriveEIP712Digest(domainSeparator, orderHash);
+ } else {
+ // Supply the original digest as the effective digest.
+ digest = originalDigest;
+ }
+
+ // Ensure that the signature for the digest is valid for the offerer.
+ _assertValidSignature(
+ offerer,
+ digest,
+ originalDigest,
+ originalSignatureLength,
+ signature
+ );
+ }
+
+ /**
+ * @dev Determines whether the specified bulk order size is valid.
+ *
+ * @param signatureLength The signature length of the bulk order to check.
+ *
+ * @return validLength True if bulk order size is valid, false otherwise.
+ */
+ function _isValidBulkOrderSize(
+ uint256 signatureLength
+ ) internal pure returns (bool validLength) {
+ // Utilize assembly to validate the length; the equivalent logic is
+ // (64 + x) + 3 + 32y where (0 <= x <= 1) and (1 <= y <= 24).
+ assembly {
+ validLength := and(
+ lt(
+ sub(signatureLength, BulkOrderProof_minSize),
+ BulkOrderProof_rangeSize
+ ),
+ lt(
+ and(
+ add(
+ signatureLength,
+ BulkOrderProof_lengthAdjustmentBeforeMask
+ ),
+ ThirtyOneBytes
+ ),
+ BulkOrderProof_lengthRangeAfterMask
+ )
+ )
+ }
+ }
+
+ /**
+ * @dev Computes the bulk order hash for the specified proof and leaf. Note
+ * that if an index that exceeds the number of orders in the bulk order
+ * payload will instead "wrap around" and refer to an earlier index.
+ *
+ * @param proofAndSignature The proof and signature of the bulk order.
+ * @param leaf The leaf of the bulk order tree.
+ *
+ * @return bulkOrderHash The bulk order hash.
+ */
+ function _computeBulkOrderProof(
+ bytes memory proofAndSignature,
+ bytes32 leaf
+ ) internal pure returns (bytes32 bulkOrderHash) {
+ // Declare arguments for the root hash and the height of the proof.
+ bytes32 root;
+ uint256 height;
+
+ // Utilize assembly to efficiently derive the root hash using the proof.
+ assembly {
+ // Retrieve the length of the proof, key, and signature combined.
+ let fullLength := mload(proofAndSignature)
+
+ // If proofAndSignature has odd length, it is a compact signature
+ // with 64 bytes.
+ let signatureLength := sub(ECDSA_MaxLength, and(fullLength, 1))
+
+ // Derive height (or depth of tree) with signature and proof length.
+ height := shr(OneWordShift, sub(fullLength, signatureLength))
+
+ // Update the length in memory to only include the signature.
+ mstore(proofAndSignature, signatureLength)
+
+ // Derive the pointer for the key using the signature length.
+ let keyPtr := add(proofAndSignature, add(OneWord, signatureLength))
+
+ // Retrieve the three-byte key using the derived pointer.
+ let key := shr(BulkOrderProof_keyShift, mload(keyPtr))
+
+ /// Retrieve pointer to first proof element by applying a constant
+ // for the key size to the derived key pointer.
+ let proof := add(keyPtr, BulkOrderProof_keySize)
+
+ // Compute level 1.
+ let scratchPtr1 := shl(OneWordShift, and(key, 1))
+ mstore(scratchPtr1, leaf)
+ mstore(xor(scratchPtr1, OneWord), mload(proof))
+
+ // Compute remaining proofs.
+ for {
+ let i := 1
+ } lt(i, height) {
+ i := add(i, 1)
+ } {
+ proof := add(proof, OneWord)
+ let scratchPtr := shl(OneWordShift, and(shr(i, key), 1))
+ mstore(scratchPtr, keccak256(0, TwoWords))
+ mstore(xor(scratchPtr, OneWord), mload(proof))
+ }
+
+ // Compute root hash.
+ root := keccak256(0, TwoWords)
+ }
+
+ // Retrieve appropriate typehash constant based on height.
+ bytes32 rootTypeHash = _lookupBulkOrderTypehash(height);
+
+ // Use the typehash and the root hash to derive final bulk order hash.
+ assembly {
+ mstore(0, rootTypeHash)
+ mstore(OneWord, root)
+ bulkOrderHash := keccak256(0, TwoWords)
+ }
+ }
+
+ /**
+ * @dev Internal pure function to look up one of twenty-four potential bulk
+ * order typehash constants based on the height of the bulk order tree.
+ * Note that values between one and twenty-four are supported, which is
+ * enforced by _isValidBulkOrderSize.
+ *
+ * @param _treeHeight The height of the bulk order tree. The value must be
+ * between one and twenty-four.
+ *
+ * @return _typeHash The EIP-712 typehash for the bulk order type with the
+ * given height.
+ */
+ function _lookupBulkOrderTypehash(
+ uint256 _treeHeight
+ ) internal pure returns (bytes32 _typeHash) {
+ // Utilize assembly to efficiently retrieve correct bulk order typehash.
+ assembly {
+ // Use a Yul function to enable use of the `leave` keyword
+ // to stop searching once the appropriate type hash is found.
+ function lookupTypeHash(treeHeight) -> typeHash {
+ // Handle tree heights one through eight.
+ if lt(treeHeight, 9) {
+ // Handle tree heights one through four.
+ if lt(treeHeight, 5) {
+ // Handle tree heights one and two.
+ if lt(treeHeight, 3) {
+ // Utilize branchless logic to determine typehash.
+ typeHash := ternary(
+ eq(treeHeight, 1),
+ BulkOrder_Typehash_Height_One,
+ BulkOrder_Typehash_Height_Two
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle height three and four via branchless logic.
+ typeHash := ternary(
+ eq(treeHeight, 3),
+ BulkOrder_Typehash_Height_Three,
+ BulkOrder_Typehash_Height_Four
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle tree height five and six.
+ if lt(treeHeight, 7) {
+ // Utilize branchless logic to determine typehash.
+ typeHash := ternary(
+ eq(treeHeight, 5),
+ BulkOrder_Typehash_Height_Five,
+ BulkOrder_Typehash_Height_Six
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle height seven and eight via branchless logic.
+ typeHash := ternary(
+ eq(treeHeight, 7),
+ BulkOrder_Typehash_Height_Seven,
+ BulkOrder_Typehash_Height_Eight
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle tree height nine through sixteen.
+ if lt(treeHeight, 17) {
+ // Handle tree height nine through twelve.
+ if lt(treeHeight, 13) {
+ // Handle tree height nine and ten.
+ if lt(treeHeight, 11) {
+ // Utilize branchless logic to determine typehash.
+ typeHash := ternary(
+ eq(treeHeight, 9),
+ BulkOrder_Typehash_Height_Nine,
+ BulkOrder_Typehash_Height_Ten
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle height eleven and twelve via branchless logic.
+ typeHash := ternary(
+ eq(treeHeight, 11),
+ BulkOrder_Typehash_Height_Eleven,
+ BulkOrder_Typehash_Height_Twelve
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle tree height thirteen and fourteen.
+ if lt(treeHeight, 15) {
+ // Utilize branchless logic to determine typehash.
+ typeHash := ternary(
+ eq(treeHeight, 13),
+ BulkOrder_Typehash_Height_Thirteen,
+ BulkOrder_Typehash_Height_Fourteen
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+ // Handle height fifteen and sixteen via branchless logic.
+ typeHash := ternary(
+ eq(treeHeight, 15),
+ BulkOrder_Typehash_Height_Fifteen,
+ BulkOrder_Typehash_Height_Sixteen
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle tree height seventeen through twenty.
+ if lt(treeHeight, 21) {
+ // Handle tree height seventeen and eighteen.
+ if lt(treeHeight, 19) {
+ // Utilize branchless logic to determine typehash.
+ typeHash := ternary(
+ eq(treeHeight, 17),
+ BulkOrder_Typehash_Height_Seventeen,
+ BulkOrder_Typehash_Height_Eighteen
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle height nineteen and twenty via branchless logic.
+ typeHash := ternary(
+ eq(treeHeight, 19),
+ BulkOrder_Typehash_Height_Nineteen,
+ BulkOrder_Typehash_Height_Twenty
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle tree height twenty-one and twenty-two.
+ if lt(treeHeight, 23) {
+ // Utilize branchless logic to determine typehash.
+ typeHash := ternary(
+ eq(treeHeight, 21),
+ BulkOrder_Typehash_Height_TwentyOne,
+ BulkOrder_Typehash_Height_TwentyTwo
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Handle height twenty-three & twenty-four w/ branchless logic.
+ typeHash := ternary(
+ eq(treeHeight, 23),
+ BulkOrder_Typehash_Height_TwentyThree,
+ BulkOrder_Typehash_Height_TwentyFour
+ )
+
+ // Exit the function once typehash has been located.
+ leave
+ }
+
+ // Implement ternary conditional using branchless logic.
+ function ternary(cond, ifTrue, ifFalse) -> c {
+ c := xor(ifFalse, mul(cond, xor(ifFalse, ifTrue)))
+ }
+
+ // Look up the typehash using the supplied tree height.
+ _typeHash := lookupTypeHash(_treeHeight)
+ }
+ }
+
+ /**
+ * @dev Internal view function to ensure that the supplied consideration
+ * array length on a given set of order parameters is not less than the
+ * original consideration array length for that order and to retrieve
+ * the current counter for a given order's offerer and zone and use it
+ * to derive the order hash.
+ *
+ * @param orderParameters The parameters of the order to hash.
+ *
+ * @return The hash.
+ */
+ function _assertConsiderationLengthAndGetOrderHash(
+ OrderParameters memory orderParameters,
+ SeaportInterface seaport
+ ) internal view returns (bytes32) {
+ // Ensure supplied consideration array length is not less than original.
+ _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
+ orderParameters.consideration.length,
+ orderParameters.totalOriginalConsiderationItems
+ );
+
+ // Derive and return order hash using current counter for the offerer.
+ return
+ _deriveOrderHash(
+ orderParameters,
+ _getCounter(seaport, orderParameters.offerer),
+ seaport
+ );
+ }
+
+ function _getCounter(
+ SeaportInterface seaport,
+ address offerer
+ ) internal view returns (uint256) {
+ return seaport.getCounter(offerer);
+ }
+
+ function _deriveOrderHash(
+ OrderParameters memory orderParameters,
+ uint256 counter,
+ SeaportInterface seaport
+ ) internal view returns (bytes32 orderHash) {
+ return
+ seaport.getOrderHash(_toOrderComponents(orderParameters, counter));
+ }
+
+ /**
+ * @dev Converts an OrderParameters struct into an OrderComponents struct.
+ *
+ * @param parameters the OrderParameters struct to convert
+ * @param counter the counter to use for the OrderComponents struct
+ *
+ * @return components the OrderComponents struct
+ */
+ function _toOrderComponents(
+ OrderParameters memory parameters,
+ uint256 counter
+ ) internal pure returns (OrderComponents memory components) {
+ components.offerer = parameters.offerer;
+ components.zone = parameters.zone;
+ components.offer = parameters.offer;
+ components.consideration = parameters.consideration;
+ components.orderType = parameters.orderType;
+ components.startTime = parameters.startTime;
+ components.endTime = parameters.endTime;
+ components.zoneHash = parameters.zoneHash;
+ components.salt = parameters.salt;
+ components.conduitKey = parameters.conduitKey;
+ components.counter = counter;
+ }
+
+ /**
+ * @dev Internal pure function to efficiently derive an digest to sign for
+ * an order in accordance with EIP-712.
+ *
+ * @param domainSeparator The domain separator.
+ * @param orderHash The order hash.
+ *
+ * @return value The hash.
+ */
+ function _deriveEIP712Digest(
+ bytes32 domainSeparator,
+ bytes32 orderHash
+ ) internal pure returns (bytes32 value) {
+ // Leverage scratch space to perform an efficient hash.
+ assembly {
+ // Place the EIP-712 prefix at the start of scratch space.
+ mstore(0, EIP_712_PREFIX)
+
+ // Place the domain separator in the next region of scratch space.
+ mstore(EIP712_DomainSeparator_offset, domainSeparator)
+
+ // Place the order hash in scratch space, spilling into the first
+ // two bytes of the free memory pointer — this should never be set
+ // as memory cannot be expanded to that size, and will be zeroed out
+ // after the hash is performed.
+ mstore(EIP712_OrderHash_offset, orderHash)
+
+ // Hash the relevant region (65 bytes).
+ value := keccak256(0, EIP712_DigestPayload_size)
+
+ // Clear out the dirtied bits in the memory pointer.
+ mstore(EIP712_OrderHash_offset, 0)
+ }
+ }
+
+ /**
+ * @dev Internal pure function to ensure that the supplied consideration
+ * array length for an order to be fulfilled is not less than the
+ * original consideration array length for that order.
+ *
+ * @param suppliedConsiderationItemTotal The number of consideration items
+ * supplied when fulfilling the order.
+ * @param originalConsiderationItemTotal The number of consideration items
+ * supplied on initial order creation.
+ */
+ function _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
+ uint256 suppliedConsiderationItemTotal,
+ uint256 originalConsiderationItemTotal
+ ) internal pure {
+ // Ensure supplied consideration array length is not less than original.
+ if (suppliedConsiderationItemTotal < originalConsiderationItemTotal) {
+ _revertMissingOriginalConsiderationItems();
+ }
+ }
+}
diff --git a/contracts/helpers/order-validator/lib/SeaportValidatorHelper.sol b/contracts/helpers/order-validator/lib/SeaportValidatorHelper.sol
index e597cb453..2ea2fa58c 100644
--- a/contracts/helpers/order-validator/lib/SeaportValidatorHelper.sol
+++ b/contracts/helpers/order-validator/lib/SeaportValidatorHelper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { ItemType } from "../../../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
Order,
OrderParameters,
@@ -10,30 +10,32 @@ import {
ConsiderationItem,
Schema,
ZoneParameters
-} from "../../../lib/ConsiderationStructs.sol";
-import { ConsiderationTypeHashes } from "../lib/ConsiderationTypeHashes.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+import { ConsiderationTypeHashes } from "./ConsiderationTypeHashes.sol";
import {
ConsiderationInterface
-} from "../../../interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
ConduitControllerInterface
-} from "../../../interfaces/ConduitControllerInterface.sol";
+} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";
import {
ContractOffererInterface
-} from "../../../interfaces/ContractOffererInterface.sol";
-import { ZoneInterface } from "../../../interfaces/ZoneInterface.sol";
-import { GettersAndDerivers } from "../../../lib/GettersAndDerivers.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
+import {
+ GettersAndDerivers
+} from "seaport-core/src/lib/GettersAndDerivers.sol";
import {
SeaportValidatorInterface
} from "../lib/SeaportValidatorInterface.sol";
-import { ZoneInterface } from "../../../interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../../../interfaces/AbridgedTokenInterfaces.sol";
-import { IERC165 } from "../../../interfaces/IERC165.sol";
-import { IERC2981 } from "../../../interfaces/IERC2981.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
+import { IERC165 } from "@openzeppelin/contracts/interfaces/IERC165.sol";
+import { IERC2981 } from "@openzeppelin/contracts/interfaces/IERC2981.sol";
import {
ErrorsAndWarnings,
ErrorsAndWarningsLib
@@ -59,8 +61,8 @@ import {
SignatureIssue,
GenericIssue,
ConsiderationItemConfiguration
-} from "../lib/SeaportValidatorTypes.sol";
-import { Verifiers } from "../../../lib/Verifiers.sol";
+} from "./SeaportValidatorTypes.sol";
+import { Verifiers } from "seaport-core/src/lib/Verifiers.sol";
/**
* @title SeaportValidator
diff --git a/contracts/helpers/order-validator/lib/SeaportValidatorInterface.sol b/contracts/helpers/order-validator/lib/SeaportValidatorInterface.sol
index 5dd5925a6..3d0abd321 100644
--- a/contracts/helpers/order-validator/lib/SeaportValidatorInterface.sol
+++ b/contracts/helpers/order-validator/lib/SeaportValidatorInterface.sol
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
-import { ItemType } from "../../../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
Order,
OrderParameters,
ZoneParameters
-} from "../../../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ErrorsAndWarnings } from "./ErrorsAndWarnings.sol";
import { ValidationConfiguration } from "./SeaportValidatorTypes.sol";
@@ -29,7 +29,7 @@ interface SeaportValidatorInterface {
function isValidOrder(
Order calldata order,
address seaportAddress
- ) external returns (ErrorsAndWarnings memory errorsAndWarnings);
+ ) external view returns (ErrorsAndWarnings memory errorsAndWarnings);
/**
* @notice Same as `isValidOrder` but allows for more configuration related to fee validation.
@@ -37,14 +37,6 @@ interface SeaportValidatorInterface {
function isValidOrderWithConfiguration(
ValidationConfiguration memory validationConfiguration,
Order memory order
- ) external returns (ErrorsAndWarnings memory errorsAndWarnings);
-
- /**
- * @notice Same as `isValidOrderWithConfiguration` but doesn't call `validate` on Seaport.
- */
- function isValidOrderWithConfigurationReadOnly(
- ValidationConfiguration memory validationConfiguration,
- Order memory order
) external view returns (ErrorsAndWarnings memory errorsAndWarnings);
/**
diff --git a/contracts/helpers/sol/ConduitControllerInterface.sol b/contracts/helpers/sol/ConduitControllerInterface.sol
deleted file mode 100644
index b9f1c4b41..000000000
--- a/contracts/helpers/sol/ConduitControllerInterface.sol
+++ /dev/null
@@ -1,6 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- ConduitControllerInterface
-} from "../../interfaces/ConduitControllerInterface.sol";
diff --git a/contracts/helpers/sol/ConduitInterface.sol b/contracts/helpers/sol/ConduitInterface.sol
deleted file mode 100644
index 5b634ad5a..000000000
--- a/contracts/helpers/sol/ConduitInterface.sol
+++ /dev/null
@@ -1,4 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { ConduitInterface } from "../../interfaces/ConduitInterface.sol";
diff --git a/contracts/helpers/sol/ContractOffererInterface.sol b/contracts/helpers/sol/ContractOffererInterface.sol
deleted file mode 100644
index 42b47e1c2..000000000
--- a/contracts/helpers/sol/ContractOffererInterface.sol
+++ /dev/null
@@ -1,6 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- ContractOffererInterface
-} from "../../interfaces/ContractOffererInterface.sol";
diff --git a/contracts/helpers/sol/ErrorSpaceEnums.sol b/contracts/helpers/sol/ErrorSpaceEnums.sol
deleted file mode 100644
index cecd2bb41..000000000
--- a/contracts/helpers/sol/ErrorSpaceEnums.sol
+++ /dev/null
@@ -1,110 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-enum ErrorType {
- CORE_CONSIDERATION_ERROR,
- TOKEN_TRANSFER_ERROR,
- SIGNATURE_VERIFICATION_ERROR,
- REENTRANCY_ERROR,
- CONDUIT_ERROR,
- ZONE_ERROR,
- AMOUNT_DERIVATION_ERROR,
- TRANSFER_HELPER_ERROR,
- CRITERIA_RESOLUTION_ERROR,
- FULFILLMENT_APPLICATION_ERROR,
- PAUSABLE_ZONE_ERROR,
- ZONE_INTERACTION_ERROR
-}
-
-enum CoreConsiderationErrors {
- BAD_FRACTION,
- CANNOT_CANCEL_ORDER,
- CONSIDERATION_LENGTH_NOT_EQUAL_TO_TOTAL_ORIGINAL,
- CONSIDERATION_NOT_MET,
- INSUFFICIENT_NATIVE_TOKENS_SUPPLIED,
- INVALID_BASIC_ORDER_PARAMETER_ENCODING,
- INVALID_CALL_TO_CONDUIT,
- INVALID_MSG_VALUE,
- INVALID_NATIVE_OFFER_ITEM,
- INVALID_TIME,
- MISMATCHED_OFFER_AND_CONSIDERATION_COMPONENTS,
- MISSING_ORIGINAL_CONSIDERATION_ITEMS,
- NO_SPECIFIED_ORDERS_AVAILABLE,
- ORDER_ALREADY_FILLED,
- ORDER_IS_CANCELLED,
- ORDER_PARTIALLY_FILLED,
- PARTIAL_FILLS_NOT_ENABLED_FOR_ORDER
-}
-
-enum TokenTransferrerErrors {
- INVALID_ERC721_TRANSFER_AMOUNT,
- MISSING_ITEM_AMOUNT,
- UNUSED_ITEM_PARAMETERS,
- TOKEN_TRANSFER_GENERIC_FAILURE,
- ERC1155_BATCH_TRANSFER_GENERIC_FAILURE,
- BAD_RETURN_VALUE_FROM_ERC20_ON_TRANSFER,
- NO_CONTRACT,
- INVALID1155_BATCH_TRANSFER_ENCODING
-}
-
-enum SignatureVerificationErrors {
- BAD_SIGNATURE_V,
- INVALID_SIGNER,
- INVALID_SIGNATURE,
- BAD_CONTRACT_SIGNATURE
-}
-
-enum ReentrancyErrors {
- NO_REENTRANT_CALLS
-}
-
-enum AmountDerivationErrors {
- INEXACT_FRACTION
-}
-
-enum TransferHelperErrors {
- INVALID_ITEM_TYPE,
- INVALID_ERC721_TRANSFER_AMOUNT,
- INVALID_ERC721_RECIPIENT,
- ERC721_RECEIVER_ERROR_REVERT_BYTES,
- ERC721_RECEIVER_ERROR_REVERT_STRING,
- INVALID_ERC20_IDENTIFIER,
- RECIPIENT_CANNOT_BE_ZERO_ADDRESS,
- INVALID_CONDUIT,
- CONDUIT_ERROR_REVERT_STRING,
- CONDUIT_ERROR_REVERT_BYTES
-}
-
-enum CriteriaResolutionErrors {
- ORDER_CRITERIA_RESOLVER_OUT_OF_RANGE,
- UNRESOLVED_OFFER_CRITERIA,
- UNRESOLVED_CONSIDERATION_CRITERIA,
- OFFER_CRITERIA_RESOLVER_OUT_OF_RANGE,
- CONSIDERATION_CRITERIA_RESOLVER_OUT_OF_RANGE,
- CRITERIA_NOT_ENABLED_FOR_ITEM,
- INVALID_PROOF
-}
-
-enum FulfillmentApplicationErrors {
- MISSING_FULFILLMENT_COMPONENT_ON_AGGREGATION,
- OFFER_AND_CONSIDERATION_REQUIRED_ON_FULFILLMENT,
- MISMATCHED_FULFILLMENT_OFFER_AND_CONSIDERATION_COMPONENTS,
- INVALID_FULFILLMENT_COMPONENT_DATA
-}
-
-enum PausableZoneErrors {
- INVALID_PAUSER,
- INVALID_OPERATOR,
- INVALID_CONTROLLER,
- ZONE_ALREADY_EXISTS,
- CALLER_IS_NOT_OWNER,
- CALLER_IS_NOT_OPERATOR,
- OWNER_CAN_NOT_BE_SET_AS_ZERO,
- PAUSER_CAN_NOT_BE_SET_AS_ZERO,
- CALLER_IS_NOT_POTENTIAL_OWNER
-}
-
-enum ZoneInteractionErrors {
- INVALID_RESTRICTED_ORDER,
- INVALID_CONTRACT_ORDER
-}
diff --git a/contracts/helpers/sol/README.md b/contracts/helpers/sol/README.md
deleted file mode 100644
index d8e08c779..000000000
--- a/contracts/helpers/sol/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# seaport-sol
-
-## Note
-These helpers are intended for use with Forge tests and scripts. As such, they are highly gas-inefficient.
-
-They are still experimental, not thoroughly-tested, and not intended for production use.
\ No newline at end of file
diff --git a/contracts/helpers/sol/SeaportEnums.sol b/contracts/helpers/sol/SeaportEnums.sol
deleted file mode 100644
index ed84184b2..000000000
--- a/contracts/helpers/sol/SeaportEnums.sol
+++ /dev/null
@@ -1,4 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import "../../lib/ConsiderationEnums.sol";
diff --git a/contracts/helpers/sol/SeaportInterface.sol b/contracts/helpers/sol/SeaportInterface.sol
deleted file mode 100644
index 04eb51311..000000000
--- a/contracts/helpers/sol/SeaportInterface.sol
+++ /dev/null
@@ -1,6 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- ConsiderationInterface as SeaportInterface
-} from "../../interfaces/ConsiderationInterface.sol";
diff --git a/contracts/helpers/sol/SeaportSol.sol b/contracts/helpers/sol/SeaportSol.sol
deleted file mode 100644
index 49c79ef4c..000000000
--- a/contracts/helpers/sol/SeaportSol.sol
+++ /dev/null
@@ -1,28 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import "./SeaportStructs.sol";
-import "./SeaportEnums.sol";
-import "./lib/SeaportStructLib.sol";
-import "./lib/SeaportEnumsLib.sol";
-import "./fulfillments/lib/Structs.sol";
-import { SeaportArrays } from "./lib/SeaportArrays.sol";
-import { SeaportInterface } from "./SeaportInterface.sol";
-import {
- ConsiderationInterface
-} from "../../interfaces/ConsiderationInterface.sol";
-import { ConduitInterface } from "./ConduitInterface.sol";
-import { ConduitControllerInterface } from "./ConduitControllerInterface.sol";
-import { ZoneInterface } from "./ZoneInterface.sol";
-import { ContractOffererInterface } from "./ContractOffererInterface.sol";
-import { Solarray } from "./Solarray.sol";
-import {
- FulfillAvailableHelper
-} from "./fulfillments/available/FulfillAvailableHelper.sol";
-import {
- MatchFulfillmentHelper
-} from "./fulfillments/match/MatchFulfillmentHelper.sol";
-import {
- MatchComponent,
- MatchComponentType
-} from "./lib/types/MatchComponentType.sol";
diff --git a/contracts/helpers/sol/SeaportStructs.sol b/contracts/helpers/sol/SeaportStructs.sol
deleted file mode 100644
index 505e04960..000000000
--- a/contracts/helpers/sol/SeaportStructs.sol
+++ /dev/null
@@ -1,4 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import "../../lib/ConsiderationStructs.sol";
diff --git a/contracts/helpers/sol/Solarray.sol b/contracts/helpers/sol/Solarray.sol
deleted file mode 100644
index 827bbf4c3..000000000
--- a/contracts/helpers/sol/Solarray.sol
+++ /dev/null
@@ -1,2098 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity >=0.6.2 <0.9.0;
-
-library Solarray {
- function uint8s(uint8 a) internal pure returns (uint8[] memory) {
- uint8[] memory arr = new uint8[](1);
- arr[0] = a;
- return arr;
- }
-
- function uint8s(uint8 a, uint8 b) internal pure returns (uint8[] memory) {
- uint8[] memory arr = new uint8[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uint8s(
- uint8 a,
- uint8 b,
- uint8 c
- ) internal pure returns (uint8[] memory) {
- uint8[] memory arr = new uint8[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uint8s(
- uint8 a,
- uint8 b,
- uint8 c,
- uint8 d
- ) internal pure returns (uint8[] memory) {
- uint8[] memory arr = new uint8[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uint8s(
- uint8 a,
- uint8 b,
- uint8 c,
- uint8 d,
- uint8 e
- ) internal pure returns (uint8[] memory) {
- uint8[] memory arr = new uint8[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uint8s(
- uint8 a,
- uint8 b,
- uint8 c,
- uint8 d,
- uint8 e,
- uint8 f
- ) internal pure returns (uint8[] memory) {
- uint8[] memory arr = new uint8[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uint8s(
- uint8 a,
- uint8 b,
- uint8 c,
- uint8 d,
- uint8 e,
- uint8 f,
- uint8 g
- ) internal pure returns (uint8[] memory) {
- uint8[] memory arr = new uint8[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function uint16s(uint16 a) internal pure returns (uint16[] memory) {
- uint16[] memory arr = new uint16[](1);
- arr[0] = a;
- return arr;
- }
-
- function uint16s(
- uint16 a,
- uint16 b
- ) internal pure returns (uint16[] memory) {
- uint16[] memory arr = new uint16[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uint16s(
- uint16 a,
- uint16 b,
- uint16 c
- ) internal pure returns (uint16[] memory) {
- uint16[] memory arr = new uint16[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uint16s(
- uint16 a,
- uint16 b,
- uint16 c,
- uint16 d
- ) internal pure returns (uint16[] memory) {
- uint16[] memory arr = new uint16[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uint16s(
- uint16 a,
- uint16 b,
- uint16 c,
- uint16 d,
- uint16 e
- ) internal pure returns (uint16[] memory) {
- uint16[] memory arr = new uint16[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uint16s(
- uint16 a,
- uint16 b,
- uint16 c,
- uint16 d,
- uint16 e,
- uint16 f
- ) internal pure returns (uint16[] memory) {
- uint16[] memory arr = new uint16[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uint16s(
- uint16 a,
- uint16 b,
- uint16 c,
- uint16 d,
- uint16 e,
- uint16 f,
- uint16 g
- ) internal pure returns (uint16[] memory) {
- uint16[] memory arr = new uint16[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function uint32s(uint32 a) internal pure returns (uint32[] memory) {
- uint32[] memory arr = new uint32[](1);
- arr[0] = a;
- return arr;
- }
-
- function uint32s(
- uint32 a,
- uint32 b
- ) internal pure returns (uint32[] memory) {
- uint32[] memory arr = new uint32[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uint32s(
- uint32 a,
- uint32 b,
- uint32 c
- ) internal pure returns (uint32[] memory) {
- uint32[] memory arr = new uint32[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uint32s(
- uint32 a,
- uint32 b,
- uint32 c,
- uint32 d
- ) internal pure returns (uint32[] memory) {
- uint32[] memory arr = new uint32[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uint32s(
- uint32 a,
- uint32 b,
- uint32 c,
- uint32 d,
- uint32 e
- ) internal pure returns (uint32[] memory) {
- uint32[] memory arr = new uint32[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uint32s(
- uint32 a,
- uint32 b,
- uint32 c,
- uint32 d,
- uint32 e,
- uint32 f
- ) internal pure returns (uint32[] memory) {
- uint32[] memory arr = new uint32[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uint32s(
- uint32 a,
- uint32 b,
- uint32 c,
- uint32 d,
- uint32 e,
- uint32 f,
- uint32 g
- ) internal pure returns (uint32[] memory) {
- uint32[] memory arr = new uint32[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function uint40s(uint40 a) internal pure returns (uint40[] memory) {
- uint40[] memory arr = new uint40[](1);
- arr[0] = a;
- return arr;
- }
-
- function uint40s(
- uint40 a,
- uint40 b
- ) internal pure returns (uint40[] memory) {
- uint40[] memory arr = new uint40[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uint40s(
- uint40 a,
- uint40 b,
- uint40 c
- ) internal pure returns (uint40[] memory) {
- uint40[] memory arr = new uint40[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uint40s(
- uint40 a,
- uint40 b,
- uint40 c,
- uint40 d
- ) internal pure returns (uint40[] memory) {
- uint40[] memory arr = new uint40[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uint40s(
- uint40 a,
- uint40 b,
- uint40 c,
- uint40 d,
- uint40 e
- ) internal pure returns (uint40[] memory) {
- uint40[] memory arr = new uint40[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uint40s(
- uint40 a,
- uint40 b,
- uint40 c,
- uint40 d,
- uint40 e,
- uint40 f
- ) internal pure returns (uint40[] memory) {
- uint40[] memory arr = new uint40[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uint40s(
- uint40 a,
- uint40 b,
- uint40 c,
- uint40 d,
- uint40 e,
- uint40 f,
- uint40 g
- ) internal pure returns (uint40[] memory) {
- uint40[] memory arr = new uint40[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function uint64s(uint64 a) internal pure returns (uint64[] memory) {
- uint64[] memory arr = new uint64[](1);
- arr[0] = a;
- return arr;
- }
-
- function uint64s(
- uint64 a,
- uint64 b
- ) internal pure returns (uint64[] memory) {
- uint64[] memory arr = new uint64[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uint64s(
- uint64 a,
- uint64 b,
- uint64 c
- ) internal pure returns (uint64[] memory) {
- uint64[] memory arr = new uint64[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uint64s(
- uint64 a,
- uint64 b,
- uint64 c,
- uint64 d
- ) internal pure returns (uint64[] memory) {
- uint64[] memory arr = new uint64[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uint64s(
- uint64 a,
- uint64 b,
- uint64 c,
- uint64 d,
- uint64 e
- ) internal pure returns (uint64[] memory) {
- uint64[] memory arr = new uint64[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uint64s(
- uint64 a,
- uint64 b,
- uint64 c,
- uint64 d,
- uint64 e,
- uint64 f
- ) internal pure returns (uint64[] memory) {
- uint64[] memory arr = new uint64[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uint64s(
- uint64 a,
- uint64 b,
- uint64 c,
- uint64 d,
- uint64 e,
- uint64 f,
- uint64 g
- ) internal pure returns (uint64[] memory) {
- uint64[] memory arr = new uint64[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function uint128s(uint128 a) internal pure returns (uint128[] memory) {
- uint128[] memory arr = new uint128[](1);
- arr[0] = a;
- return arr;
- }
-
- function uint128s(
- uint128 a,
- uint128 b
- ) internal pure returns (uint128[] memory) {
- uint128[] memory arr = new uint128[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uint128s(
- uint128 a,
- uint128 b,
- uint128 c
- ) internal pure returns (uint128[] memory) {
- uint128[] memory arr = new uint128[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uint128s(
- uint128 a,
- uint128 b,
- uint128 c,
- uint128 d
- ) internal pure returns (uint128[] memory) {
- uint128[] memory arr = new uint128[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uint128s(
- uint128 a,
- uint128 b,
- uint128 c,
- uint128 d,
- uint128 e
- ) internal pure returns (uint128[] memory) {
- uint128[] memory arr = new uint128[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uint128s(
- uint128 a,
- uint128 b,
- uint128 c,
- uint128 d,
- uint128 e,
- uint128 f
- ) internal pure returns (uint128[] memory) {
- uint128[] memory arr = new uint128[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uint128s(
- uint128 a,
- uint128 b,
- uint128 c,
- uint128 d,
- uint128 e,
- uint128 f,
- uint128 g
- ) internal pure returns (uint128[] memory) {
- uint128[] memory arr = new uint128[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function uint256s(uint256 a) internal pure returns (uint256[] memory) {
- uint256[] memory arr = new uint256[](1);
- arr[0] = a;
- return arr;
- }
-
- function uint256s(
- uint256 a,
- uint256 b
- ) internal pure returns (uint256[] memory) {
- uint256[] memory arr = new uint256[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uint256s(
- uint256 a,
- uint256 b,
- uint256 c
- ) internal pure returns (uint256[] memory) {
- uint256[] memory arr = new uint256[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uint256s(
- uint256 a,
- uint256 b,
- uint256 c,
- uint256 d
- ) internal pure returns (uint256[] memory) {
- uint256[] memory arr = new uint256[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uint256s(
- uint256 a,
- uint256 b,
- uint256 c,
- uint256 d,
- uint256 e
- ) internal pure returns (uint256[] memory) {
- uint256[] memory arr = new uint256[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uint256s(
- uint256 a,
- uint256 b,
- uint256 c,
- uint256 d,
- uint256 e,
- uint256 f
- ) internal pure returns (uint256[] memory) {
- uint256[] memory arr = new uint256[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uint256s(
- uint256 a,
- uint256 b,
- uint256 c,
- uint256 d,
- uint256 e,
- uint256 f,
- uint256 g
- ) internal pure returns (uint256[] memory) {
- uint256[] memory arr = new uint256[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function int8s(int8 a) internal pure returns (int8[] memory) {
- int8[] memory arr = new int8[](1);
- arr[0] = a;
- return arr;
- }
-
- function int8s(int8 a, int8 b) internal pure returns (int8[] memory) {
- int8[] memory arr = new int8[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function int8s(
- int8 a,
- int8 b,
- int8 c
- ) internal pure returns (int8[] memory) {
- int8[] memory arr = new int8[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function int8s(
- int8 a,
- int8 b,
- int8 c,
- int8 d
- ) internal pure returns (int8[] memory) {
- int8[] memory arr = new int8[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function int8s(
- int8 a,
- int8 b,
- int8 c,
- int8 d,
- int8 e
- ) internal pure returns (int8[] memory) {
- int8[] memory arr = new int8[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function int8s(
- int8 a,
- int8 b,
- int8 c,
- int8 d,
- int8 e,
- int8 f
- ) internal pure returns (int8[] memory) {
- int8[] memory arr = new int8[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function int8s(
- int8 a,
- int8 b,
- int8 c,
- int8 d,
- int8 e,
- int8 f,
- int8 g
- ) internal pure returns (int8[] memory) {
- int8[] memory arr = new int8[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function int16s(int16 a) internal pure returns (int16[] memory) {
- int16[] memory arr = new int16[](1);
- arr[0] = a;
- return arr;
- }
-
- function int16s(int16 a, int16 b) internal pure returns (int16[] memory) {
- int16[] memory arr = new int16[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function int16s(
- int16 a,
- int16 b,
- int16 c
- ) internal pure returns (int16[] memory) {
- int16[] memory arr = new int16[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function int16s(
- int16 a,
- int16 b,
- int16 c,
- int16 d
- ) internal pure returns (int16[] memory) {
- int16[] memory arr = new int16[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function int16s(
- int16 a,
- int16 b,
- int16 c,
- int16 d,
- int16 e
- ) internal pure returns (int16[] memory) {
- int16[] memory arr = new int16[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function int16s(
- int16 a,
- int16 b,
- int16 c,
- int16 d,
- int16 e,
- int16 f
- ) internal pure returns (int16[] memory) {
- int16[] memory arr = new int16[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function int16s(
- int16 a,
- int16 b,
- int16 c,
- int16 d,
- int16 e,
- int16 f,
- int16 g
- ) internal pure returns (int16[] memory) {
- int16[] memory arr = new int16[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function int32s(int32 a) internal pure returns (int32[] memory) {
- int32[] memory arr = new int32[](1);
- arr[0] = a;
- return arr;
- }
-
- function int32s(int32 a, int32 b) internal pure returns (int32[] memory) {
- int32[] memory arr = new int32[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function int32s(
- int32 a,
- int32 b,
- int32 c
- ) internal pure returns (int32[] memory) {
- int32[] memory arr = new int32[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function int32s(
- int32 a,
- int32 b,
- int32 c,
- int32 d
- ) internal pure returns (int32[] memory) {
- int32[] memory arr = new int32[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function int32s(
- int32 a,
- int32 b,
- int32 c,
- int32 d,
- int32 e
- ) internal pure returns (int32[] memory) {
- int32[] memory arr = new int32[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function int32s(
- int32 a,
- int32 b,
- int32 c,
- int32 d,
- int32 e,
- int32 f
- ) internal pure returns (int32[] memory) {
- int32[] memory arr = new int32[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function int32s(
- int32 a,
- int32 b,
- int32 c,
- int32 d,
- int32 e,
- int32 f,
- int32 g
- ) internal pure returns (int32[] memory) {
- int32[] memory arr = new int32[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function int64s(int64 a) internal pure returns (int64[] memory) {
- int64[] memory arr = new int64[](1);
- arr[0] = a;
- return arr;
- }
-
- function int64s(int64 a, int64 b) internal pure returns (int64[] memory) {
- int64[] memory arr = new int64[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function int64s(
- int64 a,
- int64 b,
- int64 c
- ) internal pure returns (int64[] memory) {
- int64[] memory arr = new int64[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function int64s(
- int64 a,
- int64 b,
- int64 c,
- int64 d
- ) internal pure returns (int64[] memory) {
- int64[] memory arr = new int64[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function int64s(
- int64 a,
- int64 b,
- int64 c,
- int64 d,
- int64 e
- ) internal pure returns (int64[] memory) {
- int64[] memory arr = new int64[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function int64s(
- int64 a,
- int64 b,
- int64 c,
- int64 d,
- int64 e,
- int64 f
- ) internal pure returns (int64[] memory) {
- int64[] memory arr = new int64[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function int64s(
- int64 a,
- int64 b,
- int64 c,
- int64 d,
- int64 e,
- int64 f,
- int64 g
- ) internal pure returns (int64[] memory) {
- int64[] memory arr = new int64[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function int128s(int128 a) internal pure returns (int128[] memory) {
- int128[] memory arr = new int128[](1);
- arr[0] = a;
- return arr;
- }
-
- function int128s(
- int128 a,
- int128 b
- ) internal pure returns (int128[] memory) {
- int128[] memory arr = new int128[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function int128s(
- int128 a,
- int128 b,
- int128 c
- ) internal pure returns (int128[] memory) {
- int128[] memory arr = new int128[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function int128s(
- int128 a,
- int128 b,
- int128 c,
- int128 d
- ) internal pure returns (int128[] memory) {
- int128[] memory arr = new int128[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function int128s(
- int128 a,
- int128 b,
- int128 c,
- int128 d,
- int128 e
- ) internal pure returns (int128[] memory) {
- int128[] memory arr = new int128[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function int128s(
- int128 a,
- int128 b,
- int128 c,
- int128 d,
- int128 e,
- int128 f
- ) internal pure returns (int128[] memory) {
- int128[] memory arr = new int128[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function int128s(
- int128 a,
- int128 b,
- int128 c,
- int128 d,
- int128 e,
- int128 f,
- int128 g
- ) internal pure returns (int128[] memory) {
- int128[] memory arr = new int128[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function int256s(int256 a) internal pure returns (int256[] memory) {
- int256[] memory arr = new int256[](1);
- arr[0] = a;
- return arr;
- }
-
- function int256s(
- int256 a,
- int256 b
- ) internal pure returns (int256[] memory) {
- int256[] memory arr = new int256[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function int256s(
- int256 a,
- int256 b,
- int256 c
- ) internal pure returns (int256[] memory) {
- int256[] memory arr = new int256[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function int256s(
- int256 a,
- int256 b,
- int256 c,
- int256 d
- ) internal pure returns (int256[] memory) {
- int256[] memory arr = new int256[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function int256s(
- int256 a,
- int256 b,
- int256 c,
- int256 d,
- int256 e
- ) internal pure returns (int256[] memory) {
- int256[] memory arr = new int256[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function int256s(
- int256 a,
- int256 b,
- int256 c,
- int256 d,
- int256 e,
- int256 f
- ) internal pure returns (int256[] memory) {
- int256[] memory arr = new int256[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function int256s(
- int256 a,
- int256 b,
- int256 c,
- int256 d,
- int256 e,
- int256 f,
- int256 g
- ) internal pure returns (int256[] memory) {
- int256[] memory arr = new int256[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function bytes1s(bytes1 a) internal pure returns (bytes1[] memory) {
- bytes1[] memory arr = new bytes1[](1);
- arr[0] = a;
- return arr;
- }
-
- function bytes1s(
- bytes1 a,
- bytes1 b
- ) internal pure returns (bytes1[] memory) {
- bytes1[] memory arr = new bytes1[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function bytes1s(
- bytes1 a,
- bytes1 b,
- bytes1 c
- ) internal pure returns (bytes1[] memory) {
- bytes1[] memory arr = new bytes1[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function bytes1s(
- bytes1 a,
- bytes1 b,
- bytes1 c,
- bytes1 d
- ) internal pure returns (bytes1[] memory) {
- bytes1[] memory arr = new bytes1[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function bytes1s(
- bytes1 a,
- bytes1 b,
- bytes1 c,
- bytes1 d,
- bytes1 e
- ) internal pure returns (bytes1[] memory) {
- bytes1[] memory arr = new bytes1[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function bytes1s(
- bytes1 a,
- bytes1 b,
- bytes1 c,
- bytes1 d,
- bytes1 e,
- bytes1 f
- ) internal pure returns (bytes1[] memory) {
- bytes1[] memory arr = new bytes1[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function bytes1s(
- bytes1 a,
- bytes1 b,
- bytes1 c,
- bytes1 d,
- bytes1 e,
- bytes1 f,
- bytes1 g
- ) internal pure returns (bytes1[] memory) {
- bytes1[] memory arr = new bytes1[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function bytes8s(bytes8 a) internal pure returns (bytes8[] memory) {
- bytes8[] memory arr = new bytes8[](1);
- arr[0] = a;
- return arr;
- }
-
- function bytes8s(
- bytes8 a,
- bytes8 b
- ) internal pure returns (bytes8[] memory) {
- bytes8[] memory arr = new bytes8[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function bytes8s(
- bytes8 a,
- bytes8 b,
- bytes8 c
- ) internal pure returns (bytes8[] memory) {
- bytes8[] memory arr = new bytes8[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function bytes8s(
- bytes8 a,
- bytes8 b,
- bytes8 c,
- bytes8 d
- ) internal pure returns (bytes8[] memory) {
- bytes8[] memory arr = new bytes8[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function bytes8s(
- bytes8 a,
- bytes8 b,
- bytes8 c,
- bytes8 d,
- bytes8 e
- ) internal pure returns (bytes8[] memory) {
- bytes8[] memory arr = new bytes8[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function bytes8s(
- bytes8 a,
- bytes8 b,
- bytes8 c,
- bytes8 d,
- bytes8 e,
- bytes8 f
- ) internal pure returns (bytes8[] memory) {
- bytes8[] memory arr = new bytes8[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function bytes8s(
- bytes8 a,
- bytes8 b,
- bytes8 c,
- bytes8 d,
- bytes8 e,
- bytes8 f,
- bytes8 g
- ) internal pure returns (bytes8[] memory) {
- bytes8[] memory arr = new bytes8[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function bytes16s(bytes16 a) internal pure returns (bytes16[] memory) {
- bytes16[] memory arr = new bytes16[](1);
- arr[0] = a;
- return arr;
- }
-
- function bytes16s(
- bytes16 a,
- bytes16 b
- ) internal pure returns (bytes16[] memory) {
- bytes16[] memory arr = new bytes16[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function bytes16s(
- bytes16 a,
- bytes16 b,
- bytes16 c
- ) internal pure returns (bytes16[] memory) {
- bytes16[] memory arr = new bytes16[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function bytes16s(
- bytes16 a,
- bytes16 b,
- bytes16 c,
- bytes16 d
- ) internal pure returns (bytes16[] memory) {
- bytes16[] memory arr = new bytes16[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function bytes16s(
- bytes16 a,
- bytes16 b,
- bytes16 c,
- bytes16 d,
- bytes16 e
- ) internal pure returns (bytes16[] memory) {
- bytes16[] memory arr = new bytes16[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function bytes16s(
- bytes16 a,
- bytes16 b,
- bytes16 c,
- bytes16 d,
- bytes16 e,
- bytes16 f
- ) internal pure returns (bytes16[] memory) {
- bytes16[] memory arr = new bytes16[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function bytes16s(
- bytes16 a,
- bytes16 b,
- bytes16 c,
- bytes16 d,
- bytes16 e,
- bytes16 f,
- bytes16 g
- ) internal pure returns (bytes16[] memory) {
- bytes16[] memory arr = new bytes16[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function bytes20s(bytes20 a) internal pure returns (bytes20[] memory) {
- bytes20[] memory arr = new bytes20[](1);
- arr[0] = a;
- return arr;
- }
-
- function bytes20s(
- bytes20 a,
- bytes20 b
- ) internal pure returns (bytes20[] memory) {
- bytes20[] memory arr = new bytes20[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function bytes20s(
- bytes20 a,
- bytes20 b,
- bytes20 c
- ) internal pure returns (bytes20[] memory) {
- bytes20[] memory arr = new bytes20[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function bytes20s(
- bytes20 a,
- bytes20 b,
- bytes20 c,
- bytes20 d
- ) internal pure returns (bytes20[] memory) {
- bytes20[] memory arr = new bytes20[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function bytes20s(
- bytes20 a,
- bytes20 b,
- bytes20 c,
- bytes20 d,
- bytes20 e
- ) internal pure returns (bytes20[] memory) {
- bytes20[] memory arr = new bytes20[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function bytes20s(
- bytes20 a,
- bytes20 b,
- bytes20 c,
- bytes20 d,
- bytes20 e,
- bytes20 f
- ) internal pure returns (bytes20[] memory) {
- bytes20[] memory arr = new bytes20[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function bytes20s(
- bytes20 a,
- bytes20 b,
- bytes20 c,
- bytes20 d,
- bytes20 e,
- bytes20 f,
- bytes20 g
- ) internal pure returns (bytes20[] memory) {
- bytes20[] memory arr = new bytes20[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function bytes32s(bytes32 a) internal pure returns (bytes32[] memory) {
- bytes32[] memory arr = new bytes32[](1);
- arr[0] = a;
- return arr;
- }
-
- function bytes32s(
- bytes32 a,
- bytes32 b
- ) internal pure returns (bytes32[] memory) {
- bytes32[] memory arr = new bytes32[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function bytes32s(
- bytes32 a,
- bytes32 b,
- bytes32 c
- ) internal pure returns (bytes32[] memory) {
- bytes32[] memory arr = new bytes32[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function bytes32s(
- bytes32 a,
- bytes32 b,
- bytes32 c,
- bytes32 d
- ) internal pure returns (bytes32[] memory) {
- bytes32[] memory arr = new bytes32[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function bytes32s(
- bytes32 a,
- bytes32 b,
- bytes32 c,
- bytes32 d,
- bytes32 e
- ) internal pure returns (bytes32[] memory) {
- bytes32[] memory arr = new bytes32[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function bytes32s(
- bytes32 a,
- bytes32 b,
- bytes32 c,
- bytes32 d,
- bytes32 e,
- bytes32 f
- ) internal pure returns (bytes32[] memory) {
- bytes32[] memory arr = new bytes32[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function bytes32s(
- bytes32 a,
- bytes32 b,
- bytes32 c,
- bytes32 d,
- bytes32 e,
- bytes32 f,
- bytes32 g
- ) internal pure returns (bytes32[] memory) {
- bytes32[] memory arr = new bytes32[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function bytess(bytes memory a) internal pure returns (bytes[] memory) {
- bytes[] memory arr = new bytes[](1);
- arr[0] = a;
- return arr;
- }
-
- function bytess(
- bytes memory a,
- bytes memory b
- ) internal pure returns (bytes[] memory) {
- bytes[] memory arr = new bytes[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function bytess(
- bytes memory a,
- bytes memory b,
- bytes memory c
- ) internal pure returns (bytes[] memory) {
- bytes[] memory arr = new bytes[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function bytess(
- bytes memory a,
- bytes memory b,
- bytes memory c,
- bytes memory d
- ) internal pure returns (bytes[] memory) {
- bytes[] memory arr = new bytes[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function bytess(
- bytes memory a,
- bytes memory b,
- bytes memory c,
- bytes memory d,
- bytes memory e
- ) internal pure returns (bytes[] memory) {
- bytes[] memory arr = new bytes[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function bytess(
- bytes memory a,
- bytes memory b,
- bytes memory c,
- bytes memory d,
- bytes memory e,
- bytes memory f
- ) internal pure returns (bytes[] memory) {
- bytes[] memory arr = new bytes[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function bytess(
- bytes memory a,
- bytes memory b,
- bytes memory c,
- bytes memory d,
- bytes memory e,
- bytes memory f,
- bytes memory g
- ) internal pure returns (bytes[] memory) {
- bytes[] memory arr = new bytes[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function addresses(address a) internal pure returns (address[] memory) {
- address[] memory arr = new address[](1);
- arr[0] = a;
- return arr;
- }
-
- function addresses(
- address a,
- address b
- ) internal pure returns (address[] memory) {
- address[] memory arr = new address[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function addresses(
- address a,
- address b,
- address c
- ) internal pure returns (address[] memory) {
- address[] memory arr = new address[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function addresses(
- address a,
- address b,
- address c,
- address d
- ) internal pure returns (address[] memory) {
- address[] memory arr = new address[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function addresses(
- address a,
- address b,
- address c,
- address d,
- address e
- ) internal pure returns (address[] memory) {
- address[] memory arr = new address[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function addresses(
- address a,
- address b,
- address c,
- address d,
- address e,
- address f
- ) internal pure returns (address[] memory) {
- address[] memory arr = new address[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function addresses(
- address a,
- address b,
- address c,
- address d,
- address e,
- address f,
- address g
- ) internal pure returns (address[] memory) {
- address[] memory arr = new address[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function bools(bool a) internal pure returns (bool[] memory) {
- bool[] memory arr = new bool[](1);
- arr[0] = a;
- return arr;
- }
-
- function bools(bool a, bool b) internal pure returns (bool[] memory) {
- bool[] memory arr = new bool[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function bools(
- bool a,
- bool b,
- bool c
- ) internal pure returns (bool[] memory) {
- bool[] memory arr = new bool[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function bools(
- bool a,
- bool b,
- bool c,
- bool d
- ) internal pure returns (bool[] memory) {
- bool[] memory arr = new bool[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function bools(
- bool a,
- bool b,
- bool c,
- bool d,
- bool e
- ) internal pure returns (bool[] memory) {
- bool[] memory arr = new bool[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function bools(
- bool a,
- bool b,
- bool c,
- bool d,
- bool e,
- bool f
- ) internal pure returns (bool[] memory) {
- bool[] memory arr = new bool[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function bools(
- bool a,
- bool b,
- bool c,
- bool d,
- bool e,
- bool f,
- bool g
- ) internal pure returns (bool[] memory) {
- bool[] memory arr = new bool[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function strings(string memory a) internal pure returns (string[] memory) {
- string[] memory arr = new string[](1);
- arr[0] = a;
- return arr;
- }
-
- function strings(
- string memory a,
- string memory b
- ) internal pure returns (string[] memory) {
- string[] memory arr = new string[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function strings(
- string memory a,
- string memory b,
- string memory c
- ) internal pure returns (string[] memory) {
- string[] memory arr = new string[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function strings(
- string memory a,
- string memory b,
- string memory c,
- string memory d
- ) internal pure returns (string[] memory) {
- string[] memory arr = new string[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function strings(
- string memory a,
- string memory b,
- string memory c,
- string memory d,
- string memory e
- ) internal pure returns (string[] memory) {
- string[] memory arr = new string[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function strings(
- string memory a,
- string memory b,
- string memory c,
- string memory d,
- string memory e,
- string memory f
- ) internal pure returns (string[] memory) {
- string[] memory arr = new string[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function strings(
- string memory a,
- string memory b,
- string memory c,
- string memory d,
- string memory e,
- string memory f,
- string memory g
- ) internal pure returns (string[] memory) {
- string[] memory arr = new string[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-}
diff --git a/contracts/helpers/sol/SpaceEnums.sol b/contracts/helpers/sol/SpaceEnums.sol
deleted file mode 100644
index b84f0102b..000000000
--- a/contracts/helpers/sol/SpaceEnums.sol
+++ /dev/null
@@ -1,382 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-enum Method {
- BASIC,
- FULFILL,
- MATCH,
- FULFILL_AVAILABLE,
- FULFILL_ADVANCED,
- MATCH_ADVANCED,
- FULFILL_AVAILABLE_ADVANCED,
- CANCEL,
- VALIDATE,
- INCREMENT_COUNTER,
- GET_ORDER_HASH,
- GET_ORDER_STATUS,
- GET_COUNTER,
- INFORMATION,
- NAME
-}
-
-enum OrderStatusEnum {
- AVAILABLE, // not validated or fulfilled; implicitly validated via signature except when match is called
- VALIDATED, // validated on-chain
- PARTIAL, // partially fulfilled
- FULFILLED, // completely fulfilled
- CANCELLED_EXPLICIT, // explicit cancellation
- CANCELLED_COUNTER, // canceled via counter increment (reverts due to invalid sig)
- REVERT // fulfilling reverts
-}
-
-enum BroadOrderType {
- FULL,
- PARTIAL,
- CONTRACT
-}
-
-// !BroadOrderType.CONTRACT <- Zone
-enum Zone {
- NONE,
- PASS,
- FAIL
-}
-
-// !BroadOrderType.CONTRACT <- OrderAuth
-enum NumOrders {
- ONE,
- MULTIPLE
-}
-
-// NumOrders.MULTIPLE && any(OrderFulfillment.PARTIAL) <- OrderComposition
-enum OrdersComposition {
- HOMOGENOUS,
- HETEROGENOUS
-}
-
-// OrderStatus.REVERT && !Zone.FAIL && !Offerer.CONTRACT_OFFERER <- OrderStatusRevertReason
-enum OrderStatusRevertReason {
- NATIVE, // receive hook fails
- ERC1155 // receive hook fails
-}
-
-// ItemType.ERC20/ERC1155/ERC721 <- TokenIndex
-// (test contracts have 3 of each token deployed; can mix and match)
-enum TokenIndex {
- ONE,
- TWO,
- THREE
-}
-
-enum Criteria {
- MERKLE, // non-zero criteria
- WILDCARD // criteria zero
-}
-
-// Criteria.WILDCARD/MERKLE <- CriteriaResolved
-enum CriteriaResolved {
- VALID, // correctly resolved
- INVALID, // incorrectly resolved
- UNAVAILABLE // resolved but not owned/approved
-}
-
-enum Amount {
- FIXED,
- ASCENDING,
- DESCENDING
-}
-
-enum AmountDegree {
- // ZERO, ?
- SMALL,
- MEDIUM,
- LARGE,
- WUMBO
-}
-
-enum FulfillmentRecipient {
- ZERO,
- ALICE,
- BOB,
- EVE
-}
-
-// ConsiderationItem.* / ReceivedItem.* / Method.*ADVANCED <- Recipient
-enum Recipient {
- // ZERO,?
- OFFERER,
- RECIPIENT,
- DILLON,
- EVE,
- FRANK
- // INVALID
-}
-
-enum RecipientDirty {
- CLEAN,
- DIRTY
-}
-
-enum Caller {
- TEST_CONTRACT,
- ALICE,
- BOB,
- CAROL,
- DILLON,
- EVE,
- FRANK
-}
-
-// disregarded in the self_ad_hoc case
-enum Offerer {
- TEST_CONTRACT,
- ALICE, // consider EOA space enum
- BOB,
- CONTRACT_OFFERER,
- EIP1271
-}
-
-// debatable if needed but we do need to test zonehash permutations
-enum ZoneHash {
- NONE,
- VALID,
- INVALID
-}
-
-// Offerer.CONTRACT_OFFERER <- ContractOfferer
-enum ContractOfferer {
- PASS,
- FAIL_GENERATE,
- FAIL_MIN_RECEIVED,
- FAIL_MAX_SPENT,
- FAIL_RATIFY
-}
-
-// ContractOfferer.PASS <- ContractOffererPassGenerated
-enum ContractOffererPassGenerated {
- IDENTITY,
- MIN_RECEIVED,
- MAX_SPENT,
- BOTH
-}
-
-// ContractOffererPassGenerated.MIN_RECEIVED/BOTH <- ContractOffererPassMinReceived
-enum ContractOffererPassMinReceived {
- MORE_MIN_RECEIVED,
- EXTRA_MIN_RECEIVED,
- BOTH
-}
-
-// ContractOffererPassGenerated.MAX_SPENT/BOTH <- ContractOffererPassMaxSpent
-enum ContractOffererPassMaxSpent {
- LESS_MAX_SPENT,
- TRUNCATED_MAX_SPENT,
- BOTH
-}
-
-enum ContractOffererFailGenerated {
- MIN_RECEIVED,
- MAX_SPENT,
- BOTH
-}
-
-// ContractOffererFailGenerated.MIN_RECEIVED/BOTH <- ContractOffererFailMinReceived
-enum ContractOffererFailMinReceived {
- LESS_MIN_RECEIVED,
- TRUNCATED_MIN_RECEIVED,
- BOTH
-}
-
-// ContractOffererFailGenerated.MAX_SPENT/BOTH <- ContractOffererFailMaxSpent
-enum ContractOffererFailMaxSpent {
- MORE_MAX_SPENT,
- EXTRA_MAX_SPENT,
- BOTH
-}
-
-enum Time {
- // valid granularity important for ascending/descending
- STARTS_IN_FUTURE,
- EXACT_START, // order is live
- ONGOING,
- EXACT_END, // order is expired
- EXPIRED
-}
-
-// Method.MATCH* <- MatchValidation
-enum MatchValidation {
- SELF_AD_HOC,
- SIGNATURE
-}
-
-enum SignatureMethod {
- EOA,
- VALIDATE,
- EIP1271,
- CONTRACT,
- SELF_AD_HOC
-}
-
-// Offerer.EOA <- EOASignature
-enum EOASignature {
- STANDARD,
- EIP2098,
- BULK,
- BULK2098
-}
-
-// Offerer.EIP1271 <- EIP1271Signature
-enum EIP1271Signature {
- EIP1271,
- EIP1271_BULKLIKE
-}
-
-// Validation.SIGNATURE <- SignatureValidity
-enum SignatureValidity {
- VALID,
- INVALID
-}
-
-// EOASignature.BULK/BULK2098+EIP1271Signature.EIP1271_BULKLIKE <- BulkSignatureSize
-enum BulkSignatureSize {
- ONE,
- TWO,
- THREE,
- FOUR,
- FIVE,
- SIX,
- SEVEN,
- EIGHT,
- NINE,
- TEN,
- ELEVEN,
- TWELVE,
- THIRTEEN,
- FOURTEEN,
- FIFTEEN,
- SIXTEEN,
- SEVENTEEN,
- EIGHTEEN,
- NINETEEN,
- TWENTY,
- TWENTYONE,
- TWENTYTWO,
- TWENTYTHREE,
- TWENTYFOUR
-}
-
-enum Salt {
- VALID,
- DUPLICATE // ?
-}
-
-enum ConduitChoice {
- NONE,
- ONE,
- TWO
-}
-
-enum Counter {
- VALID,
- INVALID
-}
-
-// Counter.INVALID <- CounterValue
-enum CounterValue {
- LESS,
- GREATER
-}
-
-enum TotalOriginalConsiderationItems {
- LESS,
- EQUAL,
- GREATER
-}
-
-// Method.*Advanced <- Fraction
-enum Fraction {
- INVALID,
- VALID
-}
-
-// Fraction.VALID <- ValidFraction
-enum ValidFraction {
- SMALL,
- HALF,
- LARGE,
- WHOLE
-}
-
-enum InvalidFraction {
- INVALID, // order is a full order
- UNEVEN, // cannot divide into amount
- IRREGULAR // N/M where N > M
-}
-
-enum CriteriaProofs {
- LESS, // too few proofs
- EQUAL, // sufficient number of proofs
- GREATER // extra proofs
-}
-
-// Method.FULFILL_AVAILABLE* <= FulfillAvailableFulfillments
-enum FulfillAvailableFulfillments {
- NAIVE, // one component per offer + consideration item, ie, unaggregated
- AGGREGATED,
- INVALID
-}
-
-// FulfillAvailableFulfillments.INVALID <- InvalidFulfillAvailableFulfillments
-enum InvalidFulfillAvailableFulfillments {
- OFFER,
- CONSIDERATION,
- BOTH
-}
-
-// InvalidFulfillAvailableFulfillments.* <- InvalidFulfillAvailableFulfillmentsCondition
-enum InvalidFulfillAvailableFulfillmentsCondition {
- INVALID, // ie not correctly constructed, duplicates, etc
- LESS, // ie missing fulfillments
- GREATER // ie including duplicates
-}
-
-// FulfillAvailableFulfillments.AGGREGATED <- AggregatedFulfillAvailableFulfillments
-enum AggregatedFulfillAvailableFulfillments {
- OFFER,
- CONSIDERATION,
- BOTH
-}
-
-enum BasicOrderCategory {
- NONE,
- LISTING,
- BID
-}
-
-enum Tips {
- NONE,
- TIPS
-}
-
-enum UnavailableReason {
- AVAILABLE,
- EXPIRED,
- STARTS_IN_FUTURE,
- CANCELLED,
- ALREADY_FULFILLED,
- MAX_FULFILLED_SATISFIED,
- GENERATE_ORDER_FAILURE
-}
-
-enum ExtraData {
- NONE,
- RANDOM
-}
-
-enum ContractOrderRebate {
- NONE,
- MORE_OFFER_ITEMS,
- MORE_OFFER_ITEM_AMOUNTS,
- LESS_CONSIDERATION_ITEMS,
- LESS_CONSIDERATION_ITEM_AMOUNTS
-}
diff --git a/contracts/helpers/sol/StructSpace.sol b/contracts/helpers/sol/StructSpace.sol
deleted file mode 100644
index e2291e6a9..000000000
--- a/contracts/helpers/sol/StructSpace.sol
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { ItemType } from "./SeaportEnums.sol";
-
-import {
- Amount,
- BroadOrderType,
- Caller,
- ConduitChoice,
- ContractOrderRebate,
- Criteria,
- EOASignature,
- ExtraData,
- FulfillmentRecipient,
- Offerer,
- Recipient,
- SignatureMethod,
- Time,
- Tips,
- TokenIndex,
- UnavailableReason,
- Zone,
- ZoneHash
-} from "./SpaceEnums.sol";
-
-import {
- FulfillmentStrategy
-} from "./fulfillments/lib/FulfillmentLib.sol";
-
-struct OfferItemSpace {
- ItemType itemType;
- TokenIndex tokenIndex;
- Criteria criteria;
- Amount amount;
-}
-
-struct ConsiderationItemSpace {
- ItemType itemType;
- TokenIndex tokenIndex;
- Criteria criteria;
- Amount amount;
- Recipient recipient;
-}
-
-struct SpentItemSpace {
- ItemType itemType;
- TokenIndex tokenIndex;
-}
-
-struct ReceivedItemSpace {
- ItemType itemType;
- TokenIndex tokenIndex;
- Recipient recipient;
-}
-
-struct OrderComponentsSpace {
- Offerer offerer;
- Zone zone;
- OfferItemSpace[] offer;
- ConsiderationItemSpace[] consideration;
- BroadOrderType orderType;
- Time time;
- ZoneHash zoneHash;
- SignatureMethod signatureMethod;
- EOASignature eoaSignatureType;
- uint256 bulkSigHeight;
- uint256 bulkSigIndex;
- ConduitChoice conduit;
- Tips tips;
- UnavailableReason unavailableReason; // ignored unless unavailable
- ExtraData extraData;
- ContractOrderRebate rebate;
-}
-
-struct AdvancedOrdersSpace {
- OrderComponentsSpace[] orders;
- bool isMatchable;
- uint256 maximumFulfilled;
- FulfillmentRecipient recipient;
- ConduitChoice conduit;
- Caller caller;
- FulfillmentStrategy strategy;
-}
diff --git a/contracts/helpers/sol/ZoneInterface.sol b/contracts/helpers/sol/ZoneInterface.sol
deleted file mode 100644
index 6a2531209..000000000
--- a/contracts/helpers/sol/ZoneInterface.sol
+++ /dev/null
@@ -1,4 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { ZoneInterface } from "../../interfaces/ZoneInterface.sol";
diff --git a/contracts/helpers/sol/executions/ExecutionHelper.sol b/contracts/helpers/sol/executions/ExecutionHelper.sol
deleted file mode 100644
index b1fda3ee7..000000000
--- a/contracts/helpers/sol/executions/ExecutionHelper.sol
+++ /dev/null
@@ -1,1188 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- AmountDeriverHelper
-} from "../lib/fulfillment/AmountDeriverHelper.sol";
-
-import { AdvancedOrderLib } from "../lib/AdvancedOrderLib.sol";
-
-import { SpentItemLib } from "../lib/SpentItemLib.sol";
-
-import { ReceivedItemLib } from "../lib/ReceivedItemLib.sol";
-
-import {
- AdvancedOrder,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- Order,
- ReceivedItem,
- SpentItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { ItemType, Side } from "../../../lib/ConsiderationEnums.sol";
-
-import {
- FulfillmentDetails,
- OrderDetails
-} from "../fulfillments/lib/Structs.sol";
-
-import { UnavailableReason } from "../SpaceEnums.sol";
-
-/**
- * @dev Helper contract for deriving explicit and executions from orders and
- * fulfillment details
- *
- * @dev TODO: move to the tests folder? not really useful for normal scripting
- */
-library ExecutionHelper {
- using AdvancedOrderLib for AdvancedOrder[];
- using SpentItemLib for SpentItem[];
- using ReceivedItemLib for ReceivedItem[];
-
- /**
- * @dev get explicit and implicit executions for a fulfillAvailable call
- *
- * @param fulfillmentDetails the fulfillment details
- * @param offerFulfillments 2d array of offer fulfillment components
- * @param considerationFulfillments 2d array of consideration fulfillment
- *
- * @return explicitExecutions the explicit executions
- * @return implicitExecutionsPre the implicit executions (unspecified offer
- * items)
- * @return implicitExecutionsPost the implicit executions (unspecified offer
- * items)
- */
- function getFulfillAvailableExecutions(
- FulfillmentDetails memory fulfillmentDetails,
- FulfillmentComponent[][] memory offerFulfillments,
- FulfillmentComponent[][] memory considerationFulfillments,
- OrderDetails[] memory orderDetails
- )
- public
- pure
- returns (
- Execution[] memory explicitExecutions,
- Execution[] memory implicitExecutionsPre,
- Execution[] memory implicitExecutionsPost,
- uint256 nativeTokensReturned
- )
- {
- FulfillmentDetails memory details = copy(fulfillmentDetails);
-
- bool[] memory availableOrders = new bool[](orderDetails.length);
-
- for (uint256 i = 0; i < orderDetails.length; ++i) {
- availableOrders[i] =
- orderDetails[i].unavailableReason ==
- UnavailableReason.AVAILABLE;
- }
-
- implicitExecutionsPre = processImplicitPreOrderExecutions(
- details,
- availableOrders
- );
-
- explicitExecutions = processExplicitExecutionsFromAggregatedComponents(
- details,
- offerFulfillments,
- considerationFulfillments,
- availableOrders
- );
-
- implicitExecutionsPost = processImplicitPostOrderExecutions(
- details,
- availableOrders
- );
-
- nativeTokensReturned = _handleExcessNativeTokens(
- details,
- explicitExecutions,
- implicitExecutionsPre,
- implicitExecutionsPost
- );
- }
-
- /**
- * @dev Process an array of fulfillments into an array of explicit and
- * implicit executions.
- *
- * @param fulfillmentDetails The fulfillment details.
- * @param fulfillments An array of fulfillments.
- *
- * @return explicitExecutions The explicit executions
- * @return implicitExecutionsPre The implicit executions
- * @return implicitExecutionsPost The implicit executions
- */
- function getMatchExecutions(
- FulfillmentDetails memory fulfillmentDetails,
- Fulfillment[] memory fulfillments
- )
- internal
- pure
- returns (
- Execution[] memory explicitExecutions,
- Execution[] memory implicitExecutionsPre,
- Execution[] memory implicitExecutionsPost,
- uint256 nativeTokensReturned
- )
- {
- FulfillmentDetails memory details = copy(fulfillmentDetails);
-
- explicitExecutions = new Execution[](fulfillments.length);
-
- uint256 filteredExecutions = 0;
-
- bool[] memory availableOrders = new bool[](details.orders.length);
-
- for (uint256 i = 0; i < details.orders.length; ++i) {
- availableOrders[i] = true;
- }
-
- implicitExecutionsPre = processImplicitPreOrderExecutions(
- details,
- availableOrders
- );
-
- for (uint256 i = 0; i < fulfillments.length; i++) {
- Execution memory execution = processExecutionFromFulfillment(
- details,
- fulfillments[i]
- );
-
- if (
- execution.item.recipient == execution.offerer &&
- execution.item.itemType != ItemType.NATIVE
- ) {
- filteredExecutions++;
- } else {
- explicitExecutions[i - filteredExecutions] = execution;
- }
- }
-
- // If some number of executions have been filtered...
- if (filteredExecutions != 0) {
- // reduce the total length of the executions array.
- assembly {
- mstore(
- explicitExecutions,
- sub(mload(explicitExecutions), filteredExecutions)
- )
- }
- }
-
- implicitExecutionsPost = processImplicitPostOrderExecutions(
- details,
- availableOrders
- );
-
- nativeTokensReturned = _handleExcessNativeTokens(
- details,
- explicitExecutions,
- implicitExecutionsPre,
- implicitExecutionsPost
- );
- }
-
- function processExcessNativeTokens(
- Execution[] memory explicitExecutions,
- Execution[] memory implicitExecutionsPre,
- Execution[] memory implicitExecutionsPost
- ) internal pure returns (uint256 excessNativeTokens) {
- for (uint256 i; i < implicitExecutionsPre.length; i++) {
- excessNativeTokens += implicitExecutionsPre[i].item.amount;
- }
- for (uint256 i; i < explicitExecutions.length; i++) {
- ReceivedItem memory item = explicitExecutions[i].item;
- if (item.itemType == ItemType.NATIVE) {
- if (item.amount > excessNativeTokens) {
- revert(
- "ExecutionsHelper: explicit execution amount exceeds seaport balance"
- );
- }
- excessNativeTokens -= item.amount;
- }
- }
- for (uint256 i; i < implicitExecutionsPost.length; i++) {
- ReceivedItem memory item = implicitExecutionsPost[i].item;
- if (item.itemType == ItemType.NATIVE) {
- if (item.amount > excessNativeTokens) {
- revert(
- "ExecutionsHelper: post execution amount exceeds seaport balance"
- );
- }
- excessNativeTokens -= item.amount;
- }
- }
- }
-
- function getStandardExecutions(
- FulfillmentDetails memory details
- )
- public
- pure
- returns (
- Execution[] memory implicitExecutions,
- uint256 nativeTokensReturned
- )
- {
- if (details.orders.length != 1) {
- revert("ExecutionHelper: bad orderDetails length for standard");
- }
-
- return
- getStandardExecutions(
- details.orders[0],
- details.fulfiller,
- details.fulfillerConduitKey,
- details.recipient,
- details.nativeTokensSupplied,
- details.seaport
- );
- }
-
- /**
- * @dev Return executions for fulfilOrder and fulfillAdvancedOrder.
- */
- function getStandardExecutions(
- OrderDetails memory orderDetails,
- address fulfiller,
- bytes32 fulfillerConduitKey,
- address recipient,
- uint256 nativeTokensSupplied,
- address seaport
- )
- public
- pure
- returns (
- Execution[] memory implicitExecutions,
- uint256 nativeTokensReturned
- )
- {
- uint256 currentSeaportBalance = 0;
-
- // implicit executions (use max and resize at end):
- // - supplying native tokens (0-1)
- // - providing native tokens from contract offerer (0-offer.length)
- // - transferring offer items to recipient (offer.length)
- // - transferring consideration items to each recipient (consideration.length)
- // - returning unspent native tokens (0-1)
- implicitExecutions = new Execution[](
- 2 *
- orderDetails.offer.length +
- orderDetails.consideration.length +
- 2
- );
-
- uint256 executionIndex = 0;
-
- if (nativeTokensSupplied > 0) {
- implicitExecutions[executionIndex++] = Execution({
- offerer: fulfiller,
- conduitKey: fulfillerConduitKey,
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: uint256(0),
- amount: nativeTokensSupplied,
- recipient: payable(seaport)
- })
- });
- currentSeaportBalance += nativeTokensSupplied;
- }
-
- if (orderDetails.isContract) {
- for (uint256 i = 0; i < orderDetails.offer.length; i++) {
- SpentItem memory item = orderDetails.offer[i];
- if (item.itemType == ItemType.NATIVE) {
- implicitExecutions[executionIndex++] = Execution({
- offerer: orderDetails.offerer,
- conduitKey: orderDetails.conduitKey,
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: uint256(0),
- amount: orderDetails.offer[i].amount,
- recipient: payable(seaport)
- })
- });
- currentSeaportBalance += orderDetails.offer[i].amount;
- }
- }
- }
-
- for (uint256 i = 0; i < orderDetails.offer.length; i++) {
- SpentItem memory item = orderDetails.offer[i];
- implicitExecutions[executionIndex++] = Execution({
- offerer: item.itemType == ItemType.NATIVE
- ? seaport
- : orderDetails.offerer,
- conduitKey: orderDetails.conduitKey,
- item: ReceivedItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifier,
- amount: item.amount,
- recipient: payable(recipient)
- })
- });
- if (item.itemType == ItemType.NATIVE) {
- if (item.amount > currentSeaportBalance) {
- revert(
- "ExecutionHelper: offer item amount exceeds seaport balance"
- );
- }
-
- currentSeaportBalance -= item.amount;
- }
- }
-
- for (uint256 i = 0; i < orderDetails.consideration.length; i++) {
- ReceivedItem memory item = orderDetails.consideration[i];
- implicitExecutions[executionIndex++] = Execution({
- offerer: item.itemType == ItemType.NATIVE ? seaport : fulfiller,
- conduitKey: fulfillerConduitKey,
- item: item
- });
- if (item.itemType == ItemType.NATIVE) {
- if (item.amount > currentSeaportBalance) {
- revert(
- "ExecutionHelper: consideration item amount exceeds seaport balance"
- );
- }
-
- currentSeaportBalance -= item.amount;
- }
- }
-
- nativeTokensReturned = currentSeaportBalance;
-
- if (currentSeaportBalance > 0) {
- implicitExecutions[executionIndex++] = Execution({
- offerer: seaport,
- conduitKey: bytes32(0),
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: 0,
- amount: currentSeaportBalance,
- recipient: payable(fulfiller)
- })
- });
- }
-
- // Set actual length of the implicit executions array.
- assembly {
- mstore(implicitExecutions, executionIndex)
- }
- }
-
- function getBasicExecutions(
- FulfillmentDetails memory details
- )
- public
- pure
- returns (
- Execution[] memory implicitExecutions,
- uint256 nativeTokensReturned
- )
- {
- if (details.orders.length != 1) {
- revert("ExecutionHelper: bad orderDetails length for basic");
- }
-
- return
- getBasicExecutions(
- details.orders[0],
- details.fulfiller,
- details.fulfillerConduitKey,
- details.nativeTokensSupplied,
- details.seaport
- );
- }
-
- /**
- * @dev return executions for fulfillBasicOrder and
- * fulfillBasicOrderEfficient.
- */
- function getBasicExecutions(
- OrderDetails memory orderDetails,
- address fulfiller,
- bytes32 fulfillerConduitKey,
- uint256 nativeTokensSupplied,
- address seaport
- )
- public
- pure
- returns (
- Execution[] memory implicitExecutions,
- uint256 nativeTokensReturned
- )
- {
- if (orderDetails.offer.length != 1) {
- revert("not a basic order");
- }
-
- if (orderDetails.offer[0].itemType == ItemType.ERC20) {
- require(nativeTokensSupplied == 0, "native tokens not allowed");
- require(orderDetails.consideration.length > 0, "no items received");
-
- implicitExecutions = new Execution[](
- 1 + orderDetails.consideration.length
- );
-
- implicitExecutions[0] = Execution({
- offerer: fulfiller,
- conduitKey: fulfillerConduitKey,
- item: orderDetails.consideration[0]
- });
-
- uint256 additionalAmounts = 0;
-
- for (uint256 i = 1; i < orderDetails.consideration.length; i++) {
- implicitExecutions[i] = Execution({
- offerer: orderDetails.offerer,
- conduitKey: orderDetails.conduitKey,
- item: orderDetails.consideration[i]
- });
- additionalAmounts += orderDetails.consideration[i].amount;
- }
-
- implicitExecutions[orderDetails.consideration.length] = Execution({
- offerer: orderDetails.offerer,
- conduitKey: orderDetails.conduitKey,
- item: ReceivedItem({
- itemType: orderDetails.offer[0].itemType,
- token: orderDetails.offer[0].token,
- identifier: orderDetails.offer[0].identifier,
- amount: orderDetails.offer[0].amount - additionalAmounts,
- recipient: payable(fulfiller)
- })
- });
- } else {
- uint256 currentSeaportBalance = 0;
-
- // implicit executions (use max and resize at end):
- // - supplying native tokens (0-1)
- // - transferring offer item to recipient (1)
- // - transfer additional recipient consideration items (consideration.length - 1)
- // - transfer first consideration item to the fulfiller (1)
- // - returning unspent native tokens (0-1)
- implicitExecutions = new Execution[](
- orderDetails.consideration.length + 3
- );
-
- uint256 executionIndex = 0;
-
- if (nativeTokensSupplied > 0) {
- implicitExecutions[executionIndex++] = Execution({
- offerer: fulfiller,
- conduitKey: fulfillerConduitKey,
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: uint256(0),
- amount: nativeTokensSupplied,
- recipient: payable(seaport)
- })
- });
- currentSeaportBalance += nativeTokensSupplied;
- }
-
- {
- if (orderDetails.offer.length != 1) {
- revert("ExecutionHelper: wrong length for basic offer");
- }
- SpentItem memory offerItem = orderDetails.offer[0];
- implicitExecutions[executionIndex++] = Execution({
- offerer: orderDetails.offerer,
- conduitKey: orderDetails.conduitKey,
- item: ReceivedItem({
- itemType: offerItem.itemType,
- token: offerItem.token,
- identifier: offerItem.identifier,
- amount: offerItem.amount,
- recipient: payable(fulfiller)
- })
- });
- }
-
- for (uint256 i = 1; i < orderDetails.consideration.length; i++) {
- ReceivedItem memory item = orderDetails.consideration[i];
- implicitExecutions[executionIndex++] = Execution({
- offerer: item.itemType == ItemType.NATIVE
- ? seaport
- : fulfiller,
- conduitKey: fulfillerConduitKey,
- item: item
- });
- if (item.itemType == ItemType.NATIVE) {
- if (item.amount > currentSeaportBalance) {
- revert(
- "ExecutionHelper: basic consideration item amount exceeds seaport balance"
- );
- }
-
- currentSeaportBalance -= item.amount;
- }
- }
-
- {
- if (orderDetails.consideration.length < 1) {
- revert(
- "ExecutionHelper: wrong length for basic consideration"
- );
- }
- ReceivedItem memory item = orderDetails.consideration[0];
- implicitExecutions[executionIndex++] = Execution({
- offerer: item.itemType == ItemType.NATIVE
- ? seaport
- : fulfiller,
- conduitKey: fulfillerConduitKey,
- item: item
- });
- if (item.itemType == ItemType.NATIVE) {
- if (item.amount > currentSeaportBalance) {
- revert(
- "ExecutionHelper: first basic consideration item amount exceeds seaport balance"
- );
- }
-
- currentSeaportBalance -= item.amount;
- }
- }
-
- nativeTokensReturned = currentSeaportBalance;
-
- if (currentSeaportBalance > 0) {
- implicitExecutions[executionIndex++] = Execution({
- offerer: seaport,
- conduitKey: bytes32(0),
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: 0,
- amount: currentSeaportBalance,
- recipient: payable(fulfiller)
- })
- });
- }
-
- // Set actual length of the implicit executions array.
- assembly {
- mstore(implicitExecutions, executionIndex)
- }
- }
- }
-
- /**
- * @dev Get the item and recipient for a given fulfillment component.
- *
- * @param fulfillmentDetails The order fulfillment details
- * @param offerRecipient The offer recipient
- * @param component The fulfillment component
- * @param side The side of the order
- *
- * @return item The item
- * @return trueRecipient The actual recipient
- */
- function getItemAndRecipient(
- FulfillmentDetails memory fulfillmentDetails,
- address payable offerRecipient,
- FulfillmentComponent memory component,
- Side side
- )
- internal
- pure
- returns (SpentItem memory item, address payable trueRecipient)
- {
- OrderDetails memory details = fulfillmentDetails.orders[
- component.orderIndex
- ];
-
- if (side == Side.OFFER) {
- item = details.offer[component.itemIndex];
- trueRecipient = offerRecipient;
- } else {
- ReceivedItem memory _item = details.consideration[
- component.itemIndex
- ];
- // cast to SpentItem
- assembly {
- item := _item
- }
- trueRecipient = _item.recipient;
- }
- }
-
- /**
- * @dev Process the aggregated fulfillment components for a given side of an
- * order.
- *
- * @param fulfillmentDetails The order fulfillment details
- * @param offerRecipient The recipient for any offer items. Note: may
- * not be FulfillmentDetails' recipient, eg,
- * when processing matchOrders fulfillments
- * @param aggregatedComponents The aggregated fulfillment components
- * @param side The side of the order
- *
- * @return The execution
- */
- function processExecutionFromAggregatedFulfillmentComponents(
- FulfillmentDetails memory fulfillmentDetails,
- address payable offerRecipient,
- FulfillmentComponent[] memory aggregatedComponents,
- Side side
- ) internal pure returns (Execution memory) {
- // aggregate the amounts of each item
- uint256 aggregatedAmount;
- for (uint256 j = 0; j < aggregatedComponents.length; j++) {
- (SpentItem memory item, ) = getItemAndRecipient(
- fulfillmentDetails,
- offerRecipient,
- aggregatedComponents[j],
- side
- );
- aggregatedAmount += item.amount;
- }
-
- // use the first fulfillment component to get the order details
- FulfillmentComponent memory first = aggregatedComponents[0];
- (
- SpentItem memory firstItem,
- address payable trueRecipient
- ) = getItemAndRecipient(
- fulfillmentDetails,
- offerRecipient,
- first,
- side
- );
- OrderDetails memory details = fulfillmentDetails.orders[
- first.orderIndex
- ];
-
- return
- Execution({
- offerer: side == Side.OFFER
- ? details.offerer
- : fulfillmentDetails.fulfiller,
- conduitKey: side == Side.OFFER
- ? details.conduitKey
- : fulfillmentDetails.fulfillerConduitKey,
- item: ReceivedItem({
- itemType: firstItem.itemType,
- token: firstItem.token,
- identifier: firstItem.identifier,
- amount: aggregatedAmount,
- recipient: trueRecipient
- })
- });
- }
-
- /**
- * @dev Process explicit executions from 2d aggregated fulfillAvailable
- * fulfillment components arrays. Note that amounts on OrderDetails are
- * modified in-place during fulfillment processing.
- *
- * @param fulfillmentDetails The fulfillment details
- * @param offerComponents The offer components
- * @param considerationComponents The consideration components
- *
- * @return explicitExecutions The explicit executions
- */
- function processExplicitExecutionsFromAggregatedComponents(
- FulfillmentDetails memory fulfillmentDetails,
- FulfillmentComponent[][] memory offerComponents,
- FulfillmentComponent[][] memory considerationComponents,
- bool[] memory availableOrders
- ) internal pure returns (Execution[] memory explicitExecutions) {
- explicitExecutions = new Execution[](
- offerComponents.length + considerationComponents.length
- );
-
- uint256 filteredExecutions = 0;
-
- // process offer components
- // iterate over each array of fulfillment components
- for (uint256 i = 0; i < offerComponents.length; i++) {
- FulfillmentComponent[]
- memory aggregatedComponents = offerComponents[i];
-
- // aggregate & zero-out the amounts of each offer item
- uint256 aggregatedAmount;
- for (uint256 j = 0; j < aggregatedComponents.length; j++) {
- FulfillmentComponent memory component = aggregatedComponents[j];
-
- if (!availableOrders[component.orderIndex]) {
- continue;
- }
-
- OrderDetails memory offerOrderDetails = fulfillmentDetails
- .orders[component.orderIndex];
-
- if (component.itemIndex < offerOrderDetails.offer.length) {
- SpentItem memory item = offerOrderDetails.offer[
- component.itemIndex
- ];
-
- aggregatedAmount += item.amount;
-
- item.amount = 0;
- }
- }
-
- if (aggregatedAmount == 0) {
- filteredExecutions++;
- continue;
- }
-
- // use the first fulfillment component to get the order details
- FulfillmentComponent memory first = aggregatedComponents[0];
- OrderDetails memory details = fulfillmentDetails.orders[
- first.orderIndex
- ];
- SpentItem memory firstItem = details.offer[first.itemIndex];
-
- if (
- fulfillmentDetails.recipient == details.offerer &&
- firstItem.itemType != ItemType.NATIVE
- ) {
- filteredExecutions++;
- } else {
- explicitExecutions[i - filteredExecutions] = Execution({
- offerer: details.offerer,
- conduitKey: details.conduitKey,
- item: ReceivedItem({
- itemType: firstItem.itemType,
- token: firstItem.token,
- identifier: firstItem.identifier,
- amount: aggregatedAmount,
- recipient: fulfillmentDetails.recipient
- })
- });
- }
- }
-
- // process consideration components
- // iterate over each array of fulfillment components
- for (uint256 i; i < considerationComponents.length; i++) {
- FulfillmentComponent[]
- memory aggregatedComponents = considerationComponents[i];
-
- // aggregate & zero-out the amounts of each offer item
- uint256 aggregatedAmount;
- for (uint256 j = 0; j < aggregatedComponents.length; j++) {
- FulfillmentComponent memory component = aggregatedComponents[j];
-
- if (!availableOrders[component.orderIndex]) {
- continue;
- }
-
- OrderDetails
- memory considerationOrderDetails = fulfillmentDetails
- .orders[component.orderIndex];
-
- if (
- component.itemIndex <
- considerationOrderDetails.consideration.length
- ) {
- ReceivedItem memory item = considerationOrderDetails
- .consideration[component.itemIndex];
-
- aggregatedAmount += item.amount;
-
- item.amount = 0;
- }
- }
-
- if (aggregatedAmount == 0) {
- filteredExecutions++;
- continue;
- }
-
- // use the first fulfillment component to get the order details
- FulfillmentComponent memory first = aggregatedComponents[0];
- OrderDetails memory details = fulfillmentDetails.orders[
- first.orderIndex
- ];
- ReceivedItem memory firstItem = details.consideration[
- first.itemIndex
- ];
-
- if (
- firstItem.recipient == fulfillmentDetails.fulfiller &&
- firstItem.itemType != ItemType.NATIVE
- ) {
- filteredExecutions++;
- } else {
- explicitExecutions[
- i + offerComponents.length - filteredExecutions
- ] = Execution({
- offerer: fulfillmentDetails.fulfiller,
- conduitKey: fulfillmentDetails.fulfillerConduitKey,
- item: ReceivedItem({
- itemType: firstItem.itemType,
- token: firstItem.token,
- identifier: firstItem.identifier,
- amount: aggregatedAmount,
- recipient: firstItem.recipient
- })
- });
- }
- }
-
- // If some number of executions have been filtered...
- if (filteredExecutions != 0) {
- // reduce the total length of the executions array.
- assembly {
- mstore(
- explicitExecutions,
- sub(mload(explicitExecutions), filteredExecutions)
- )
- }
- }
- }
-
- /**
- * @dev Process an array of *sorted* fulfillment components into an array of
- * executions. Note that components must be sorted.
- *
- * @param orderDetails The order details
- * @param components The fulfillment components
- * @param recipient The recipient of implicit executions
- *
- * @return executions The executions
- */
- function processExecutionsFromIndividualOfferFulfillmentComponents(
- OrderDetails[] memory orderDetails,
- address payable recipient,
- FulfillmentComponent[] memory components
- ) internal pure returns (Execution[] memory executions) {
- executions = new Execution[](components.length);
-
- for (uint256 i = 0; i < components.length; i++) {
- FulfillmentComponent memory component = components[i];
- OrderDetails memory details = orderDetails[component.orderIndex];
- SpentItem memory item = details.offer[component.itemIndex];
- executions[i] = Execution({
- offerer: details.offerer,
- conduitKey: details.conduitKey,
- item: ReceivedItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifier,
- amount: item.amount,
- recipient: recipient
- })
- });
- }
- }
-
- /**
- * @dev Generate implicit Executions for a set of orders by getting all
- * offer items that are not fully spent as part of a fulfillment.
- *
- * @param fulfillmentDetails fulfillment details
- *
- * @return implicitExecutions The implicit executions
- */
- function processImplicitPreOrderExecutions(
- FulfillmentDetails memory fulfillmentDetails,
- bool[] memory availableOrders
- ) internal pure returns (Execution[] memory implicitExecutions) {
- // Get the maximum possible number of implicit executions.
- uint256 maxPossible = 1;
- for (uint256 i = 0; i < fulfillmentDetails.orders.length; ++i) {
- if (availableOrders[i]) {
- maxPossible += fulfillmentDetails.orders[i].offer.length;
- }
- }
- implicitExecutions = new Execution[](maxPossible);
-
- uint256 executionIndex;
- if (fulfillmentDetails.nativeTokensSupplied > 0) {
- implicitExecutions[executionIndex++] = Execution({
- offerer: fulfillmentDetails.fulfiller,
- conduitKey: bytes32(0),
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: uint256(0),
- amount: fulfillmentDetails.nativeTokensSupplied,
- recipient: payable(fulfillmentDetails.seaport)
- })
- });
- }
-
- for (uint256 o; o < fulfillmentDetails.orders.length; o++) {
- OrderDetails memory orderDetails = fulfillmentDetails.orders[o];
- if (!availableOrders[o]) {
- continue;
- }
-
- if (orderDetails.isContract) {
- for (uint256 i = 0; i < orderDetails.offer.length; i++) {
- SpentItem memory item = orderDetails.offer[i];
- if (item.itemType == ItemType.NATIVE) {
- implicitExecutions[executionIndex++] = Execution({
- offerer: orderDetails.offerer,
- conduitKey: bytes32(0),
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: uint256(0),
- amount: item.amount,
- recipient: payable(fulfillmentDetails.seaport)
- })
- });
- }
- }
- }
- }
-
- // Set the final length of the implicit executions array.
- // Leave space for possible excess native token return.
- assembly {
- mstore(implicitExecutions, executionIndex)
- }
- }
-
- /**
- * @dev Generate implicit Executions for a set of orders by getting all
- * offer items that are not fully spent as part of a fulfillment.
- *
- * @param fulfillmentDetails fulfillment details
- *
- * @return implicitExecutions The implicit executions
- */
- function processImplicitPostOrderExecutions(
- FulfillmentDetails memory fulfillmentDetails,
- bool[] memory availableOrders
- ) internal pure returns (Execution[] memory implicitExecutions) {
- OrderDetails[] memory orderDetails = fulfillmentDetails.orders;
-
- // Get the maximum possible number of implicit executions.
- uint256 maxPossible = 1;
- for (uint256 i = 0; i < orderDetails.length; ++i) {
- if (availableOrders[i]) {
- maxPossible += orderDetails[i].offer.length;
- }
- }
-
- // Insert an implicit execution for each non-zero offer item.
- implicitExecutions = new Execution[](maxPossible);
- uint256 insertionIndex = 0;
- for (uint256 i = 0; i < orderDetails.length; ++i) {
- if (!availableOrders[i]) {
- continue;
- }
-
- OrderDetails memory details = orderDetails[i];
- for (uint256 j; j < details.offer.length; ++j) {
- SpentItem memory item = details.offer[j];
- if (item.amount != 0) {
- // Insert the item and increment insertion index.
- implicitExecutions[insertionIndex++] = Execution({
- offerer: item.itemType == ItemType.NATIVE
- ? fulfillmentDetails.seaport
- : details.offerer,
- conduitKey: details.conduitKey,
- item: ReceivedItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifier,
- amount: item.amount,
- recipient: fulfillmentDetails.recipient
- })
- });
- }
- }
- }
-
- // Set the final length of the implicit executions array.
- // Leave space for possible excess native token return.
- assembly {
- mstore(implicitExecutions, add(insertionIndex, 1))
- }
- }
-
- /**
- * @dev Process a Fulfillment into an Execution
- *
- * @param fulfillmentDetails fulfillment details
- * @param fulfillment A Fulfillment.
- *
- * @return An Execution.
- */
- function processExecutionFromFulfillment(
- FulfillmentDetails memory fulfillmentDetails,
- Fulfillment memory fulfillment
- ) internal pure returns (Execution memory) {
- // aggregate & zero-out the amounts of each offer item
- uint256 aggregatedOfferAmount;
- for (uint256 j = 0; j < fulfillment.offerComponents.length; j++) {
- FulfillmentComponent memory component = fulfillment.offerComponents[
- j
- ];
-
- OrderDetails memory details = fulfillmentDetails.orders[
- component.orderIndex
- ];
-
- if (component.itemIndex < details.offer.length) {
- SpentItem memory offerSpentItem = details.offer[
- component.itemIndex
- ];
-
- aggregatedOfferAmount += offerSpentItem.amount;
-
- offerSpentItem.amount = 0;
- }
- }
-
- // aggregate & zero-out the amounts of each offer item
- uint256 aggregatedConsiderationAmount;
- for (
- uint256 j = 0;
- j < fulfillment.considerationComponents.length;
- j++
- ) {
- FulfillmentComponent memory component = fulfillment
- .considerationComponents[j];
-
- OrderDetails memory details = fulfillmentDetails.orders[
- component.orderIndex
- ];
-
- if (component.itemIndex < details.consideration.length) {
- ReceivedItem memory considerationSpentItem = details
- .consideration[component.itemIndex];
-
- aggregatedConsiderationAmount += considerationSpentItem.amount;
-
- considerationSpentItem.amount = 0;
- }
- }
-
- // Get the first item on each side
- FulfillmentComponent memory firstOfferComponent = fulfillment
- .offerComponents[0];
- OrderDetails memory sourceOrder = fulfillmentDetails.orders[
- firstOfferComponent.orderIndex
- ];
-
- FulfillmentComponent memory firstConsiderationComponent = fulfillment
- .considerationComponents[0];
- ReceivedItem memory item = fulfillmentDetails
- .orders[firstConsiderationComponent.orderIndex]
- .consideration[firstConsiderationComponent.itemIndex];
-
- // put back any extra (TODO: put it on first *in-range* item)
- uint256 amount = aggregatedOfferAmount;
- if (aggregatedOfferAmount > aggregatedConsiderationAmount) {
- sourceOrder
- .offer[firstOfferComponent.itemIndex]
- .amount += (aggregatedOfferAmount -
- aggregatedConsiderationAmount);
- amount = aggregatedConsiderationAmount;
- } else if (aggregatedOfferAmount < aggregatedConsiderationAmount) {
- item.amount += (aggregatedConsiderationAmount -
- aggregatedOfferAmount);
- }
-
- return
- Execution({
- offerer: sourceOrder.offerer,
- conduitKey: sourceOrder.conduitKey,
- item: ReceivedItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifier,
- amount: amount,
- recipient: item.recipient
- })
- });
- }
-
- /**
- * @dev Process excess native tokens. If there are excess native tokens,
- * insert an implicit execution at the end of the implicitExecutions
- * array. If not, reduce the length of the implicitExecutions array.
- *
- * @param fulfillmentDetails fulfillment details
- * @param explicitExecutions explicit executions
- * @param implicitExecutionsPre implicit executions
- * @param implicitExecutionsPost implicit executions
- */
- function _handleExcessNativeTokens(
- FulfillmentDetails memory fulfillmentDetails,
- Execution[] memory explicitExecutions,
- Execution[] memory implicitExecutionsPre,
- Execution[] memory implicitExecutionsPost
- ) internal pure returns (uint256 excessNativeTokens) {
- excessNativeTokens = processExcessNativeTokens(
- explicitExecutions,
- implicitExecutionsPre,
- implicitExecutionsPost
- );
-
- if (excessNativeTokens > 0) {
- implicitExecutionsPost[
- implicitExecutionsPost.length - 1
- ] = Execution({
- offerer: fulfillmentDetails.seaport,
- conduitKey: bytes32(0),
- item: ReceivedItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifier: 0,
- amount: excessNativeTokens,
- recipient: fulfillmentDetails.fulfiller
- })
- });
- } else {
- // Reduce length of the implicit executions array by one.
- assembly {
- mstore(
- implicitExecutionsPost,
- sub(mload(implicitExecutionsPost), 1)
- )
- }
- }
- }
-
- function copy(
- OrderDetails[] memory orderDetails
- ) internal pure returns (OrderDetails[] memory copiedOrderDetails) {
- copiedOrderDetails = new OrderDetails[](orderDetails.length);
- for (uint256 i = 0; i < orderDetails.length; ++i) {
- OrderDetails memory order = orderDetails[i];
-
- copiedOrderDetails[i] = OrderDetails({
- offerer: order.offerer,
- conduitKey: order.conduitKey,
- offer: order.offer.copy(),
- consideration: order.consideration.copy(),
- isContract: order.isContract,
- orderHash: order.orderHash,
- unavailableReason: order.unavailableReason
- });
- }
- }
-
- function copy(
- FulfillmentDetails memory fulfillmentDetails
- ) internal pure returns (FulfillmentDetails memory) {
- return
- FulfillmentDetails({
- orders: copy(fulfillmentDetails.orders),
- recipient: fulfillmentDetails.recipient,
- fulfiller: fulfillmentDetails.fulfiller,
- nativeTokensSupplied: fulfillmentDetails.nativeTokensSupplied,
- fulfillerConduitKey: fulfillmentDetails.fulfillerConduitKey,
- seaport: fulfillmentDetails.seaport
- });
- }
-}
diff --git a/contracts/helpers/sol/executions/FulfillmentComponentSet.sol b/contracts/helpers/sol/executions/FulfillmentComponentSet.sol
deleted file mode 100644
index 0bc9e7901..000000000
--- a/contracts/helpers/sol/executions/FulfillmentComponentSet.sol
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { FulfillmentComponent } from "../SeaportStructs.sol";
-
-struct FulfillmentComponentSet {
- mapping(bytes32 => uint256) offByOneIndex;
- FulfillmentComponent[] enumeration;
-}
-
-library FulfillmentComponentSetLib {
- error NotPresent();
-
- function add(
- FulfillmentComponentSet storage set,
- FulfillmentComponent memory value
- ) internal returns (bool added) {
- // add value to enumeration; hash it to set its entry in the offByOneIndex
- bytes32 key = keccak256(abi.encode(value));
- if (set.offByOneIndex[key] == 0) {
- set.enumeration.push(value);
- set.offByOneIndex[key] = set.enumeration.length;
- added = true;
- } else {
- added = false;
- }
- }
-
- // remove value from enumeration and replace it with last member of enumeration
- // if not last member, update offByOneIndex of last member
- function remove(
- FulfillmentComponentSet storage set,
- FulfillmentComponent memory value
- ) internal returns (bool removed) {
- bytes32 key = keccak256(abi.encode(value));
- uint256 index = set.offByOneIndex[key];
- if (index > 0) {
- uint256 lastIndex = set.enumeration.length - 1;
- FulfillmentComponent memory lastValue = set.enumeration[lastIndex];
- set.enumeration[index - 1] = lastValue;
- bytes32 lastKey = keccak256(abi.encode(lastValue));
- // if lastKey is the same as key, then we are removing the last element; do not update it
- if (lastKey != key) {
- set.offByOneIndex[lastKey] = index;
- }
- set.enumeration.pop();
- delete set.offByOneIndex[key];
- removed = true;
- } else {
- removed = false;
- }
- }
-
- function removeAll(
- FulfillmentComponentSet storage set,
- FulfillmentComponent[] memory values
- ) internal {
- for (uint256 i = 0; i < values.length; i++) {
- remove(set, values[i]);
- }
- }
-
- function removeAll(
- FulfillmentComponentSet storage set,
- FulfillmentComponent[][] memory values
- ) internal {
- for (uint256 i = 0; i < values.length; i++) {
- removeAll(set, values[i]);
- }
- }
-
- function contains(
- FulfillmentComponentSet storage set,
- FulfillmentComponent memory value
- ) internal view returns (bool) {
- return set.offByOneIndex[keccak256(abi.encode(value))] > 0;
- }
-
- function length(
- FulfillmentComponentSet storage set
- ) internal view returns (uint256) {
- return set.enumeration.length;
- }
-
- function at(
- FulfillmentComponentSet storage set,
- uint256 index
- ) internal view returns (FulfillmentComponent memory) {
- return set.enumeration[index];
- }
-
- function clear(FulfillmentComponentSet storage set) internal {
- while (set.enumeration.length > 0) {
- FulfillmentComponent memory component = set.enumeration[
- set.enumeration.length - 1
- ];
- delete set.offByOneIndex[keccak256(abi.encode(component))];
- set.enumeration.pop();
- }
- }
-}
diff --git a/contracts/helpers/sol/executions/FulfillmentComponentSortLib.sol b/contracts/helpers/sol/executions/FulfillmentComponentSortLib.sol
deleted file mode 100644
index 8b9ef90c1..000000000
--- a/contracts/helpers/sol/executions/FulfillmentComponentSortLib.sol
+++ /dev/null
@@ -1,97 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { FulfillmentComponent } from "../SeaportStructs.sol";
-
-library FulfillmentComponentSortLib {
- function key(
- FulfillmentComponent memory component
- ) internal pure returns (uint256) {
- return (uint256(component.orderIndex) << 8) | component.itemIndex;
- }
-
- function sort(FulfillmentComponent[] memory components) internal pure {
- sort(components, key);
- }
-
- // Sorts the array in-place with intro-quicksort.
- function sort(
- FulfillmentComponent[] memory a,
- function(FulfillmentComponent memory)
- internal
- pure
- returns (uint256) accessor
- ) internal pure {
- if (a.length < 2) {
- return;
- }
-
- uint256[] memory stack = new uint256[](2 * a.length);
- uint256 stackIndex = 0;
-
- uint256 l = 0;
- uint256 h = a.length - 1;
-
- stack[stackIndex++] = l;
- stack[stackIndex++] = h;
-
- while (stackIndex > 0) {
- h = stack[--stackIndex];
- l = stack[--stackIndex];
-
- if (h - l <= 12) {
- // Insertion sort for small subarrays
- for (uint256 i = l + 1; i <= h; i++) {
- FulfillmentComponent memory k = a[i];
- uint256 j = i;
- while (j > l && accessor(a[j - 1]) > accessor(k)) {
- a[j] = a[j - 1];
- j--;
- }
- a[j] = k;
- }
- } else {
- // Intro-Quicksort
- uint256 p = (l + h) / 2;
-
- // Median of 3
- if (accessor(a[l]) > accessor(a[p])) {
- (a[l], a[p]) = (a[p], a[l]);
- }
- if (accessor(a[l]) > accessor(a[h])) {
- (a[l], a[h]) = (a[h], a[l]);
- }
- if (accessor(a[p]) > accessor(a[h])) {
- (a[p], a[h]) = (a[h], a[p]);
- }
-
- uint256 pivot = accessor(a[p]);
- uint256 i = l;
- uint256 j = h;
-
- while (i <= j) {
- while (accessor(a[i]) < pivot) {
- i++;
- }
- while (accessor(a[j]) > pivot) {
- j--;
- }
- if (i <= j) {
- (a[i], a[j]) = (a[j], a[i]);
- i++;
- j--;
- }
- }
-
- if (j > l) {
- stack[stackIndex++] = l;
- stack[stackIndex++] = j;
- }
- if (i < h) {
- stack[stackIndex++] = i;
- stack[stackIndex++] = h;
- }
- }
- }
- }
-}
diff --git a/contracts/helpers/sol/executions/GenericEnumerableMapping.sol b/contracts/helpers/sol/executions/GenericEnumerableMapping.sol
deleted file mode 100644
index 0bc9e7901..000000000
--- a/contracts/helpers/sol/executions/GenericEnumerableMapping.sol
+++ /dev/null
@@ -1,101 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { FulfillmentComponent } from "../SeaportStructs.sol";
-
-struct FulfillmentComponentSet {
- mapping(bytes32 => uint256) offByOneIndex;
- FulfillmentComponent[] enumeration;
-}
-
-library FulfillmentComponentSetLib {
- error NotPresent();
-
- function add(
- FulfillmentComponentSet storage set,
- FulfillmentComponent memory value
- ) internal returns (bool added) {
- // add value to enumeration; hash it to set its entry in the offByOneIndex
- bytes32 key = keccak256(abi.encode(value));
- if (set.offByOneIndex[key] == 0) {
- set.enumeration.push(value);
- set.offByOneIndex[key] = set.enumeration.length;
- added = true;
- } else {
- added = false;
- }
- }
-
- // remove value from enumeration and replace it with last member of enumeration
- // if not last member, update offByOneIndex of last member
- function remove(
- FulfillmentComponentSet storage set,
- FulfillmentComponent memory value
- ) internal returns (bool removed) {
- bytes32 key = keccak256(abi.encode(value));
- uint256 index = set.offByOneIndex[key];
- if (index > 0) {
- uint256 lastIndex = set.enumeration.length - 1;
- FulfillmentComponent memory lastValue = set.enumeration[lastIndex];
- set.enumeration[index - 1] = lastValue;
- bytes32 lastKey = keccak256(abi.encode(lastValue));
- // if lastKey is the same as key, then we are removing the last element; do not update it
- if (lastKey != key) {
- set.offByOneIndex[lastKey] = index;
- }
- set.enumeration.pop();
- delete set.offByOneIndex[key];
- removed = true;
- } else {
- removed = false;
- }
- }
-
- function removeAll(
- FulfillmentComponentSet storage set,
- FulfillmentComponent[] memory values
- ) internal {
- for (uint256 i = 0; i < values.length; i++) {
- remove(set, values[i]);
- }
- }
-
- function removeAll(
- FulfillmentComponentSet storage set,
- FulfillmentComponent[][] memory values
- ) internal {
- for (uint256 i = 0; i < values.length; i++) {
- removeAll(set, values[i]);
- }
- }
-
- function contains(
- FulfillmentComponentSet storage set,
- FulfillmentComponent memory value
- ) internal view returns (bool) {
- return set.offByOneIndex[keccak256(abi.encode(value))] > 0;
- }
-
- function length(
- FulfillmentComponentSet storage set
- ) internal view returns (uint256) {
- return set.enumeration.length;
- }
-
- function at(
- FulfillmentComponentSet storage set,
- uint256 index
- ) internal view returns (FulfillmentComponent memory) {
- return set.enumeration[index];
- }
-
- function clear(FulfillmentComponentSet storage set) internal {
- while (set.enumeration.length > 0) {
- FulfillmentComponent memory component = set.enumeration[
- set.enumeration.length - 1
- ];
- delete set.offByOneIndex[keccak256(abi.encode(component))];
- set.enumeration.pop();
- }
- }
-}
diff --git a/contracts/helpers/sol/fulfillments/available/FulfillAvailableHelper.sol b/contracts/helpers/sol/fulfillments/available/FulfillAvailableHelper.sol
deleted file mode 100644
index f1460c0b2..000000000
--- a/contracts/helpers/sol/fulfillments/available/FulfillAvailableHelper.sol
+++ /dev/null
@@ -1,402 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import "../../SeaportStructs.sol";
-import "../../lib/SeaportArrays.sol";
-import {
- FulfillAvailableHelperStorageLayout,
- FulfillmentHelperCounterLayout,
- AggregatableOffer,
- AggregatableConsideration
-} from "../lib/Structs.sol";
-import { FulfillAvailableLayout } from "./FulfillAvailableLayout.sol";
-import {
- FULFILL_AVAILABLE_COUNTER_KEY,
- FULFILL_AVAILABLE_STORAGE_BASE_KEY
-} from "../lib/Constants.sol";
-import { OrderDetails } from "../lib/Structs.sol";
-
-contract FulfillAvailableHelper {
- /**
- * @notice get naive 2d fulfillment component arrays for
- * fulfillAvailableOrders, one 1d array for each offer and consideration
- * item
- * @param orders orders
- * @return offer
- * @return consideration
- */
- function getNaiveFulfillmentComponents(
- Order[] memory orders
- )
- public
- pure
- returns (
- FulfillmentComponent[][] memory offer,
- FulfillmentComponent[][] memory consideration
- )
- {
- OrderParameters[] memory orderParameters = new OrderParameters[](
- orders.length
- );
- for (uint256 i = 0; i < orders.length; i++) {
- orderParameters[i] = orders[i].parameters;
- }
- return getNaiveFulfillmentComponents(orderParameters);
- }
-
- /**
- * @notice get naive 2d fulfillment component arrays for
- * fulfillAvailableOrders, one 1d array for each offer and consideration
- * item
- * @param orders orders
- * @return offer
- * @return consideration
- */
- function getNaiveFulfillmentComponents(
- AdvancedOrder[] memory orders
- )
- public
- pure
- returns (
- FulfillmentComponent[][] memory offer,
- FulfillmentComponent[][] memory consideration
- )
- {
- OrderParameters[] memory orderParameters = new OrderParameters[](
- orders.length
- );
- for (uint256 i = 0; i < orders.length; i++) {
- orderParameters[i] = orders[i].parameters;
- }
- return getNaiveFulfillmentComponents(orderParameters);
- }
-
- /**
- * @notice get naive 2d fulfillment component arrays for
- * fulfillAvailableOrders, one 1d array for each offer and consideration
- * item
- * @param orderParameters orderParameters
- * @return offer
- * @return consideration
- */
- function getNaiveFulfillmentComponents(
- OrderParameters[] memory orderParameters
- )
- public
- pure
- returns (
- FulfillmentComponent[][] memory offer,
- FulfillmentComponent[][] memory consideration
- )
- {
- {
- // get total number of offer items and consideration items
- uint256 numOffers;
- uint256 numConsiderations;
- for (uint256 i = 0; i < orderParameters.length; i++) {
- OrderParameters memory parameters = orderParameters[i];
-
- numOffers += parameters.offer.length;
- numConsiderations += parameters.consideration.length;
- }
-
- // create arrays
- offer = new FulfillmentComponent[][](numOffers);
- consideration = new FulfillmentComponent[][](numConsiderations);
- }
-
- uint256 offerIndex;
- uint256 considerationIndex;
- // iterate over orders again, creating one one-element array per offer and consideration item
- for (uint256 i = 0; i < orderParameters.length; i++) {
- OrderParameters memory parameters = orderParameters[i];
- for (uint256 j; j < parameters.offer.length; j++) {
- offer[offerIndex] = SeaportArrays.FulfillmentComponents(
- FulfillmentComponent({ orderIndex: i, itemIndex: j })
- );
- ++offerIndex;
- }
- // do the same for consideration
- for (uint256 j; j < parameters.consideration.length; j++) {
- consideration[considerationIndex] = SeaportArrays
- .FulfillmentComponents(
- FulfillmentComponent({ orderIndex: i, itemIndex: j })
- );
- ++considerationIndex;
- }
- }
- return (offer, consideration);
- }
-
- /**
- * @notice get naive 2d fulfillment component arrays for
- * fulfillAvailableOrders, one 1d array for each offer and consideration
- * item
- * @param orders OrderDetails[]
- * @return offer
- * @return consideration
- */
- function getNaiveFulfillmentComponents(
- OrderDetails[] memory orders
- )
- public
- pure
- returns (
- FulfillmentComponent[][] memory offer,
- FulfillmentComponent[][] memory consideration
- )
- {
- {
- // get total number of offer items and consideration items
- uint256 numOffers;
- uint256 numConsiderations;
- for (uint256 i = 0; i < orders.length; i++) {
- OrderDetails memory order = orders[i];
-
- numOffers += order.offer.length;
- numConsiderations += order.consideration.length;
- }
-
- // create arrays
- offer = new FulfillmentComponent[][](numOffers);
- consideration = new FulfillmentComponent[][](numConsiderations);
- }
-
- uint256 offerIndex;
- uint256 considerationIndex;
- // iterate over orders again, creating one one-element array per offer and consideration item
- for (uint256 i = 0; i < orders.length; i++) {
- OrderDetails memory order = orders[i];
- for (uint256 j; j < order.offer.length; j++) {
- offer[offerIndex] = SeaportArrays.FulfillmentComponents(
- FulfillmentComponent({ orderIndex: i, itemIndex: j })
- );
- ++offerIndex;
- }
- // do the same for consideration
- for (uint256 j; j < order.consideration.length; j++) {
- consideration[considerationIndex] = SeaportArrays
- .FulfillmentComponents(
- FulfillmentComponent({ orderIndex: i, itemIndex: j })
- );
- ++considerationIndex;
- }
- }
- return (offer, consideration);
- }
-
- /**
- * @notice Get aggregated fulfillment components for aggregatable types from the same offerer or to the same recipient
- * NOTE: this will break for multiple criteria items that resolve
- * to different identifiers
- * @param orders orders
- * @return offer
- * @return consideration
- */
- function getAggregatedFulfillmentComponents(
- Order[] memory orders
- )
- public
- returns (
- FulfillmentComponent[][] memory offer,
- FulfillmentComponent[][] memory consideration
- )
- {
- OrderParameters[] memory orderParameters = new OrderParameters[](
- orders.length
- );
- for (uint256 i = 0; i < orders.length; i++) {
- orderParameters[i] = orders[i].parameters;
- }
- return getAggregatedFulfillmentComponents(orderParameters);
- }
-
- /**
- * @notice Get aggregated fulfillment components for aggregatable types from the same offerer or to the same recipient
- * NOTE: this will break for multiple criteria items that resolve
- * to different identifiers
- * @param orders orders
- * @return offer
- * @return consideration
- */
- function getAggregatedFulfillmentComponents(
- AdvancedOrder[] memory orders
- )
- public
- returns (
- FulfillmentComponent[][] memory offer,
- FulfillmentComponent[][] memory consideration
- )
- {
- OrderParameters[] memory orderParameters = new OrderParameters[](
- orders.length
- );
- for (uint256 i = 0; i < orders.length; i++) {
- orderParameters[i] = orders[i].parameters;
- }
- return getAggregatedFulfillmentComponents(orderParameters);
- }
-
- /**
- * @notice Get aggregated fulfillment components for aggregatable types from the same offerer or to the same recipient
- * NOTE: this will break for multiple criteria items that resolve
- * to different identifiers
- * @param orders orders
- * @return offer
- * @return consideration
- */
- function getAggregatedFulfillmentComponents(
- OrderParameters[] memory orders
- )
- public
- returns (
- FulfillmentComponent[][] memory offer,
- FulfillmentComponent[][] memory consideration
- )
- {
- // increment counter to get clean mappings and enumeration
- FulfillAvailableLayout.incrementFulfillmentCounter();
- FulfillAvailableHelperStorageLayout
- storage layout = FulfillAvailableLayout.getStorageLayout();
-
- // iterate over each order
- for (uint256 i; i < orders.length; ++i) {
- OrderParameters memory parameters = orders[i];
- preProcessOffer(
- parameters.offer,
- parameters.offerer,
- parameters.conduitKey,
- i,
- layout
- );
- preProcessConsideration(parameters.consideration, i, layout);
- }
-
- // allocate offer arrays
- offer = new FulfillmentComponent[][](layout.offerEnumeration.length);
- // iterate over enumerated groupings and add to array
- for (uint256 i; i < layout.offerEnumeration.length; ++i) {
- AggregatableOffer memory token = layout.offerEnumeration[i];
-
- offer[i] = layout.offerMap[token.contractAddress][token.tokenId][
- token.offerer
- ][token.conduitKey];
- }
- // do the same for considerations
- consideration = new FulfillmentComponent[][](
- layout.considerationEnumeration.length
- );
- for (uint256 i; i < layout.considerationEnumeration.length; ++i) {
- AggregatableConsideration memory token = layout
- .considerationEnumeration[i];
- consideration[i] = layout.considerationMap[token.recipient][
- token.contractAddress
- ][token.tokenId];
- }
- return (offer, consideration);
- }
-
- function extend(
- FulfillmentComponent[][] memory array,
- FulfillmentComponent[] memory toAdd
- ) internal pure returns (FulfillmentComponent[][] memory extended) {
- extended = new FulfillmentComponent[][](array.length + 1);
- for (uint256 i = 0; i < array.length; i++) {
- extended[i] = array[i];
- }
- extended[array.length] = toAdd;
- }
-
- /**
- * @notice Process offer items and insert them into enumeration and map
- * @param offer offer items
- * @param offerer offerer
- * @param orderIndex order index of processed items
- * @param layout layout
- */
- function preProcessOffer(
- OfferItem[] memory offer,
- address offerer,
- bytes32 conduitKey,
- uint256 orderIndex,
- FulfillAvailableHelperStorageLayout storage layout
- ) private {
- // iterate over each offer item
- for (uint256 j; j < offer.length; ++j) {
- // create the fulfillment component for this offer item
- FulfillmentComponent memory component = FulfillmentComponent({
- orderIndex: orderIndex,
- itemIndex: j
- });
- // grab order parameters to get offerer
- // grab offer item
- OfferItem memory item = offer[j];
- // create enumeration struct
- AggregatableOffer memory aggregatableOffer = AggregatableOffer({
- offerer: offerer,
- conduitKey: conduitKey,
- contractAddress: item.token,
- tokenId: item.identifierOrCriteria
- });
- // if it does not exist in the map, add it to our enumeration
- if (
- !FulfillAvailableLayout.aggregatableOfferExists(
- aggregatableOffer,
- layout
- )
- ) {
- layout.offerEnumeration.push(aggregatableOffer);
- }
- // update mapping with this component
- layout
- .offerMap[aggregatableOffer.contractAddress][
- aggregatableOffer.tokenId
- ][aggregatableOffer.offerer][aggregatableOffer.conduitKey].push(
- component
- );
- }
- }
-
- /**
- * @notice Process consideration items and insert them into enumeration and map
- * @param consideration consideration items
- * @param orderIndex order index of processed items
- * @param layout layout
- */
- function preProcessConsideration(
- ConsiderationItem[] memory consideration,
- uint256 orderIndex,
- FulfillAvailableHelperStorageLayout storage layout
- ) private {
- // iterate over each offer item
- for (uint256 j; j < consideration.length; ++j) {
- // create the fulfillment component for this offer item
- FulfillmentComponent memory component = FulfillmentComponent({
- orderIndex: orderIndex,
- itemIndex: j
- });
- // grab consideration item
- ConsiderationItem memory item = consideration[j];
- // create enumeration struct
- AggregatableConsideration memory token = AggregatableConsideration({
- recipient: item.recipient,
- contractAddress: item.token,
- tokenId: item.identifierOrCriteria
- });
- // if it does not exist in the map, add it to our enumeration
- if (
- !FulfillAvailableLayout.aggregatableConsiderationExists(
- token,
- layout
- )
- ) {
- layout.considerationEnumeration.push(token);
- }
- // update mapping with this component
- layout
- .considerationMap[token.recipient][token.contractAddress][
- token.tokenId
- ].push(component);
- }
- }
-}
diff --git a/contracts/helpers/sol/fulfillments/available/FulfillAvailableLayout.sol b/contracts/helpers/sol/fulfillments/available/FulfillAvailableLayout.sol
deleted file mode 100644
index d9fa4db8c..000000000
--- a/contracts/helpers/sol/fulfillments/available/FulfillAvailableLayout.sol
+++ /dev/null
@@ -1,128 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- MatchComponent,
- MatchComponentType
-} from "../../lib/types/MatchComponentType.sol";
-import {
- FulfillAvailableHelperStorageLayout,
- FulfillmentHelperCounterLayout,
- AggregatableConsideration,
- AggregatableOffer
-} from "../lib/Structs.sol";
-import {
- FULFILL_AVAILABLE_COUNTER_KEY,
- FULFILL_AVAILABLE_STORAGE_BASE_KEY
-} from "../lib/Constants.sol";
-
-library FulfillAvailableLayout {
- /**
- * @notice Check if a token already exists in a mapping by checking the length of the array at that slot
- * @param token token to check
- * @param layout storage layout
- */
- function aggregatableConsiderationExists(
- AggregatableConsideration memory token,
- FulfillAvailableHelperStorageLayout storage layout
- ) internal view returns (bool) {
- return
- layout
- .considerationMap[token.recipient][token.contractAddress][
- token.tokenId
- ].length > 0;
- }
-
- /**
- * @notice Check if an entry into the offer component mapping already exists by checking its length
- */
- function aggregatableOfferExists(
- AggregatableOffer memory offer,
- FulfillAvailableHelperStorageLayout storage layout
- ) internal view returns (bool) {
- return
- layout
- .offerMap[offer.contractAddress][offer.tokenId][offer.offerer][
- offer.conduitKey
- ].length > 0;
- }
-
- /**
- * @notice load storage layout for the current fulfillmentCounter
- */
- function getStorageLayout()
- internal
- view
- returns (FulfillAvailableHelperStorageLayout storage layout)
- {
- FulfillmentHelperCounterLayout
- storage counterLayout = getCounterLayout();
- uint256 counter = counterLayout.fulfillmentCounter;
- bytes32 storageLayoutKey = FULFILL_AVAILABLE_STORAGE_BASE_KEY;
- assembly {
- mstore(0, counter)
- mstore(0x20, storageLayoutKey)
- layout.slot := keccak256(0, 0x40)
- }
- }
-
- /**
- * @notice load storage layout for the counter itself
- */
- function getCounterLayout()
- internal
- pure
- returns (FulfillmentHelperCounterLayout storage layout)
- {
- bytes32 counterLayoutKey = FULFILL_AVAILABLE_COUNTER_KEY;
- assembly {
- layout.slot := counterLayoutKey
- }
- }
-
- /**
- * @notice increment the fulfillmentCounter to effectively clear the mappings and enumerations between calls
- */
- function incrementFulfillmentCounter() internal {
- FulfillmentHelperCounterLayout
- storage counterLayout = getCounterLayout();
- counterLayout.fulfillmentCounter += 1;
- }
-
- /**
- * @notice Get the mapping of tokens for a given key (offer or consideration), derived from the hash of the key and the current fulfillmentCounter value
- * @param key Original key used to derive the slot of the enumeration
- */
- function getMap(
- bytes32 key
- )
- internal
- view
- returns (
- mapping(address /*offererOrRecipient*/ => mapping(address /*tokenContract*/ => mapping(uint256 /*identifier*/ => MatchComponent[] /*components*/)))
- storage map
- )
- {
- bytes32 counterKey = FULFILL_AVAILABLE_COUNTER_KEY;
- assembly {
- mstore(0, key)
- mstore(0x20, sload(counterKey))
- map.slot := keccak256(0, 0x40)
- }
- }
-
- /**
- * @notice Get the enumeration of AggregatableConsiderations for a given key (offer or consideration), derived from the hash of the key and the current fulfillmentCounter value
- * @param key Original key used to derive the slot of the enumeration
- */
- function getEnumeration(
- bytes32 key
- ) internal view returns (AggregatableConsideration[] storage tokens) {
- bytes32 counterKey = FULFILL_AVAILABLE_COUNTER_KEY;
- assembly {
- mstore(0, key)
- mstore(0x20, sload(counterKey))
- tokens.slot := keccak256(0, 0x40)
- }
- }
-}
diff --git a/contracts/helpers/sol/fulfillments/lib/Constants.sol b/contracts/helpers/sol/fulfillments/lib/Constants.sol
deleted file mode 100644
index d97eb31e7..000000000
--- a/contracts/helpers/sol/fulfillments/lib/Constants.sol
+++ /dev/null
@@ -1,20 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-// used to effectively "wipe" the mappings and enumerations each time getAggregated is called
-bytes32 constant MATCH_FULFILLMENT_COUNTER_KEY = keccak256(
- "MatchFulfillmentHelper.fulfillmentCounter"
-);
-
-bytes32 constant MATCH_FULFILLMENT_STORAGE_BASE_KEY = keccak256(
- "MatchFulfillmentHelper.storageBase"
-);
-
-// used to effectively "wipe" the mappings and enumerations each time getAggregated is called
-bytes32 constant FULFILL_AVAILABLE_COUNTER_KEY = keccak256(
- "FulfillAvailableHelper.fulfillmentCounter"
-);
-
-bytes32 constant FULFILL_AVAILABLE_STORAGE_BASE_KEY = keccak256(
- "FulfillAvailableHelper.storageBase"
-);
diff --git a/contracts/helpers/sol/fulfillments/lib/FulfillmentLib.sol b/contracts/helpers/sol/fulfillments/lib/FulfillmentLib.sol
deleted file mode 100644
index 4fa28488f..000000000
--- a/contracts/helpers/sol/fulfillments/lib/FulfillmentLib.sol
+++ /dev/null
@@ -1,2271 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { LibPRNG } from "solady/src/utils/LibPRNG.sol";
-
-import { LibSort } from "solady/src/utils/LibSort.sol";
-
-import {
- FulfillmentComponent,
- Fulfillment,
- Order,
- AdvancedOrder,
- OrderParameters,
- SpentItem,
- ReceivedItem,
- CriteriaResolver
-} from "../../SeaportStructs.sol";
-
-import { ItemType, Side } from "../../SeaportEnums.sol";
-
-import { MatchComponent, OrderDetails } from "./Structs.sol";
-
-enum FulfillmentEligibility {
- NONE,
- FULFILL_AVAILABLE,
- MATCH,
- BOTH
-}
-
-enum AggregationStrategy {
- MINIMUM, // Aggregate as few items as possible
- MAXIMUM, // Aggregate as many items as possible
- RANDOM // Randomize aggregation quantity
- // NOTE: for match cases, there may be more sophisticated optimal strategies
-}
-
-enum FulfillAvailableStrategy {
- KEEP_ALL, // Persist default aggregation strategy
- DROP_SINGLE_OFFER, // Exclude aggregations for single offer items
- DROP_ALL_OFFER, // Exclude offer aggregations (keep one if no consideration)
- DROP_RANDOM_OFFER, // Exclude random offer aggregations
- DROP_SINGLE_KEEP_FILTERED, // Exclude single unless it would be filtered
- DROP_ALL_KEEP_FILTERED, // Exclude all unfilterable offer aggregations
- DROP_RANDOM_KEEP_FILTERED // Exclude random, unfilterable offer aggregations
-}
-
-enum MatchStrategy {
- MAX_FILTERS, // prioritize locating filterable executions
- MIN_FILTERS, // prioritize avoiding filterable executions where possible
- MAX_INCLUSION, // try not to leave any unspent offer items
- MIN_INCLUSION, // leave as many unspent offer items as possible
- MIN_INCLUSION_MAX_FILTERS, // leave unspent items if not filterable
- MAX_EXECUTIONS, // use as many fulfillments as possible given aggregations
- MIN_EXECUTIONS, // use as few fulfillments as possible given aggregations
- MIN_EXECUTIONS_MAX_FILTERS // minimize fulfillments and prioritize filters
- // NOTE: more sophisticated match strategies require modifying aggregations
-}
-
-enum ItemCategory {
- NATIVE,
- ERC721,
- OTHER
-}
-
-struct FulfillmentStrategy {
- AggregationStrategy aggregationStrategy;
- FulfillAvailableStrategy fulfillAvailableStrategy;
- MatchStrategy matchStrategy;
-}
-
-struct FulfillmentItem {
- uint256 orderIndex;
- uint256 itemIndex;
- uint256 amount;
- address account;
-}
-
-struct FulfillmentItems {
- ItemCategory itemCategory;
- uint256 totalAmount;
- FulfillmentItem[] items;
-}
-
-struct DualFulfillmentItems {
- FulfillmentItems[] offer;
- FulfillmentItems[] consideration;
-}
-
-struct DualFulfillmentMatchContext {
- ItemCategory itemCategory;
- uint256 totalOfferAmount;
- uint256 totalConsiderationAmount;
-}
-
-struct FulfillAvailableDetails {
- DualFulfillmentItems items;
- address caller;
- address recipient;
- uint256 totalItems;
-}
-
-struct MatchDetails {
- DualFulfillmentItems[] items;
- DualFulfillmentMatchContext[] context;
- address recipient;
- uint256 totalItems;
-}
-
-library FulfillmentGeneratorLib {
- using LibPRNG for LibPRNG.PRNG;
- using ItemReferenceLib for OrderDetails[];
- using FulfillmentPrepLib for ItemReferenceLib.ItemReference[];
-
- function getDefaultFulfillmentStrategy()
- internal
- pure
- returns (FulfillmentStrategy memory)
- {
- return
- FulfillmentStrategy({
- aggregationStrategy: AggregationStrategy.MAXIMUM,
- fulfillAvailableStrategy: FulfillAvailableStrategy.KEEP_ALL,
- matchStrategy: MatchStrategy.MAX_INCLUSION
- });
- }
-
- // This uses the "default" set of strategies and applies no randomization.
- function getFulfillments(
- OrderDetails[] memory orderDetails,
- address recipient,
- address caller
- )
- internal
- pure
- returns (
- FulfillmentEligibility eligibility,
- FulfillmentComponent[][] memory offerFulfillments,
- FulfillmentComponent[][] memory considerationFulfillments,
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- uint256 seed = 0;
-
- return
- getFulfillments(
- orderDetails,
- getDefaultFulfillmentStrategy(),
- recipient,
- caller,
- seed
- );
- }
-
- function getFulfillments(
- OrderDetails[] memory orderDetails,
- FulfillmentStrategy memory strategy,
- address recipient,
- address caller,
- uint256 seed
- )
- internal
- pure
- returns (
- FulfillmentEligibility eligibility,
- FulfillmentComponent[][] memory offerFulfillments,
- FulfillmentComponent[][] memory considerationFulfillments,
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- ItemReferenceLib.ItemReference[] memory references = orderDetails
- .getItemReferences(seed);
-
- (
- FulfillAvailableDetails memory fulfillAvailableDetails,
- MatchDetails memory matchDetails
- ) = references.getDetails(recipient, caller);
-
- return
- getFulfillmentsFromDetails(
- fulfillAvailableDetails,
- matchDetails,
- strategy,
- seed
- );
- }
-
- function getFulfillmentsFromDetails(
- FulfillAvailableDetails memory fulfillAvailableDetails,
- MatchDetails memory matchDetails,
- FulfillmentStrategy memory strategy,
- uint256 seed
- )
- internal
- pure
- returns (
- FulfillmentEligibility eligibility,
- FulfillmentComponent[][] memory offerFulfillments,
- FulfillmentComponent[][] memory considerationFulfillments,
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- assertSupportedStrategy(strategy);
-
- (
- fulfillments,
- unspentOfferComponents,
- unmetConsiderationComponents
- ) = getMatchFulfillments(matchDetails, strategy, seed);
-
- eligibility = determineEligibility(
- fulfillAvailableDetails,
- unmetConsiderationComponents.length
- );
-
- if (
- eligibility == FulfillmentEligibility.FULFILL_AVAILABLE ||
- eligibility == FulfillmentEligibility.BOTH
- ) {
- (
- offerFulfillments,
- considerationFulfillments
- ) = getFulfillAvailableFulfillments(
- fulfillAvailableDetails,
- strategy,
- seed
- );
- }
- }
-
- function assertSupportedStrategy(
- FulfillmentStrategy memory strategy
- ) internal pure {
- // TODO: add more strategies here as support is added for them.
- if (uint256(strategy.fulfillAvailableStrategy) > 3) {
- revert(
- "FulfillmentGeneratorLib: unsupported fulfillAvailable strategy"
- );
- }
-
- MatchStrategy matchStrategy = strategy.matchStrategy;
- if (matchStrategy != MatchStrategy.MAX_INCLUSION) {
- revert("FulfillmentGeneratorLib: unsupported match strategy");
- }
- }
-
- function determineEligibility(
- FulfillAvailableDetails memory fulfillAvailableDetails,
- uint256 totalUnmetConsiderationComponents
- ) internal pure returns (FulfillmentEligibility) {
- // FulfillAvailable: cannot be used if native offer items are present on
- // non-contract orders or if ERC721 items with amounts != 1 are present.
- // There must also be at least one unfiltered explicit execution. Note
- // that it is also *very* tricky to use FulfillAvailable in cases where
- // ERC721 items are present on both the offer side & consideration side.
- bool eligibleForFulfillAvailable = determineFulfillAvailableEligibility(
- fulfillAvailableDetails
- );
-
- // Match: cannot be used if there is no way to meet each consideration
- // item. In these cases, remaining offer components should be returned.
- bool eligibleForMatch = totalUnmetConsiderationComponents == 0;
-
- if (eligibleForFulfillAvailable) {
- return
- eligibleForMatch
- ? FulfillmentEligibility.BOTH
- : FulfillmentEligibility.FULFILL_AVAILABLE;
- }
-
- return
- eligibleForMatch
- ? FulfillmentEligibility.MATCH
- : FulfillmentEligibility.NONE;
- }
-
- // This uses the "default" set of strategies, applies no randomization, and
- // does not give a recipient & will not properly detect filtered executions.
- function getMatchedFulfillments(
- OrderDetails[] memory orderDetails
- )
- internal
- pure
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- return
- getMatchFulfillments(
- orderDetails.getItemReferences(0).getMatchDetailsFromReferences(
- address(0)
- )
- );
- }
-
- // This does not give a recipient & so will not detect filtered executions.
- function getMatchedFulfillments(
- OrderDetails[] memory orderDetails,
- FulfillmentStrategy memory strategy,
- uint256 seed
- )
- internal
- pure
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- return
- getMatchFulfillments(
- orderDetails.getItemReferences(0).getMatchDetailsFromReferences(
- address(0)
- ),
- strategy,
- seed
- );
- }
-
- function getMatchDetails(
- OrderDetails[] memory orderDetails,
- FulfillmentStrategy memory strategy,
- address recipient,
- uint256 seed
- )
- internal
- pure
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- return
- getMatchFulfillments(
- orderDetails
- .getItemReferences(seed)
- .getMatchDetailsFromReferences(recipient),
- strategy,
- seed
- );
- }
-
- // This uses the "default" set of strategies and applies no randomization.
- function getMatchFulfillments(
- MatchDetails memory matchDetails
- )
- internal
- pure
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- uint256 seed = 0;
-
- return
- getMatchFulfillments(
- matchDetails,
- getDefaultFulfillmentStrategy(),
- seed
- );
- }
-
- function getMatchFulfillments(
- MatchDetails memory matchDetails,
- FulfillmentStrategy memory strategy,
- uint256 seed
- )
- internal
- pure
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- MatchStrategy matchStrategy = strategy.matchStrategy;
-
- if (matchStrategy == MatchStrategy.MAX_INCLUSION) {
- (
- fulfillments,
- unspentOfferComponents,
- unmetConsiderationComponents
- ) = getMatchFulfillmentsUsingConsumeMethod(
- matchDetails,
- getMaxInclusionConsumeMethod(strategy.aggregationStrategy),
- seed
- );
- } else {
- revert("FulfillmentGeneratorLib: unsupported match strategy");
- }
- }
-
- function getMaxInclusionConsumeMethod(
- AggregationStrategy aggregationStrategy
- )
- internal
- pure
- returns (
- function(FulfillmentItems memory, FulfillmentItems memory, uint256)
- internal
- pure
- returns (Fulfillment memory)
- )
- {
- if (aggregationStrategy == AggregationStrategy.MAXIMUM) {
- return consumeMaximumItemsAndGetFulfillment;
- } else if (aggregationStrategy == AggregationStrategy.MINIMUM) {
- return consumeMinimumItemsAndGetFulfillment;
- } else if (aggregationStrategy == AggregationStrategy.RANDOM) {
- return consumeRandomItemsAndGetFulfillment;
- } else {
- revert(
- "FulfillmentGeneratorLib: unknown match aggregation strategy"
- );
- }
- }
-
- function getTotalUncoveredComponents(
- DualFulfillmentMatchContext[] memory contexts
- )
- internal
- pure
- returns (
- uint256 totalUnspentOfferComponents,
- uint256 totalUnmetConsiderationComponents
- )
- {
- for (uint256 i = 0; i < contexts.length; ++i) {
- DualFulfillmentMatchContext memory context = contexts[i];
-
- if (context.totalConsiderationAmount > context.totalOfferAmount) {
- ++totalUnmetConsiderationComponents;
- } else if (
- context.totalConsiderationAmount < context.totalOfferAmount
- ) {
- ++totalUnspentOfferComponents;
- }
- }
- }
-
- function getUncoveredComponents(
- MatchDetails memory matchDetails
- )
- internal
- pure
- returns (
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- (
- uint256 totalUnspentOfferComponents,
- uint256 totalUnmetConsiderationComponents
- ) = getTotalUncoveredComponents(matchDetails.context);
-
- unspentOfferComponents = (
- new MatchComponent[](totalUnspentOfferComponents)
- );
-
- unmetConsiderationComponents = (
- new MatchComponent[](totalUnmetConsiderationComponents)
- );
-
- if (
- totalUnspentOfferComponents + totalUnmetConsiderationComponents == 0
- ) {
- return (unspentOfferComponents, unmetConsiderationComponents);
- }
-
- totalUnspentOfferComponents = 0;
- totalUnmetConsiderationComponents = 0;
-
- for (uint256 i = 0; i < matchDetails.items.length; ++i) {
- DualFulfillmentMatchContext memory context = (
- matchDetails.context[i]
- );
-
- FulfillmentItems[] memory offer = matchDetails.items[i].offer;
-
- FulfillmentItems[] memory consideration = (
- matchDetails.items[i].consideration
- );
-
- if (context.totalConsiderationAmount > context.totalOfferAmount) {
- uint256 amount = (context.totalConsiderationAmount -
- context.totalOfferAmount);
-
- if (consideration.length == 0) {
- revert(
- "FulfillmentGeneratorLib: empty consideration array"
- );
- }
-
- if (consideration[0].items.length == 0) {
- revert(
- "FulfillmentGeneratorLib: empty consideration items"
- );
- }
-
- FulfillmentItem memory item = consideration[0].items[0];
-
- if (
- item.orderIndex > type(uint8).max ||
- item.itemIndex > type(uint8).max
- ) {
- revert(
- "FulfillmentGeneratorLib: OOR consideration item index"
- );
- }
-
- unmetConsiderationComponents[
- totalUnmetConsiderationComponents++
- ] = MatchComponent({
- amount: amount,
- orderIndex: uint8(item.orderIndex),
- itemIndex: uint8(item.itemIndex)
- });
- } else if (
- context.totalConsiderationAmount < context.totalOfferAmount
- ) {
- uint256 amount = (context.totalOfferAmount -
- context.totalConsiderationAmount);
-
- if (offer.length == 0) {
- revert("FulfillmentGeneratorLib: empty offer array");
- }
-
- if (offer[0].items.length == 0) {
- revert("FulfillmentGeneratorLib: empty offer items");
- }
-
- FulfillmentItem memory item = offer[0].items[0];
-
- if (
- item.orderIndex > type(uint8).max ||
- item.itemIndex > type(uint8).max
- ) {
- revert("FulfillmentGeneratorLib: OOR offer item index");
- }
-
- unspentOfferComponents[
- totalUnspentOfferComponents++
- ] = MatchComponent({
- amount: amount,
- orderIndex: uint8(item.orderIndex),
- itemIndex: uint8(item.itemIndex)
- });
- }
- }
-
- // Sanity checks
- if (unspentOfferComponents.length != totalUnspentOfferComponents) {
- revert(
- "FulfillmentGeneratorLib: unspent match item assignment error"
- );
- }
-
- if (
- unmetConsiderationComponents.length !=
- totalUnmetConsiderationComponents
- ) {
- revert(
- "FulfillmentGeneratorLib: unmet match item assignment error"
- );
- }
-
- for (uint256 i = 0; i < unspentOfferComponents.length; ++i) {
- if (unspentOfferComponents[i].amount == 0) {
- revert("FulfillmentGeneratorLib: unspent match amount of zero");
- }
- }
-
- for (uint256 i = 0; i < unmetConsiderationComponents.length; ++i) {
- if (unmetConsiderationComponents[i].amount == 0) {
- revert("FulfillmentGeneratorLib: unmet match amount of zero");
- }
- }
- }
-
- function getMatchFulfillmentsUsingConsumeMethod(
- MatchDetails memory matchDetails,
- function(FulfillmentItems memory, FulfillmentItems memory, uint256)
- internal
- pure
- returns (Fulfillment memory) consumeMethod,
- uint256 seed
- )
- internal
- pure
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory unspentOfferComponents,
- MatchComponent[] memory unmetConsiderationComponents
- )
- {
- if (matchDetails.totalItems == 0) {
- return (
- fulfillments,
- unspentOfferComponents,
- unmetConsiderationComponents
- );
- }
-
- (
- unspentOfferComponents,
- unmetConsiderationComponents
- ) = getUncoveredComponents(matchDetails);
-
- // Allocate based on max possible fulfillments; reduce after assignment.
- fulfillments = new Fulfillment[](matchDetails.totalItems - 1);
- uint256 currentFulfillment = 0;
-
- // The outer loop processes each matchable group.
- for (uint256 i = 0; i < matchDetails.items.length; ++i) {
- // This is actually a "while" loop, but bound it as a sanity check.
- bool allProcessed = false;
- for (uint256 j = 0; j < matchDetails.totalItems; ++j) {
- Fulfillment memory fulfillment = consumeItems(
- matchDetails.items[i],
- consumeMethod,
- seed
- );
-
- // Exit the inner loop if no fulfillment was located.
- if (fulfillment.offerComponents.length == 0) {
- allProcessed = true;
- break;
- }
-
- // append the located fulfillment and continue searching.
- fulfillments[currentFulfillment++] = fulfillment;
- }
- if (!allProcessed) {
- revert("FulfillmentGeneratorLib: did not complete processing");
- }
- }
-
- // Resize the fulfillments array based on number of elements assigned.
- assembly {
- mstore(fulfillments, currentFulfillment)
- }
- }
-
- // NOTE: this does not currently minimize the number of fulfillments.
- function consumeItems(
- DualFulfillmentItems memory matchItems,
- function(FulfillmentItems memory, FulfillmentItems memory, uint256)
- internal
- pure
- returns (Fulfillment memory) consumeMethod,
- uint256 seed
- ) internal pure returns (Fulfillment memory) {
- // Search for something that can be offered.
- for (uint256 i = 0; i < matchItems.offer.length; ++i) {
- FulfillmentItems memory offerItems = matchItems.offer[i];
- if (offerItems.totalAmount != 0) {
- // Search for something it can be matched against.
- for (uint256 j = 0; j < matchItems.consideration.length; ++j) {
- FulfillmentItems memory considerationItems = (
- matchItems.consideration[j]
- );
-
- if (considerationItems.totalAmount != 0) {
- return
- consumeMethod(offerItems, considerationItems, seed);
- }
- }
- }
- }
-
- // If none were found, return an empty fulfillment.
- return emptyFulfillment();
- }
-
- function consumeMinimumItemsAndGetFulfillment(
- FulfillmentItems memory offerItems,
- FulfillmentItems memory considerationItems,
- uint256 /* seed */
- ) internal pure returns (Fulfillment memory) {
- if (
- offerItems.totalAmount == 0 || considerationItems.totalAmount == 0
- ) {
- revert("FulfillmentGeneratorLib: missing item amounts to consume");
- }
-
- // Allocate fulfillment component arrays with a single element.
- FulfillmentComponent[] memory offerComponents = (
- new FulfillmentComponent[](1)
- );
- FulfillmentComponent[] memory considerationComponents = (
- new FulfillmentComponent[](1)
- );
-
- FulfillmentItem memory offerItem;
- for (uint256 i = 0; i < offerItems.items.length; ++i) {
- offerItem = offerItems.items[i];
-
- if (offerItem.amount != 0) {
- break;
- }
- }
-
- FulfillmentItem memory considerationItem;
- for (uint256 i = 0; i < considerationItems.items.length; ++i) {
- considerationItem = considerationItems.items[i];
-
- if (considerationItem.amount != 0) {
- break;
- }
- }
-
- offerComponents[0] = getFulfillmentComponent(offerItem);
- considerationComponents[0] = getFulfillmentComponent(considerationItem);
-
- if (offerItem.amount < considerationItem.amount) {
- offerItems.totalAmount -= offerItem.amount;
- considerationItems.totalAmount -= offerItem.amount;
- considerationItem.amount -= offerItem.amount;
- offerItem.amount = 0;
- } else {
- offerItems.totalAmount -= considerationItem.amount;
- considerationItems.totalAmount -= considerationItem.amount;
- offerItem.amount -= considerationItem.amount;
- considerationItem.amount = 0;
- }
-
- return
- Fulfillment({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents
- });
- }
-
- function consumeMaximumItemsAndGetFulfillment(
- FulfillmentItems memory offerItems,
- FulfillmentItems memory considerationItems,
- uint256 /* seed */
- ) internal pure returns (Fulfillment memory) {
- if (
- offerItems.totalAmount == 0 || considerationItems.totalAmount == 0
- ) {
- revert("FulfillmentGeneratorLib: missing item amounts to consume");
- }
-
- // Allocate fulfillment component arrays using total items; reduce
- // length after based on the total number of elements assigned to each.
- FulfillmentComponent[] memory offerComponents = (
- new FulfillmentComponent[](offerItems.items.length)
- );
- FulfillmentComponent[] memory considerationComponents = (
- new FulfillmentComponent[](considerationItems.items.length)
- );
-
- uint256 assignmentIndex = 0;
-
- uint256 amountToConsume = offerItems.totalAmount >
- considerationItems.totalAmount
- ? considerationItems.totalAmount
- : offerItems.totalAmount;
-
- uint256 amountToCredit = amountToConsume;
-
- bool firstConsumedItemLocated = false;
- uint256 firstConsumedItemIndex;
-
- for (uint256 i = 0; i < offerItems.items.length; ++i) {
- FulfillmentItem memory item = offerItems.items[i];
- if (item.amount != 0) {
- if (!firstConsumedItemLocated) {
- firstConsumedItemLocated = true;
- firstConsumedItemIndex = i;
- }
-
- offerComponents[assignmentIndex++] = getFulfillmentComponent(
- item
- );
-
- if (item.amount >= amountToConsume) {
- uint256 amountToAddBack = item.amount - amountToConsume;
-
- item.amount = 0;
-
- offerItems.items[firstConsumedItemIndex].amount += (
- amountToAddBack
- );
-
- offerItems.totalAmount -= amountToConsume;
-
- amountToConsume = 0;
- break;
- } else {
- amountToConsume -= item.amount;
- offerItems.totalAmount -= item.amount;
-
- item.amount = 0;
- }
- }
- }
-
- // Sanity check
- if (amountToConsume != 0) {
- revert("FulfillmentGeneratorLib: did not consume expected amount");
- }
-
- // Reduce offerComponents length based on number of elements assigned.
- assembly {
- mstore(offerComponents, assignmentIndex)
- }
-
- firstConsumedItemLocated = false;
- assignmentIndex = 0;
-
- for (uint256 i = 0; i < considerationItems.items.length; ++i) {
- FulfillmentItem memory item = considerationItems.items[i];
- if (item.amount != 0) {
- if (!firstConsumedItemLocated) {
- firstConsumedItemLocated = true;
- firstConsumedItemIndex = i;
- }
-
- considerationComponents[assignmentIndex++] = (
- getFulfillmentComponent(item)
- );
-
- if (item.amount >= amountToCredit) {
- uint256 amountToAddBack = item.amount - amountToCredit;
-
- item.amount = 0;
-
- considerationItems.items[firstConsumedItemIndex].amount += (
- amountToAddBack
- );
-
- considerationItems.totalAmount -= amountToCredit;
-
- amountToCredit = 0;
- break;
- } else {
- amountToCredit -= item.amount;
- considerationItems.totalAmount -= item.amount;
-
- item.amount = 0;
- }
- }
- }
-
- // Sanity check
- if (amountToCredit != 0) {
- revert("FulfillmentGeneratorLib: did not credit expected amount");
- }
-
- // Reduce considerationComponents length based on # elements assigned.
- assembly {
- mstore(considerationComponents, assignmentIndex)
- }
-
- // Sanity check
- if (
- offerComponents.length == 0 || considerationComponents.length == 0
- ) {
- revert("FulfillmentGeneratorLib: empty match component generated");
- }
-
- return
- Fulfillment({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents
- });
- }
-
- function consumeRandomItemsAndGetFulfillment(
- FulfillmentItems memory offerItems,
- FulfillmentItems memory considerationItems,
- uint256 seed
- ) internal pure returns (Fulfillment memory) {
- if (
- offerItems.totalAmount == 0 || considerationItems.totalAmount == 0
- ) {
- revert("FulfillmentGeneratorLib: missing item amounts to consume");
- }
-
- // Allocate fulfillment component arrays using total items; reduce
- // length after based on the total number of elements assigned to each.
- FulfillmentComponent[] memory offerComponents = (
- new FulfillmentComponent[](offerItems.items.length)
- );
-
- FulfillmentComponent[] memory considerationComponents = (
- new FulfillmentComponent[](considerationItems.items.length)
- );
-
- uint256[] memory consumableOfferIndices = new uint256[](
- offerItems.items.length
- );
- uint256[] memory consumableConsiderationIndices = new uint256[](
- considerationItems.items.length
- );
-
- {
- uint256 assignmentIndex = 0;
-
- for (uint256 i = 0; i < offerItems.items.length; ++i) {
- FulfillmentItem memory item = offerItems.items[i];
- if (item.amount != 0) {
- consumableOfferIndices[assignmentIndex++] = i;
- }
- }
-
- assembly {
- mstore(consumableOfferIndices, assignmentIndex)
- }
-
- assignmentIndex = 0;
-
- for (uint256 i = 0; i < considerationItems.items.length; ++i) {
- FulfillmentItem memory item = considerationItems.items[i];
- if (item.amount != 0) {
- consumableConsiderationIndices[assignmentIndex++] = i;
- }
- }
-
- assembly {
- mstore(consumableConsiderationIndices, assignmentIndex)
- }
-
- // Sanity check
- if (
- consumableOfferIndices.length == 0 ||
- consumableConsiderationIndices.length == 0
- ) {
- revert(
- "FulfillmentGeneratorLib: did not find consumable items"
- );
- }
-
- LibPRNG.PRNG memory prng;
- prng.seed(seed ^ 0xdd);
-
- prng.shuffle(consumableOfferIndices);
- prng.shuffle(consumableConsiderationIndices);
-
- assignmentIndex = prng.uniform(consumableOfferIndices.length) + 1;
- assembly {
- mstore(offerComponents, assignmentIndex)
- mstore(consumableOfferIndices, assignmentIndex)
- }
-
- assignmentIndex =
- prng.uniform(consumableConsiderationIndices.length) +
- 1;
- assembly {
- mstore(considerationComponents, assignmentIndex)
- mstore(consumableConsiderationIndices, assignmentIndex)
- }
- }
-
- uint256 totalOfferAmount = 0;
- uint256 totalConsiderationAmount = 0;
-
- for (uint256 i = 0; i < consumableOfferIndices.length; ++i) {
- FulfillmentItem memory item = offerItems.items[
- consumableOfferIndices[i]
- ];
-
- offerComponents[i] = getFulfillmentComponent(item);
-
- totalOfferAmount += item.amount;
- item.amount = 0;
- }
-
- for (uint256 i = 0; i < consumableConsiderationIndices.length; ++i) {
- FulfillmentItem memory item = considerationItems.items[
- consumableConsiderationIndices[i]
- ];
-
- considerationComponents[i] = getFulfillmentComponent(item);
-
- totalConsiderationAmount += item.amount;
- item.amount = 0;
- }
-
- if (totalOfferAmount > totalConsiderationAmount) {
- uint256 remainingAmount = (totalOfferAmount -
- totalConsiderationAmount);
-
- // add back excess to first offer item
- offerItems.items[consumableOfferIndices[0]].amount += (
- remainingAmount
- );
-
- offerItems.totalAmount -= totalConsiderationAmount;
- considerationItems.totalAmount -= totalConsiderationAmount;
- } else {
- uint256 remainingAmount = (totalConsiderationAmount -
- totalOfferAmount);
-
- // add back excess to first consideration item
- considerationItems
- .items[consumableConsiderationIndices[0]]
- .amount += remainingAmount;
-
- offerItems.totalAmount -= totalOfferAmount;
- considerationItems.totalAmount -= totalOfferAmount;
- }
-
- return
- Fulfillment({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents
- });
- }
-
- function emptyFulfillment() internal pure returns (Fulfillment memory) {
- FulfillmentComponent[] memory components;
- return
- Fulfillment({
- offerComponents: components,
- considerationComponents: components
- });
- }
-
- function getFulfillAvailableFulfillments(
- FulfillAvailableDetails memory fulfillAvailableDetails,
- FulfillmentStrategy memory strategy,
- uint256 seed
- )
- internal
- pure
- returns (
- FulfillmentComponent[][] memory offerFulfillments,
- FulfillmentComponent[][] memory considerationFulfillments
- )
- {
- ItemCategory[] memory offerCategories;
- (
- offerFulfillments,
- offerCategories,
- considerationFulfillments,
-
- ) = getFulfillmentComponentsUsingMethod(
- fulfillAvailableDetails,
- getFulfillmentMethod(strategy.aggregationStrategy),
- seed
- );
-
- FulfillAvailableStrategy dropStrategy = (
- strategy.fulfillAvailableStrategy
- );
-
- if (dropStrategy == FulfillAvailableStrategy.KEEP_ALL) {
- return (offerFulfillments, considerationFulfillments);
- }
-
- if (dropStrategy == FulfillAvailableStrategy.DROP_SINGLE_OFFER) {
- return (
- dropSingle(offerFulfillments, offerCategories),
- considerationFulfillments
- );
- }
-
- if (dropStrategy == FulfillAvailableStrategy.DROP_ALL_OFFER) {
- return (
- dropAllNon721(offerFulfillments, offerCategories),
- considerationFulfillments
- );
- }
-
- if (dropStrategy == FulfillAvailableStrategy.DROP_RANDOM_OFFER) {
- return (
- dropRandom(offerFulfillments, offerCategories, seed),
- considerationFulfillments
- );
- }
-
- if (
- dropStrategy == FulfillAvailableStrategy.DROP_SINGLE_KEEP_FILTERED
- ) {
- revert(
- "FulfillmentGeneratorLib: DROP_SINGLE_KEEP_FILTERED unsupported"
- );
- }
-
- if (dropStrategy == FulfillAvailableStrategy.DROP_ALL_KEEP_FILTERED) {
- revert(
- "FulfillmentGeneratorLib: DROP_ALL_KEEP_FILTERED unsupported"
- );
- }
-
- if (
- dropStrategy == FulfillAvailableStrategy.DROP_RANDOM_KEEP_FILTERED
- ) {
- revert(
- "FulfillmentGeneratorLib: DROP_RANDOM_KEEP_FILTERED unsupported"
- );
- }
-
- revert("FulfillmentGeneratorLib: unknown fulfillAvailable strategy");
- }
-
- function dropSingle(
- FulfillmentComponent[][] memory offerFulfillments,
- ItemCategory[] memory offerCategories
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory fulfillments = (
- new FulfillmentComponent[][](offerFulfillments.length)
- );
-
- uint256 assignmentIndex = 0;
-
- for (uint256 i = 0; i < offerFulfillments.length; ++i) {
- FulfillmentComponent[] memory components = offerFulfillments[i];
- if (
- offerCategories[i] == ItemCategory.ERC721 ||
- components.length > 1
- ) {
- fulfillments[assignmentIndex++] = components;
- }
- }
-
- assembly {
- mstore(fulfillments, assignmentIndex)
- }
-
- return fulfillments;
- }
-
- function dropAllNon721(
- FulfillmentComponent[][] memory offerFulfillments,
- ItemCategory[] memory offerCategories
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory fulfillments = (
- new FulfillmentComponent[][](offerFulfillments.length)
- );
-
- uint256 assignmentIndex = 0;
-
- for (uint256 i = 0; i < offerFulfillments.length; ++i) {
- FulfillmentComponent[] memory components = offerFulfillments[i];
- if (offerCategories[i] == ItemCategory.ERC721) {
- fulfillments[assignmentIndex++] = components;
- }
- }
-
- assembly {
- mstore(fulfillments, assignmentIndex)
- }
-
- return fulfillments;
- }
-
- function dropRandom(
- FulfillmentComponent[][] memory offerFulfillments,
- ItemCategory[] memory offerCategories,
- uint256 seed
- ) internal pure returns (FulfillmentComponent[][] memory) {
- LibPRNG.PRNG memory prng;
- prng.seed(seed ^ 0xbb);
-
- FulfillmentComponent[][] memory fulfillments = (
- new FulfillmentComponent[][](offerFulfillments.length)
- );
-
- uint256 assignmentIndex = 0;
-
- for (uint256 i = 0; i < offerFulfillments.length; ++i) {
- FulfillmentComponent[] memory components = offerFulfillments[i];
- if (
- offerCategories[i] == ItemCategory.ERC721 ||
- prng.uniform(2) == 0
- ) {
- fulfillments[assignmentIndex++] = components;
- }
- }
-
- assembly {
- mstore(fulfillments, assignmentIndex)
- }
-
- return fulfillments;
- }
-
- function getFulfillmentMethod(
- AggregationStrategy aggregationStrategy
- )
- internal
- pure
- returns (
- function(FulfillmentItems[] memory, uint256)
- internal
- pure
- returns (FulfillmentComponent[][] memory, ItemCategory[] memory)
- )
- {
- if (aggregationStrategy == AggregationStrategy.MAXIMUM) {
- return getMaxFulfillmentComponents;
- } else if (aggregationStrategy == AggregationStrategy.MINIMUM) {
- return getMinFulfillmentComponents;
- } else if (aggregationStrategy == AggregationStrategy.RANDOM) {
- return getRandomFulfillmentComponents;
- } else {
- revert("FulfillmentGeneratorLib: unknown aggregation strategy");
- }
- }
-
- function getFulfillmentComponentsUsingMethod(
- FulfillAvailableDetails memory fulfillAvailableDetails,
- function(FulfillmentItems[] memory, uint256)
- internal
- pure
- returns (
- FulfillmentComponent[][] memory,
- ItemCategory[] memory
- ) fulfillmentMethod,
- uint256 seed
- )
- internal
- pure
- returns (
- FulfillmentComponent[][] memory offerFulfillments,
- ItemCategory[] memory offerCategories,
- FulfillmentComponent[][] memory considerationFulfillments,
- ItemCategory[] memory considerationCategories
- )
- {
- (offerFulfillments, offerCategories) = fulfillmentMethod(
- fulfillAvailableDetails.items.offer,
- seed
- );
-
- (
- considerationFulfillments,
- considerationCategories
- ) = fulfillmentMethod(
- fulfillAvailableDetails.items.consideration,
- seed
- );
- }
-
- function getMaxFulfillmentComponents(
- FulfillmentItems[] memory fulfillmentItems,
- uint256 /* seed */
- )
- internal
- pure
- returns (FulfillmentComponent[][] memory, ItemCategory[] memory)
- {
- FulfillmentComponent[][] memory fulfillments = (
- new FulfillmentComponent[][](fulfillmentItems.length)
- );
-
- ItemCategory[] memory categories = new ItemCategory[](
- fulfillmentItems.length
- );
-
- for (uint256 i = 0; i < fulfillmentItems.length; ++i) {
- fulfillments[i] = getFulfillmentComponents(
- fulfillmentItems[i].items
- );
- categories[i] = fulfillmentItems[i].itemCategory;
- }
-
- return (fulfillments, categories);
- }
-
- function getRandomFulfillmentComponents(
- FulfillmentItems[] memory fulfillmentItems,
- uint256 seed
- )
- internal
- pure
- returns (FulfillmentComponent[][] memory, ItemCategory[] memory)
- {
- uint256 fulfillmentCount = 0;
-
- for (uint256 i = 0; i < fulfillmentItems.length; ++i) {
- fulfillmentCount += fulfillmentItems[i].items.length;
- }
-
- FulfillmentComponent[][] memory fulfillments = (
- new FulfillmentComponent[][](fulfillmentCount)
- );
-
- ItemCategory[] memory categories = new ItemCategory[](fulfillmentCount);
-
- LibPRNG.PRNG memory prng;
- prng.seed(seed ^ 0xcc);
-
- fulfillmentCount = 0;
- for (uint256 i = 0; i < fulfillmentItems.length; ++i) {
- FulfillmentItem[] memory items = fulfillmentItems[i].items;
-
- for (uint256 j = 0; j < items.length; ++j) {
- FulfillmentComponent[] memory fulfillment = (
- consumeRandomFulfillmentItems(items, prng)
- );
-
- if (fulfillment.length == 0) {
- break;
- }
-
- categories[fulfillmentCount] = fulfillmentItems[i].itemCategory;
- fulfillments[fulfillmentCount++] = fulfillment;
- }
- }
-
- assembly {
- mstore(fulfillments, fulfillmentCount)
- mstore(categories, fulfillmentCount)
- }
-
- uint256[] memory componentIndices = new uint256[](fulfillments.length);
- for (uint256 i = 0; i < fulfillments.length; ++i) {
- componentIndices[i] = i;
- }
-
- prng.shuffle(componentIndices);
-
- FulfillmentComponent[][] memory shuffledFulfillments = (
- new FulfillmentComponent[][](fulfillments.length)
- );
-
- ItemCategory[] memory shuffledCategories = (
- new ItemCategory[](fulfillments.length)
- );
-
- for (uint256 i = 0; i < fulfillments.length; ++i) {
- uint256 priorIndex = componentIndices[i];
- shuffledFulfillments[i] = fulfillments[priorIndex];
- shuffledCategories[i] = categories[priorIndex];
- }
-
- return (shuffledFulfillments, shuffledCategories);
- }
-
- function consumeRandomFulfillmentItems(
- FulfillmentItem[] memory items,
- LibPRNG.PRNG memory prng
- ) internal pure returns (FulfillmentComponent[] memory) {
- uint256[] memory consumableItemIndices = new uint256[](items.length);
- uint256 assignmentIndex = 0;
- for (uint256 i = 0; i < items.length; ++i) {
- if (items[i].amount != 0) {
- consumableItemIndices[assignmentIndex++] = i;
- }
- }
-
- if (assignmentIndex == 0) {
- return new FulfillmentComponent[](0);
- }
-
- assembly {
- mstore(consumableItemIndices, assignmentIndex)
- }
-
- prng.shuffle(consumableItemIndices);
-
- assignmentIndex = prng.uniform(assignmentIndex) + 1;
-
- assembly {
- mstore(consumableItemIndices, assignmentIndex)
- }
-
- FulfillmentComponent[] memory fulfillment = new FulfillmentComponent[](
- consumableItemIndices.length
- );
-
- for (uint256 i = 0; i < consumableItemIndices.length; ++i) {
- FulfillmentItem memory item = items[consumableItemIndices[i]];
-
- fulfillment[i] = getFulfillmentComponent(item);
-
- item.amount = 0;
- }
-
- return fulfillment;
- }
-
- function getMinFulfillmentComponents(
- FulfillmentItems[] memory fulfillmentItems,
- uint256 /* seed */
- )
- internal
- pure
- returns (FulfillmentComponent[][] memory, ItemCategory[] memory)
- {
- uint256 fulfillmentCount = 0;
-
- for (uint256 i = 0; i < fulfillmentItems.length; ++i) {
- fulfillmentCount += fulfillmentItems[i].items.length;
- }
-
- FulfillmentComponent[][] memory fulfillments = (
- new FulfillmentComponent[][](fulfillmentCount)
- );
-
- ItemCategory[] memory categories = (
- new ItemCategory[](fulfillmentCount)
- );
-
- fulfillmentCount = 0;
- for (uint256 i = 0; i < fulfillmentItems.length; ++i) {
- FulfillmentItem[] memory items = fulfillmentItems[i].items;
-
- for (uint256 j = 0; j < items.length; ++j) {
- FulfillmentComponent[] memory fulfillment = (
- new FulfillmentComponent[](1)
- );
- fulfillment[0] = getFulfillmentComponent(items[j]);
- categories[fulfillmentCount] = fulfillmentItems[i].itemCategory;
- fulfillments[fulfillmentCount++] = fulfillment;
- }
- }
-
- return (fulfillments, categories);
- }
-
- function getFulfillmentComponents(
- FulfillmentItem[] memory items
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory fulfillment = new FulfillmentComponent[](
- items.length
- );
-
- for (uint256 i = 0; i < items.length; ++i) {
- fulfillment[i] = getFulfillmentComponent(items[i]);
- }
-
- return fulfillment;
- }
-
- function getFulfillmentComponent(
- FulfillmentItem memory item
- ) internal pure returns (FulfillmentComponent memory) {
- return
- FulfillmentComponent({
- orderIndex: item.orderIndex,
- itemIndex: item.itemIndex
- });
- }
-
- function determineFulfillAvailableEligibility(
- FulfillAvailableDetails memory fulfillAvailableDetails
- ) internal pure returns (bool) {
- bool atLeastOneExecution = false;
-
- FulfillmentItems[] memory offer = fulfillAvailableDetails.items.offer;
- for (uint256 i = 0; i < offer.length; ++i) {
- FulfillmentItems memory fulfillmentItems = offer[i];
- if (
- fulfillmentItems.itemCategory == ItemCategory.NATIVE ||
- (fulfillmentItems.itemCategory == ItemCategory.ERC721 &&
- fulfillmentItems.totalAmount != 1)
- ) {
- return false;
- }
-
- // TODO: Ensure that the same ERC721 item doesn't appear on both the
- // offer side and the consideration side if the recipient does not
- // equal the caller.
-
- if (!atLeastOneExecution) {
- for (uint256 j = 0; j < fulfillmentItems.items.length; ++j) {
- FulfillmentItem memory item = fulfillmentItems.items[j];
- if (item.account != fulfillAvailableDetails.recipient) {
- atLeastOneExecution = true;
- break;
- }
- }
- }
- }
-
- FulfillmentItems[] memory consideration = (
- fulfillAvailableDetails.items.consideration
- );
- for (uint256 i = 0; i < consideration.length; ++i) {
- FulfillmentItems memory fulfillmentItems = consideration[i];
- if (
- fulfillmentItems.itemCategory == ItemCategory.ERC721 &&
- fulfillmentItems.totalAmount != 1
- ) {
- return false;
- }
-
- if (!atLeastOneExecution) {
- for (uint256 j = 0; j < fulfillmentItems.items.length; ++j) {
- FulfillmentItem memory item = fulfillmentItems.items[j];
- if (item.account != fulfillAvailableDetails.caller) {
- atLeastOneExecution = true;
- break;
- }
- }
- }
- }
-
- return true;
- }
-}
-
-library FulfillmentPrepLib {
- using ItemReferenceLib for OrderDetails[];
- using ItemReferenceGroupLib for ItemReferenceLib.ItemReference[];
- using ItemReferenceGroupLib for ItemReferenceGroupLib.ItemReferenceGroup[];
- using MatchableItemReferenceGroupLib for MatchableItemReferenceGroupLib.MatchableItemReferenceGroup[];
- using FulfillAvailableReferenceGroupLib for FulfillAvailableReferenceGroupLib.FulfillAvailableReferenceGroup;
-
- function getFulfillAvailableDetails(
- OrderDetails[] memory orderDetails,
- address recipient,
- address caller,
- uint256 seed
- ) internal pure returns (FulfillAvailableDetails memory) {
- return
- getFulfillAvailableDetailsFromReferences(
- orderDetails.getItemReferences(seed),
- recipient,
- caller
- );
- }
-
- function getDetails(
- ItemReferenceLib.ItemReference[] memory itemReferences,
- address recipient,
- address caller
- )
- internal
- pure
- returns (FulfillAvailableDetails memory, MatchDetails memory)
- {
- ItemReferenceGroupLib.ItemReferenceGroup[]
- memory groups = itemReferences.bundleByAggregatable();
-
- return (
- groups.splitBySide(recipient, caller).getFulfillAvailableDetails(),
- groups.bundleByMatchable(itemReferences).getMatchDetails(recipient)
- );
- }
-
- function getFulfillAvailableDetailsFromReferences(
- ItemReferenceLib.ItemReference[] memory itemReferences,
- address recipient,
- address caller
- ) internal pure returns (FulfillAvailableDetails memory) {
- return
- itemReferences
- .bundleByAggregatable()
- .splitBySide(recipient, caller)
- .getFulfillAvailableDetails();
- }
-
- function getMatchDetails(
- OrderDetails[] memory orderDetails,
- address recipient,
- uint256 seed
- ) internal pure returns (MatchDetails memory) {
- return
- getMatchDetailsFromReferences(
- orderDetails.getItemReferences(seed),
- recipient
- );
- }
-
- function getMatchDetailsFromReferences(
- ItemReferenceLib.ItemReference[] memory itemReferences,
- address recipient
- ) internal pure returns (MatchDetails memory) {
- return
- itemReferences
- .bundleByAggregatable()
- .bundleByMatchable(itemReferences)
- .getMatchDetails(recipient);
- }
-
- function getFulfillmentMatchContext(
- DualFulfillmentItems[] memory matchItems
- ) internal pure returns (DualFulfillmentMatchContext[] memory) {
- DualFulfillmentMatchContext[] memory context = (
- new DualFulfillmentMatchContext[](matchItems.length)
- );
-
- for (uint256 i = 0; i < matchItems.length; ++i) {
- bool itemCategorySet = false;
- ItemCategory itemCategory;
- uint256 totalOfferAmount = 0;
- uint256 totalConsiderationAmount = 0;
-
- FulfillmentItems[] memory offer = matchItems[i].offer;
- for (uint256 j = 0; j < offer.length; ++j) {
- FulfillmentItems memory items = offer[j];
-
- if (!itemCategorySet) {
- itemCategory = items.itemCategory;
- } else if (itemCategory != items.itemCategory) {
- revert("FulfillmentPrepLib: mismatched item categories");
- }
-
- totalOfferAmount += items.totalAmount;
- }
-
- FulfillmentItems[] memory consideration = (
- matchItems[i].consideration
- );
- for (uint256 j = 0; j < consideration.length; ++j) {
- FulfillmentItems memory items = consideration[j];
-
- if (!itemCategorySet) {
- itemCategory = items.itemCategory;
- } else if (itemCategory != items.itemCategory) {
- revert("FulfillmentPrepLib: mismatched item categories");
- }
-
- totalConsiderationAmount += items.totalAmount;
- }
-
- context[i] = DualFulfillmentMatchContext({
- itemCategory: itemCategory,
- totalOfferAmount: totalOfferAmount,
- totalConsiderationAmount: totalConsiderationAmount
- });
- }
-
- return context;
- }
-
- function getDualFulfillmentItems(
- ItemReferenceGroupLib.ItemReferenceGroup[] memory offerGroups,
- ItemReferenceGroupLib.ItemReferenceGroup[] memory considerationGroups
- ) internal pure returns (DualFulfillmentItems memory, uint256 totalItems) {
- DualFulfillmentItems memory items = DualFulfillmentItems({
- offer: new FulfillmentItems[](offerGroups.length),
- consideration: new FulfillmentItems[](considerationGroups.length)
- });
-
- uint256 currentItems;
-
- for (uint256 i = 0; i < offerGroups.length; ++i) {
- (items.offer[i], currentItems) = getFulfillmentItems(
- offerGroups[i].references
- );
-
- totalItems += currentItems;
- }
-
- for (uint256 i = 0; i < considerationGroups.length; ++i) {
- (items.consideration[i], currentItems) = getFulfillmentItems(
- considerationGroups[i].references
- );
-
- totalItems += currentItems;
- }
-
- return (items, totalItems);
- }
-
- function getFulfillmentItems(
- ItemReferenceLib.ItemReference[] memory itemReferences
- ) internal pure returns (FulfillmentItems memory, uint256 totalItems) {
- // Sanity check: ensure there's at least one reference
- if (itemReferences.length == 0) {
- revert("FulfillmentPrepLib: empty item references supplied");
- }
-
- ItemReferenceLib.ItemReference memory firstReference = itemReferences[
- 0
- ];
- FulfillmentItems memory fulfillmentItems = FulfillmentItems({
- itemCategory: firstReference.itemCategory,
- totalAmount: 0,
- items: new FulfillmentItem[](itemReferences.length)
- });
-
- for (uint256 i = 0; i < itemReferences.length; ++i) {
- ItemReferenceLib.ItemReference
- memory itemReference = itemReferences[i];
- uint256 amount = itemReference.amount;
- fulfillmentItems.totalAmount += amount;
- fulfillmentItems.items[i] = FulfillmentItem({
- orderIndex: itemReference.orderIndex,
- itemIndex: itemReference.itemIndex,
- amount: amount,
- account: itemReference.account
- });
- }
-
- totalItems = itemReferences.length;
-
- return (fulfillmentItems, totalItems);
- }
-}
-
-library FulfillAvailableReferenceGroupLib {
- struct FulfillAvailableReferenceGroup {
- ItemReferenceGroupLib.ItemReferenceGroup[] offerGroups;
- ItemReferenceGroupLib.ItemReferenceGroup[] considerationGroups;
- address recipient;
- address caller;
- }
-
- function getFulfillAvailableDetails(
- FulfillAvailableReferenceGroup memory group
- ) internal pure returns (FulfillAvailableDetails memory) {
- (
- DualFulfillmentItems memory items,
- uint256 totalItems
- ) = FulfillmentPrepLib.getDualFulfillmentItems(
- group.offerGroups,
- group.considerationGroups
- );
-
- return
- FulfillAvailableDetails({
- items: items,
- caller: group.caller,
- recipient: group.recipient,
- totalItems: totalItems
- });
- }
-}
-
-library MatchableItemReferenceGroupLib {
- struct MatchableItemReferenceGroup {
- bytes32 dataHash;
- ItemReferenceGroupLib.ItemReferenceGroup[] offerGroups;
- ItemReferenceGroupLib.ItemReferenceGroup[] considerationGroups;
- uint256 offerAssigned;
- uint256 considerationAssigned;
- }
-
- function getMatchDetails(
- MatchableItemReferenceGroup[] memory matchableGroups,
- address recipient
- ) internal pure returns (MatchDetails memory) {
- DualFulfillmentItems[] memory items = new DualFulfillmentItems[](
- matchableGroups.length
- );
-
- uint256 totalItems = 0;
- uint256 itemsInGroup = 0;
-
- for (uint256 i = 0; i < matchableGroups.length; ++i) {
- MatchableItemReferenceGroup memory matchableGroup = (
- matchableGroups[i]
- );
-
- (items[i], itemsInGroup) = FulfillmentPrepLib
- .getDualFulfillmentItems(
- matchableGroup.offerGroups,
- matchableGroup.considerationGroups
- );
-
- totalItems += itemsInGroup;
- }
-
- return
- MatchDetails({
- items: items,
- context: FulfillmentPrepLib.getFulfillmentMatchContext(items),
- recipient: recipient,
- totalItems: totalItems
- });
- }
-}
-
-library ItemReferenceGroupLib {
- using HashCountLib for ItemReferenceLib.ItemReference[];
- using HashAllocatorLib for HashCountLib.HashCount[];
-
- struct ItemReferenceGroup {
- bytes32 fullHash;
- ItemReferenceLib.ItemReference[] references;
- uint256 assigned;
- }
-
- function bundleByAggregatable(
- ItemReferenceLib.ItemReference[] memory itemReferences
- ) internal pure returns (ItemReferenceGroup[] memory) {
- ItemReferenceGroup[] memory groups = itemReferences
- .getUniqueFullHashes()
- .allocateItemReferenceGroup();
-
- for (uint256 i = 0; i < itemReferences.length; ++i) {
- ItemReferenceLib.ItemReference
- memory itemReference = itemReferences[i];
- for (uint256 j = 0; j < groups.length; ++j) {
- ItemReferenceGroup memory group = groups[j];
- if (group.fullHash == itemReference.fullHash) {
- group.references[group.assigned++] = itemReference;
- break;
- }
- }
- }
-
- // Sanity check: ensure at least one reference item on each group
- for (uint256 i = 0; i < groups.length; ++i) {
- if (groups[i].references.length == 0) {
- revert(
- "ItemReferenceGroupLib: missing item reference in group"
- );
- }
- }
-
- return groups;
- }
-
- function splitBySide(
- ItemReferenceGroup[] memory groups,
- address recipient,
- address caller
- )
- internal
- pure
- returns (
- FulfillAvailableReferenceGroupLib.FulfillAvailableReferenceGroup
- memory
- )
- {
- // NOTE: lengths are overallocated; reduce after assignment.
- ItemReferenceGroup[] memory offerGroups = (
- new ItemReferenceGroup[](groups.length)
- );
- ItemReferenceGroup[] memory considerationGroups = (
- new ItemReferenceGroup[](groups.length)
- );
- uint256 offerItems = 0;
- uint256 considerationItems = 0;
-
- for (uint256 i = 0; i < groups.length; ++i) {
- ItemReferenceGroup memory group = groups[i];
-
- if (group.references.length == 0) {
- revert("ItemReferenceGroupLib: no items in group");
- }
-
- Side side = group.references[0].side;
-
- if (side == Side.OFFER) {
- offerGroups[offerItems++] = group;
- } else if (side == Side.CONSIDERATION) {
- considerationGroups[considerationItems++] = group;
- } else {
- revert("ItemReferenceGroupLib: invalid side located (split)");
- }
- }
-
- // Reduce group lengths based on number of elements assigned.
- assembly {
- mstore(offerGroups, offerItems)
- mstore(considerationGroups, considerationItems)
- }
-
- return
- FulfillAvailableReferenceGroupLib.FulfillAvailableReferenceGroup({
- offerGroups: offerGroups,
- considerationGroups: considerationGroups,
- recipient: recipient,
- caller: caller
- });
- }
-
- function bundleByMatchable(
- ItemReferenceGroup[] memory groups,
- ItemReferenceLib.ItemReference[] memory itemReferences
- )
- internal
- pure
- returns (
- MatchableItemReferenceGroupLib.MatchableItemReferenceGroup[] memory
- )
- {
- MatchableItemReferenceGroupLib.MatchableItemReferenceGroup[]
- memory matchableGroups = (
- itemReferences
- .getUniqueDataHashes()
- .allocateMatchableItemReferenceGroup()
- );
-
- for (uint256 i = 0; i < groups.length; ++i) {
- ItemReferenceGroup memory group = groups[i];
-
- if (group.references.length == 0) {
- revert(
- "ItemReferenceGroupLib: empty item reference group supplied"
- );
- }
-
- ItemReferenceLib.ItemReference memory firstReference = group
- .references[0];
- for (uint256 j = 0; j < matchableGroups.length; ++j) {
- MatchableItemReferenceGroupLib.MatchableItemReferenceGroup
- memory matchableGroup = (matchableGroups[j]);
-
- if (matchableGroup.dataHash == firstReference.dataHash) {
- if (firstReference.side == Side.OFFER) {
- matchableGroup.offerGroups[
- matchableGroup.offerAssigned++
- ] = group;
- } else if (firstReference.side == Side.CONSIDERATION) {
- matchableGroup.considerationGroups[
- matchableGroup.considerationAssigned++
- ] = group;
- } else {
- revert(
- "ItemReferenceGroupLib: invalid match side located"
- );
- }
-
- break;
- }
- }
- }
-
- // Reduce reference group array lengths based on assigned elements.
- for (uint256 i = 0; i < matchableGroups.length; ++i) {
- MatchableItemReferenceGroupLib.MatchableItemReferenceGroup
- memory group = matchableGroups[i];
- uint256 offerAssigned = group.offerAssigned;
- uint256 considerationAssigned = group.considerationAssigned;
- ItemReferenceGroup[] memory offerGroups = (group.offerGroups);
- ItemReferenceGroup[] memory considerationGroups = (
- group.considerationGroups
- );
-
- assembly {
- mstore(offerGroups, offerAssigned)
- mstore(considerationGroups, considerationAssigned)
- }
- }
-
- return matchableGroups;
- }
-}
-
-library HashAllocatorLib {
- function allocateItemReferenceGroup(
- HashCountLib.HashCount[] memory hashCount
- )
- internal
- pure
- returns (ItemReferenceGroupLib.ItemReferenceGroup[] memory)
- {
- ItemReferenceGroupLib.ItemReferenceGroup[]
- memory group = new ItemReferenceGroupLib.ItemReferenceGroup[](
- hashCount.length
- );
-
- for (uint256 i = 0; i < hashCount.length; ++i) {
- group[i] = ItemReferenceGroupLib.ItemReferenceGroup({
- fullHash: hashCount[i].hash,
- references: new ItemReferenceLib.ItemReference[](
- hashCount[i].count
- ),
- assigned: 0
- });
- }
-
- return group;
- }
-
- function allocateMatchableItemReferenceGroup(
- HashCountLib.HashCount[] memory hashCount
- )
- internal
- pure
- returns (
- MatchableItemReferenceGroupLib.MatchableItemReferenceGroup[] memory
- )
- {
- MatchableItemReferenceGroupLib.MatchableItemReferenceGroup[]
- memory group = (
- new MatchableItemReferenceGroupLib.MatchableItemReferenceGroup[](
- hashCount.length
- )
- );
-
- for (uint256 i = 0; i < hashCount.length; ++i) {
- // NOTE: reference group lengths are overallocated and will need to
- // be reduced once their respective elements have been assigned.
- uint256 count = hashCount[i].count;
- group[i] = MatchableItemReferenceGroupLib
- .MatchableItemReferenceGroup({
- dataHash: hashCount[i].hash,
- offerGroups: new ItemReferenceGroupLib.ItemReferenceGroup[](
- count
- ),
- considerationGroups: (
- new ItemReferenceGroupLib.ItemReferenceGroup[](count)
- ),
- offerAssigned: 0,
- considerationAssigned: 0
- });
- }
-
- return group;
- }
-}
-
-library HashCountLib {
- using LibPRNG for LibPRNG.PRNG;
- using LibSort for uint256[];
- using ItemReferenceLib for OrderDetails[];
- using ItemReferenceLib for ItemReferenceLib.ItemReference[];
-
- struct HashCount {
- bytes32 hash;
- uint256 count;
- }
-
- function getUniqueFullHashes(
- ItemReferenceLib.ItemReference[] memory itemReferences
- ) internal pure returns (HashCount[] memory) {
- uint256[] memory fullHashes = new uint256[](itemReferences.length);
-
- for (uint256 i = 0; i < itemReferences.length; ++i) {
- fullHashes[i] = uint256(itemReferences[i].fullHash);
- }
-
- return getHashCount(fullHashes);
- }
-
- function getUniqueDataHashes(
- ItemReferenceLib.ItemReference[] memory itemReferences
- ) internal pure returns (HashCount[] memory) {
- uint256[] memory dataHashes = new uint256[](itemReferences.length);
-
- for (uint256 i = 0; i < itemReferences.length; ++i) {
- dataHashes[i] = uint256(itemReferences[i].dataHash);
- }
-
- return getHashCount(dataHashes);
- }
-
- function getHashCount(
- uint256[] memory hashes
- ) internal pure returns (HashCount[] memory) {
- if (hashes.length == 0) {
- return new HashCount[](0);
- }
-
- hashes.sort();
-
- HashCount[] memory hashCount = new HashCount[](hashes.length);
- hashCount[0] = HashCount({ hash: bytes32(hashes[0]), count: 1 });
-
- uint256 hashCountPointer = 0;
- for (uint256 i = 1; i < hashes.length; ++i) {
- bytes32 element = bytes32(hashes[i]);
-
- if (element != hashCount[hashCountPointer].hash) {
- hashCount[++hashCountPointer] = HashCount({
- hash: element,
- count: 1
- });
- } else {
- ++hashCount[hashCountPointer].count;
- }
- }
-
- // update length of the hashCount array based on the hash count pointer.
- assembly {
- mstore(hashCount, add(hashCountPointer, 1))
- }
-
- return hashCount;
- }
-}
-
-library ItemReferenceLib {
- using LibPRNG for LibPRNG.PRNG;
- using LibSort for uint256[];
-
- struct ItemReference {
- uint256 orderIndex;
- uint256 itemIndex;
- Side side;
- bytes32 dataHash; // itemType ++ token ++ identifier
- bytes32 fullHash; // dataHash ++ [offerer ++ conduitKey || recipient]
- uint256 amount;
- ItemCategory itemCategory;
- address account;
- }
-
- function getItemReferences(
- OrderDetails[] memory orderDetails,
- uint256 seed
- ) internal pure returns (ItemReference[] memory) {
- ItemReference[] memory itemReferences = new ItemReference[](
- getTotalItems(orderDetails)
- );
-
- uint256 itemReferenceIndex = 0;
-
- for (
- uint256 orderIndex = 0;
- orderIndex < orderDetails.length;
- ++orderIndex
- ) {
- OrderDetails memory order = orderDetails[orderIndex];
- for (
- uint256 itemIndex = 0;
- itemIndex < order.offer.length;
- ++itemIndex
- ) {
- itemReferences[itemReferenceIndex++] = getItemReference(
- order.offer[itemIndex],
- orderIndex,
- itemIndex,
- order.offerer,
- order.conduitKey
- );
- }
- for (
- uint256 itemIndex = 0;
- itemIndex < order.consideration.length;
- ++itemIndex
- ) {
- itemReferences[itemReferenceIndex++] = getItemReference(
- order.consideration[itemIndex],
- orderIndex,
- itemIndex
- );
- }
- }
-
- if (seed == 0) {
- return itemReferences;
- }
-
- return shuffle(itemReferences, seed);
- }
-
- function shuffle(
- ItemReference[] memory itemReferences,
- uint256 seed
- ) internal pure returns (ItemReference[] memory) {
- ItemReference[] memory shuffledItemReferences = new ItemReference[](
- itemReferences.length
- );
-
- uint256[] memory indices = new uint256[](itemReferences.length);
- for (uint256 i = 0; i < indices.length; ++i) {
- indices[i] = i;
- }
-
- LibPRNG.PRNG memory prng;
- prng.seed(seed ^ 0xee);
- prng.shuffle(indices);
-
- for (uint256 i = 0; i < indices.length; ++i) {
- shuffledItemReferences[i] = itemReferences[indices[i]];
- }
-
- return shuffledItemReferences;
- }
-
- function getItemReference(
- SpentItem memory item,
- uint256 orderIndex,
- uint256 itemIndex,
- address offerer,
- bytes32 conduitKey
- ) internal pure returns (ItemReference memory) {
- return
- getItemReference(
- orderIndex,
- itemIndex,
- Side.OFFER,
- item.itemType,
- item.token,
- item.identifier,
- offerer,
- conduitKey,
- item.amount
- );
- }
-
- function getItemReference(
- ReceivedItem memory item,
- uint256 orderIndex,
- uint256 itemIndex
- ) internal pure returns (ItemReference memory) {
- return
- getItemReference(
- orderIndex,
- itemIndex,
- Side.CONSIDERATION,
- item.itemType,
- item.token,
- item.identifier,
- item.recipient,
- bytes32(0),
- item.amount
- );
- }
-
- function getItemReference(
- uint256 orderIndex,
- uint256 itemIndex,
- Side side,
- ItemType itemType,
- address token,
- uint256 identifier,
- address account,
- bytes32 conduitKey,
- uint256 amount
- ) internal pure returns (ItemReference memory) {
- bytes32 dataHash = keccak256(
- abi.encodePacked(itemType, token, identifier)
- );
-
- bytes32 fullHash;
- if (side == Side.OFFER) {
- fullHash = keccak256(
- abi.encodePacked(dataHash, account, conduitKey)
- );
- } else if (side == Side.CONSIDERATION) {
- fullHash = keccak256(abi.encodePacked(dataHash, account));
- } else {
- revert("ItemReferenceLib: invalid side located");
- }
-
- ItemCategory itemCategory;
- if (itemType == ItemType.NATIVE) {
- itemCategory = ItemCategory.NATIVE;
- } else if (itemType == ItemType.ERC721) {
- itemCategory = ItemCategory.ERC721;
- } else if (itemType == ItemType.ERC20 || itemType == ItemType.ERC1155) {
- itemCategory = ItemCategory.OTHER;
- } else {
- revert("ItemReferenceLib: invalid item type located");
- }
-
- return
- ItemReference({
- orderIndex: orderIndex,
- itemIndex: itemIndex,
- side: side,
- dataHash: dataHash,
- fullHash: fullHash,
- amount: amount,
- itemCategory: itemCategory,
- account: account
- });
- }
-
- function getTotalItems(
- OrderDetails[] memory orderDetails
- ) internal pure returns (uint256) {
- uint256 totalItems = 0;
-
- for (uint256 i = 0; i < orderDetails.length; ++i) {
- totalItems += getTotalItems(orderDetails[i]);
- }
-
- return totalItems;
- }
-
- function getTotalItems(
- OrderDetails memory order
- ) internal pure returns (uint256) {
- return (order.offer.length + order.consideration.length);
- }
-}
diff --git a/contracts/helpers/sol/fulfillments/lib/MatchArrays.sol b/contracts/helpers/sol/fulfillments/lib/MatchArrays.sol
deleted file mode 100644
index 52c3168e4..000000000
--- a/contracts/helpers/sol/fulfillments/lib/MatchArrays.sol
+++ /dev/null
@@ -1,3036 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-import "../../SeaportStructs.sol";
-import "../../lib/types/MatchComponentType.sol";
-
-library MatchArrays {
- function FulfillmentComponents(
- FulfillmentComponent memory a
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](1);
- arr[0] = a;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e,
- FulfillmentComponent memory f
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e,
- FulfillmentComponent memory f,
- FulfillmentComponent memory g
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function FulfillmentComponentsWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent memory a
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](
- maxLength
- );
- assembly {
- mstore(arr, 1)
- }
- arr[0] = a;
- return arr;
- }
-
- function FulfillmentComponentsWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent memory a,
- FulfillmentComponent memory b
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](
- maxLength
- );
- assembly {
- mstore(arr, 2)
- }
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function FulfillmentComponentsWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](
- maxLength
- );
- assembly {
- mstore(arr, 3)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function FulfillmentComponentsWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](
- maxLength
- );
- assembly {
- mstore(arr, 4)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function FulfillmentComponentsWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](
- maxLength
- );
- assembly {
- mstore(arr, 5)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function FulfillmentComponentsWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e,
- FulfillmentComponent memory f
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](
- maxLength
- );
- assembly {
- mstore(arr, 6)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function FulfillmentComponentsWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e,
- FulfillmentComponent memory f,
- FulfillmentComponent memory g
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](
- maxLength
- );
- assembly {
- mstore(arr, 7)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function extend(
- FulfillmentComponent[] memory arr1,
- FulfillmentComponent[] memory arr2
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- uint256 length1 = arr1.length;
- uint256 length2 = arr2.length;
- newArr = new FulfillmentComponent[](length1 + length2);
- for (uint256 i = 0; i < length1; ) {
- newArr[i] = arr1[i];
- unchecked {
- ++i;
- }
- }
- for (uint256 i = 0; i < arr2.length; ) {
- uint256 j;
- unchecked {
- j = i + length1;
- }
- newArr[j] = arr2[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function allocateFulfillmentComponents(
- uint256 length
- ) internal pure returns (FulfillmentComponent[] memory arr) {
- arr = new FulfillmentComponent[](length);
- assembly {
- mstore(arr, 0)
- }
- }
-
- function truncate(
- FulfillmentComponent[] memory arr,
- uint256 newLength
- ) internal pure returns (FulfillmentComponent[] memory _arr) {
- // truncate the array
- assembly {
- let oldLength := mload(arr)
- returndatacopy(
- returndatasize(),
- returndatasize(),
- gt(newLength, oldLength)
- )
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function truncateUnsafe(
- FulfillmentComponent[] memory arr,
- uint256 newLength
- ) internal pure returns (FulfillmentComponent[] memory _arr) {
- // truncate the array
- assembly {
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function append(
- FulfillmentComponent[] memory arr,
- FulfillmentComponent memory value
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- uint256 length = arr.length;
- newArr = new FulfillmentComponent[](length + 1);
- newArr[length] = value;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function appendUnsafe(
- FulfillmentComponent[] memory arr,
- FulfillmentComponent memory value
- ) internal pure returns (FulfillmentComponent[] memory modifiedArr) {
- uint256 length = arr.length;
- modifiedArr = arr;
- assembly {
- mstore(modifiedArr, add(length, 1))
- mstore(add(modifiedArr, shl(5, add(length, 1))), value)
- }
- }
-
- function copy(
- FulfillmentComponent[] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- uint256 length = arr.length;
- newArr = new FulfillmentComponent[](length);
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function copyAndResize(
- FulfillmentComponent[] memory arr,
- uint256 newLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](newLength);
- uint256 length = arr.length;
- // allow shrinking a copy without copying extra members
- length = (length > newLength) ? newLength : length;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- // TODO: consider writing 0-pointer to the rest of the array if longer for dynamic elements
- }
-
- function copyAndAllocate(
- FulfillmentComponent[] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- uint256 originalLength = arr.length;
- for (uint256 i = 0; i < originalLength; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, originalLength)
- }
- }
-
- function pop(
- FulfillmentComponent[] memory arr
- ) internal pure returns (FulfillmentComponent memory value) {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popUnsafe(
- FulfillmentComponent[] memory arr
- ) internal pure returns (FulfillmentComponent memory value) {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popLeft(
- FulfillmentComponent[] memory arr
- )
- internal
- pure
- returns (
- FulfillmentComponent[] memory newArr,
- FulfillmentComponent memory value
- )
- {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function popLeftUnsafe(
- FulfillmentComponent[] memory arr
- )
- internal
- pure
- returns (
- FulfillmentComponent[] memory newArr,
- FulfillmentComponent memory value
- )
- {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function fromFixed(
- FulfillmentComponent[1] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](1);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[1] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 1)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[2] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](2);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[2] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 2)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[3] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](3);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[3] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 3)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[4] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](4);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[4] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 4)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[5] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](5);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[5] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 5)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[6] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](6);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[6] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 6)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[7] memory arr
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](7);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[7] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[] memory newArr) {
- newArr = new FulfillmentComponent[](maxLength);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 7)
- }
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](1);
- arr[0] = a;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e,
- FulfillmentComponent[] memory f
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e,
- FulfillmentComponent[] memory f,
- FulfillmentComponent[] memory g
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function FulfillmentComponentArraysWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent[] memory a
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](
- maxLength
- );
- assembly {
- mstore(arr, 1)
- }
- arr[0] = a;
- return arr;
- }
-
- function FulfillmentComponentArraysWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](
- maxLength
- );
- assembly {
- mstore(arr, 2)
- }
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function FulfillmentComponentArraysWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](
- maxLength
- );
- assembly {
- mstore(arr, 3)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function FulfillmentComponentArraysWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](
- maxLength
- );
- assembly {
- mstore(arr, 4)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function FulfillmentComponentArraysWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](
- maxLength
- );
- assembly {
- mstore(arr, 5)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function FulfillmentComponentArraysWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e,
- FulfillmentComponent[] memory f
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](
- maxLength
- );
- assembly {
- mstore(arr, 6)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function FulfillmentComponentArraysWithMaxLength(
- uint256 maxLength,
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e,
- FulfillmentComponent[] memory f,
- FulfillmentComponent[] memory g
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](
- maxLength
- );
- assembly {
- mstore(arr, 7)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function extend(
- FulfillmentComponent[][] memory arr1,
- FulfillmentComponent[][] memory arr2
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- uint256 length1 = arr1.length;
- uint256 length2 = arr2.length;
- newArr = new FulfillmentComponent[][](length1 + length2);
- for (uint256 i = 0; i < length1; ) {
- newArr[i] = arr1[i];
- unchecked {
- ++i;
- }
- }
- for (uint256 i = 0; i < arr2.length; ) {
- uint256 j;
- unchecked {
- j = i + length1;
- }
- newArr[j] = arr2[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function allocateFulfillmentComponentArrays(
- uint256 length
- ) internal pure returns (FulfillmentComponent[][] memory arr) {
- arr = new FulfillmentComponent[][](length);
- assembly {
- mstore(arr, 0)
- }
- }
-
- function truncate(
- FulfillmentComponent[][] memory arr,
- uint256 newLength
- ) internal pure returns (FulfillmentComponent[][] memory _arr) {
- // truncate the array
- assembly {
- let oldLength := mload(arr)
- returndatacopy(
- returndatasize(),
- returndatasize(),
- gt(newLength, oldLength)
- )
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function truncateUnsafe(
- FulfillmentComponent[][] memory arr,
- uint256 newLength
- ) internal pure returns (FulfillmentComponent[][] memory _arr) {
- // truncate the array
- assembly {
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function append(
- FulfillmentComponent[][] memory arr,
- FulfillmentComponent[] memory value
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- uint256 length = arr.length;
- newArr = new FulfillmentComponent[][](length + 1);
- newArr[length] = value;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function appendUnsafe(
- FulfillmentComponent[][] memory arr,
- FulfillmentComponent[] memory value
- ) internal pure returns (FulfillmentComponent[][] memory modifiedArr) {
- uint256 length = arr.length;
- modifiedArr = arr;
- assembly {
- mstore(modifiedArr, add(length, 1))
- mstore(add(modifiedArr, shl(5, add(length, 1))), value)
- }
- }
-
- function copy(
- FulfillmentComponent[][] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- uint256 length = arr.length;
- newArr = new FulfillmentComponent[][](length);
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function copyAndResize(
- FulfillmentComponent[][] memory arr,
- uint256 newLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](newLength);
- uint256 length = arr.length;
- // allow shrinking a copy without copying extra members
- length = (length > newLength) ? newLength : length;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- // TODO: consider writing 0-pointer to the rest of the array if longer for dynamic elements
- }
-
- function copyAndAllocate(
- FulfillmentComponent[][] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- uint256 originalLength = arr.length;
- for (uint256 i = 0; i < originalLength; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, originalLength)
- }
- }
-
- function pop(
- FulfillmentComponent[][] memory arr
- ) internal pure returns (FulfillmentComponent[] memory value) {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popUnsafe(
- FulfillmentComponent[][] memory arr
- ) internal pure returns (FulfillmentComponent[] memory value) {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popLeft(
- FulfillmentComponent[][] memory arr
- )
- internal
- pure
- returns (
- FulfillmentComponent[][] memory newArr,
- FulfillmentComponent[] memory value
- )
- {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function popLeftUnsafe(
- FulfillmentComponent[][] memory arr
- )
- internal
- pure
- returns (
- FulfillmentComponent[][] memory newArr,
- FulfillmentComponent[] memory value
- )
- {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function fromFixed(
- FulfillmentComponent[][1] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](1);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[][1] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 1)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[][2] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](2);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[][2] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 2)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[][3] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](3);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[][3] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 3)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[][4] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](4);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[][4] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 4)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[][5] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](5);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[][5] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 5)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[][6] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](6);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[][6] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 6)
- }
- }
-
- function fromFixed(
- FulfillmentComponent[][7] memory arr
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](7);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- FulfillmentComponent[][7] memory arr,
- uint256 maxLength
- ) internal pure returns (FulfillmentComponent[][] memory newArr) {
- newArr = new FulfillmentComponent[][](maxLength);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 7)
- }
- }
-
- function Fulfillments(
- Fulfillment memory a
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](1);
- arr[0] = a;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e,
- Fulfillment memory f
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e,
- Fulfillment memory f,
- Fulfillment memory g
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function FulfillmentsWithMaxLength(
- uint256 maxLength,
- Fulfillment memory a
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](maxLength);
- assembly {
- mstore(arr, 1)
- }
- arr[0] = a;
- return arr;
- }
-
- function FulfillmentsWithMaxLength(
- uint256 maxLength,
- Fulfillment memory a,
- Fulfillment memory b
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](maxLength);
- assembly {
- mstore(arr, 2)
- }
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function FulfillmentsWithMaxLength(
- uint256 maxLength,
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](maxLength);
- assembly {
- mstore(arr, 3)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function FulfillmentsWithMaxLength(
- uint256 maxLength,
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](maxLength);
- assembly {
- mstore(arr, 4)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function FulfillmentsWithMaxLength(
- uint256 maxLength,
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](maxLength);
- assembly {
- mstore(arr, 5)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function FulfillmentsWithMaxLength(
- uint256 maxLength,
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e,
- Fulfillment memory f
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](maxLength);
- assembly {
- mstore(arr, 6)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function FulfillmentsWithMaxLength(
- uint256 maxLength,
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e,
- Fulfillment memory f,
- Fulfillment memory g
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](maxLength);
- assembly {
- mstore(arr, 7)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function extend(
- Fulfillment[] memory arr1,
- Fulfillment[] memory arr2
- ) internal pure returns (Fulfillment[] memory newArr) {
- uint256 length1 = arr1.length;
- uint256 length2 = arr2.length;
- newArr = new Fulfillment[](length1 + length2);
- for (uint256 i = 0; i < length1; ) {
- newArr[i] = arr1[i];
- unchecked {
- ++i;
- }
- }
- for (uint256 i = 0; i < arr2.length; ) {
- uint256 j;
- unchecked {
- j = i + length1;
- }
- newArr[j] = arr2[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function allocateFulfillments(
- uint256 length
- ) internal pure returns (Fulfillment[] memory arr) {
- arr = new Fulfillment[](length);
- assembly {
- mstore(arr, 0)
- }
- }
-
- function truncate(
- Fulfillment[] memory arr,
- uint256 newLength
- ) internal pure returns (Fulfillment[] memory _arr) {
- // truncate the array
- assembly {
- let oldLength := mload(arr)
- returndatacopy(
- returndatasize(),
- returndatasize(),
- gt(newLength, oldLength)
- )
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function truncateUnsafe(
- Fulfillment[] memory arr,
- uint256 newLength
- ) internal pure returns (Fulfillment[] memory _arr) {
- // truncate the array
- assembly {
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function append(
- Fulfillment[] memory arr,
- Fulfillment memory value
- ) internal pure returns (Fulfillment[] memory newArr) {
- uint256 length = arr.length;
- newArr = new Fulfillment[](length + 1);
- newArr[length] = value;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function appendUnsafe(
- Fulfillment[] memory arr,
- Fulfillment memory value
- ) internal pure returns (Fulfillment[] memory modifiedArr) {
- uint256 length = arr.length;
- modifiedArr = arr;
- assembly {
- mstore(modifiedArr, add(length, 1))
- mstore(add(modifiedArr, shl(5, add(length, 1))), value)
- }
- }
-
- function copy(
- Fulfillment[] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- uint256 length = arr.length;
- newArr = new Fulfillment[](length);
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function copyAndResize(
- Fulfillment[] memory arr,
- uint256 newLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](newLength);
- uint256 length = arr.length;
- // allow shrinking a copy without copying extra members
- length = (length > newLength) ? newLength : length;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- // TODO: consider writing 0-pointer to the rest of the array if longer for dynamic elements
- }
-
- function copyAndAllocate(
- Fulfillment[] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- uint256 originalLength = arr.length;
- for (uint256 i = 0; i < originalLength; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, originalLength)
- }
- }
-
- function pop(
- Fulfillment[] memory arr
- ) internal pure returns (Fulfillment memory value) {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popUnsafe(
- Fulfillment[] memory arr
- ) internal pure returns (Fulfillment memory value) {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popLeft(
- Fulfillment[] memory arr
- )
- internal
- pure
- returns (Fulfillment[] memory newArr, Fulfillment memory value)
- {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function popLeftUnsafe(
- Fulfillment[] memory arr
- )
- internal
- pure
- returns (Fulfillment[] memory newArr, Fulfillment memory value)
- {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function fromFixed(
- Fulfillment[1] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](1);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- Fulfillment[1] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 1)
- }
- }
-
- function fromFixed(
- Fulfillment[2] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](2);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- Fulfillment[2] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 2)
- }
- }
-
- function fromFixed(
- Fulfillment[3] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](3);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- Fulfillment[3] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 3)
- }
- }
-
- function fromFixed(
- Fulfillment[4] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](4);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- Fulfillment[4] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 4)
- }
- }
-
- function fromFixed(
- Fulfillment[5] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](5);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- Fulfillment[5] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 5)
- }
- }
-
- function fromFixed(
- Fulfillment[6] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](6);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- Fulfillment[6] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 6)
- }
- }
-
- function fromFixed(
- Fulfillment[7] memory arr
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](7);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- Fulfillment[7] memory arr,
- uint256 maxLength
- ) internal pure returns (Fulfillment[] memory newArr) {
- newArr = new Fulfillment[](maxLength);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 7)
- }
- }
-
- function MatchComponents(
- MatchComponent memory a
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](1);
- arr[0] = a;
- return arr;
- }
-
- function MatchComponents(
- MatchComponent memory a,
- MatchComponent memory b
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function MatchComponents(
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function MatchComponents(
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function MatchComponents(
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d,
- MatchComponent memory e
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function MatchComponents(
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d,
- MatchComponent memory e,
- MatchComponent memory f
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function MatchComponents(
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d,
- MatchComponent memory e,
- MatchComponent memory f,
- MatchComponent memory g
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function MatchComponentsWithMaxLength(
- uint256 maxLength,
- MatchComponent memory a
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](maxLength);
- assembly {
- mstore(arr, 1)
- }
- arr[0] = a;
- return arr;
- }
-
- function MatchComponentsWithMaxLength(
- uint256 maxLength,
- MatchComponent memory a,
- MatchComponent memory b
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](maxLength);
- assembly {
- mstore(arr, 2)
- }
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function MatchComponentsWithMaxLength(
- uint256 maxLength,
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](maxLength);
- assembly {
- mstore(arr, 3)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function MatchComponentsWithMaxLength(
- uint256 maxLength,
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](maxLength);
- assembly {
- mstore(arr, 4)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function MatchComponentsWithMaxLength(
- uint256 maxLength,
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d,
- MatchComponent memory e
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](maxLength);
- assembly {
- mstore(arr, 5)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function MatchComponentsWithMaxLength(
- uint256 maxLength,
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d,
- MatchComponent memory e,
- MatchComponent memory f
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](maxLength);
- assembly {
- mstore(arr, 6)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function MatchComponentsWithMaxLength(
- uint256 maxLength,
- MatchComponent memory a,
- MatchComponent memory b,
- MatchComponent memory c,
- MatchComponent memory d,
- MatchComponent memory e,
- MatchComponent memory f,
- MatchComponent memory g
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory arr = new MatchComponent[](maxLength);
- assembly {
- mstore(arr, 7)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function extend(
- MatchComponent[] memory arr1,
- MatchComponent[] memory arr2
- ) internal pure returns (MatchComponent[] memory newArr) {
- uint256 length1 = arr1.length;
- uint256 length2 = arr2.length;
- newArr = new MatchComponent[](length1 + length2);
- for (uint256 i = 0; i < length1; ) {
- newArr[i] = arr1[i];
- unchecked {
- ++i;
- }
- }
- for (uint256 i = 0; i < arr2.length; ) {
- uint256 j;
- unchecked {
- j = i + length1;
- }
- newArr[j] = arr2[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function allocateMatchComponents(
- uint256 length
- ) internal pure returns (MatchComponent[] memory arr) {
- arr = new MatchComponent[](length);
- assembly {
- mstore(arr, 0)
- }
- }
-
- function truncate(
- MatchComponent[] memory arr,
- uint256 newLength
- ) internal pure returns (MatchComponent[] memory _arr) {
- // truncate the array
- assembly {
- let oldLength := mload(arr)
- returndatacopy(
- returndatasize(),
- returndatasize(),
- gt(newLength, oldLength)
- )
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function truncateUnsafe(
- MatchComponent[] memory arr,
- uint256 newLength
- ) internal pure returns (MatchComponent[] memory _arr) {
- // truncate the array
- assembly {
- mstore(arr, newLength)
- _arr := arr
- }
- }
-
- function append(
- MatchComponent[] memory arr,
- MatchComponent memory value
- ) internal pure returns (MatchComponent[] memory newArr) {
- uint256 length = arr.length;
- newArr = new MatchComponent[](length + 1);
- newArr[length] = value;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function appendUnsafe(
- MatchComponent[] memory arr,
- MatchComponent memory value
- ) internal pure returns (MatchComponent[] memory modifiedArr) {
- uint256 length = arr.length;
- modifiedArr = arr;
- assembly {
- mstore(modifiedArr, add(length, 1))
- mstore(add(modifiedArr, shl(5, add(length, 1))), value)
- }
- }
-
- function copy(
- MatchComponent[] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- uint256 length = arr.length;
- newArr = new MatchComponent[](length);
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function copyAndResize(
- MatchComponent[] memory arr,
- uint256 newLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](newLength);
- uint256 length = arr.length;
- // allow shrinking a copy without copying extra members
- length = (length > newLength) ? newLength : length;
- for (uint256 i = 0; i < length; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- // TODO: consider writing 0-pointer to the rest of the array if longer for dynamic elements
- }
-
- function copyAndAllocate(
- MatchComponent[] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- uint256 originalLength = arr.length;
- for (uint256 i = 0; i < originalLength; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, originalLength)
- }
- }
-
- function pop(
- MatchComponent[] memory arr
- ) internal pure returns (MatchComponent memory value) {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popUnsafe(
- MatchComponent[] memory arr
- ) internal pure returns (MatchComponent memory value) {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, shl(5, length)))
- mstore(arr, sub(length, 1))
- }
- }
-
- function popLeft(
- MatchComponent[] memory arr
- )
- internal
- pure
- returns (MatchComponent[] memory newArr, MatchComponent memory value)
- {
- assembly {
- let length := mload(arr)
- returndatacopy(returndatasize(), returndatasize(), iszero(length))
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function popLeftUnsafe(
- MatchComponent[] memory arr
- )
- internal
- pure
- returns (MatchComponent[] memory newArr, MatchComponent memory value)
- {
- // This function is unsafe because it does not check if the array is empty.
- assembly {
- let length := mload(arr)
- value := mload(add(arr, 0x20))
- newArr := add(arr, 0x20)
- mstore(newArr, sub(length, 1))
- }
- }
-
- function fromFixed(
- MatchComponent[1] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](1);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- MatchComponent[1] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- for (uint256 i = 0; i < 1; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 1)
- }
- }
-
- function fromFixed(
- MatchComponent[2] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](2);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- MatchComponent[2] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- for (uint256 i = 0; i < 2; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 2)
- }
- }
-
- function fromFixed(
- MatchComponent[3] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](3);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- MatchComponent[3] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- for (uint256 i = 0; i < 3; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 3)
- }
- }
-
- function fromFixed(
- MatchComponent[4] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](4);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- MatchComponent[4] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- for (uint256 i = 0; i < 4; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 4)
- }
- }
-
- function fromFixed(
- MatchComponent[5] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](5);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- MatchComponent[5] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- for (uint256 i = 0; i < 5; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 5)
- }
- }
-
- function fromFixed(
- MatchComponent[6] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](6);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- MatchComponent[6] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- for (uint256 i = 0; i < 6; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 6)
- }
- }
-
- function fromFixed(
- MatchComponent[7] memory arr
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](7);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- }
-
- function fromFixedWithMaxLength(
- MatchComponent[7] memory arr,
- uint256 maxLength
- ) internal pure returns (MatchComponent[] memory newArr) {
- newArr = new MatchComponent[](maxLength);
- for (uint256 i = 0; i < 7; ) {
- newArr[i] = arr[i];
- unchecked {
- ++i;
- }
- }
- assembly {
- mstore(newArr, 7)
- }
- }
-
- function uints(uint a) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](1);
- arr[0] = a;
- return arr;
- }
-
- function uints(uint a, uint b) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uints(
- uint a,
- uint b,
- uint c
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uints(
- uint a,
- uint b,
- uint c,
- uint d
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uints(
- uint a,
- uint b,
- uint c,
- uint d,
- uint e
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uints(
- uint a,
- uint b,
- uint c,
- uint d,
- uint e,
- uint f
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uints(
- uint a,
- uint b,
- uint c,
- uint d,
- uint e,
- uint f,
- uint g
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function uintsWithMaxLength(
- uint256 maxLength,
- uint a
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](maxLength);
- assembly {
- mstore(arr, 1)
- }
- arr[0] = a;
- return arr;
- }
-
- function uintsWithMaxLength(
- uint256 maxLength,
- uint a,
- uint b
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](maxLength);
- assembly {
- mstore(arr, 2)
- }
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function uintsWithMaxLength(
- uint256 maxLength,
- uint a,
- uint b,
- uint c
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](maxLength);
- assembly {
- mstore(arr, 3)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function uintsWithMaxLength(
- uint256 maxLength,
- uint a,
- uint b,
- uint c,
- uint d
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](maxLength);
- assembly {
- mstore(arr, 4)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function uintsWithMaxLength(
- uint256 maxLength,
- uint a,
- uint b,
- uint c,
- uint d,
- uint e
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](maxLength);
- assembly {
- mstore(arr, 5)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function uintsWithMaxLength(
- uint256 maxLength,
- uint a,
- uint b,
- uint c,
- uint d,
- uint e,
- uint f
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](maxLength);
- assembly {
- mstore(arr, 6)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function uintsWithMaxLength(
- uint256 maxLength,
- uint a,
- uint b,
- uint c,
- uint d,
- uint e,
- uint f,
- uint g
- ) internal pure returns (uint[] memory) {
- uint[] memory arr = new uint[](maxLength);
- assembly {
- mstore(arr, 7)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function allocateUints(
- uint256 length
- ) internal pure returns (uint[] memory arr) {
- arr = new uint[](length);
- assembly {
- mstore(arr, 0)
- }
- }
-
- function ints(int a) internal pure returns (int[] memory) {
- int[] memory arr = new int[](1);
- arr[0] = a;
- return arr;
- }
-
- function ints(int a, int b) internal pure returns (int[] memory) {
- int[] memory arr = new int[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function ints(int a, int b, int c) internal pure returns (int[] memory) {
- int[] memory arr = new int[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function ints(
- int a,
- int b,
- int c,
- int d
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function ints(
- int a,
- int b,
- int c,
- int d,
- int e
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function ints(
- int a,
- int b,
- int c,
- int d,
- int e,
- int f
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function ints(
- int a,
- int b,
- int c,
- int d,
- int e,
- int f,
- int g
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function intsWithMaxLength(
- uint256 maxLength,
- int a
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](maxLength);
- assembly {
- mstore(arr, 1)
- }
- arr[0] = a;
- return arr;
- }
-
- function intsWithMaxLength(
- uint256 maxLength,
- int a,
- int b
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](maxLength);
- assembly {
- mstore(arr, 2)
- }
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function intsWithMaxLength(
- uint256 maxLength,
- int a,
- int b,
- int c
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](maxLength);
- assembly {
- mstore(arr, 3)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function intsWithMaxLength(
- uint256 maxLength,
- int a,
- int b,
- int c,
- int d
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](maxLength);
- assembly {
- mstore(arr, 4)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function intsWithMaxLength(
- uint256 maxLength,
- int a,
- int b,
- int c,
- int d,
- int e
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](maxLength);
- assembly {
- mstore(arr, 5)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function intsWithMaxLength(
- uint256 maxLength,
- int a,
- int b,
- int c,
- int d,
- int e,
- int f
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](maxLength);
- assembly {
- mstore(arr, 6)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function intsWithMaxLength(
- uint256 maxLength,
- int a,
- int b,
- int c,
- int d,
- int e,
- int f,
- int g
- ) internal pure returns (int[] memory) {
- int[] memory arr = new int[](maxLength);
- assembly {
- mstore(arr, 7)
- }
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function allocateInts(
- uint256 length
- ) internal pure returns (int[] memory arr) {
- arr = new int[](length);
- assembly {
- mstore(arr, 0)
- }
- }
-
- function amountKey(
- MatchComponent memory component
- ) internal pure returns (uint256) {
- return component.amount;
- }
-
- function indexKey(
- MatchComponent memory component
- ) internal pure returns (uint256) {
- return (component.orderIndex << 8) | component.itemIndex;
- }
-
- function sortByAmount(MatchComponent[] memory components) internal pure {
- sort(components, amountKey);
- }
-
- function sortByIndex(MatchComponent[] memory components) internal pure {
- sort(components, indexKey);
- }
-
- // Sorts the array in-place with intro-quicksort.
- function sort(
- MatchComponent[] memory a,
- function(MatchComponent memory) internal pure returns (uint256) accessor
- ) internal pure {
- if (a.length < 2) {
- return;
- }
-
- uint256[] memory stack = new uint256[](2 * a.length);
- uint256 stackIndex = 0;
-
- uint256 l = 0;
- uint256 h = a.length - 1;
-
- stack[stackIndex++] = l;
- stack[stackIndex++] = h;
-
- while (stackIndex > 0) {
- h = stack[--stackIndex];
- l = stack[--stackIndex];
-
- if (h - l <= 12) {
- // Insertion sort for small subarrays
- for (uint256 i = l + 1; i <= h; i++) {
- MatchComponent memory k = a[i];
- uint256 j = i;
- while (j > l && accessor(a[j - 1]) > accessor(k)) {
- a[j] = a[j - 1];
- j--;
- }
- a[j] = k;
- }
- } else {
- // Intro-Quicksort
- uint256 p = (l + h) / 2;
-
- // Median of 3
- if (accessor(a[l]) > accessor(a[p])) {
- (a[l], a[p]) = (a[p], a[l]);
- }
- if (accessor(a[l]) > accessor(a[h])) {
- (a[l], a[h]) = (a[h], a[l]);
- }
- if (accessor(a[p]) > accessor(a[h])) {
- (a[p], a[h]) = (a[h], a[p]);
- }
-
- uint256 pivot = accessor(a[p]);
- uint256 i = l;
- uint256 j = h;
-
- while (i <= j) {
- while (accessor(a[i]) < pivot) {
- i++;
- }
- while (accessor(a[j]) > pivot) {
- j--;
- }
- if (i <= j) {
- (a[i], a[j]) = (a[j], a[i]);
- i++;
- j--;
- }
- }
-
- if (j > l) {
- stack[stackIndex++] = l;
- stack[stackIndex++] = j;
- }
- if (i < h) {
- stack[stackIndex++] = i;
- stack[stackIndex++] = h;
- }
- }
- }
- }
-}
diff --git a/contracts/helpers/sol/fulfillments/lib/Structs.sol b/contracts/helpers/sol/fulfillments/lib/Structs.sol
deleted file mode 100644
index acd9e539d..000000000
--- a/contracts/helpers/sol/fulfillments/lib/Structs.sol
+++ /dev/null
@@ -1,105 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- MatchComponent,
- MatchComponentType
-} from "../../lib/types/MatchComponentType.sol";
-
-import {
- FulfillmentComponent,
- SpentItem,
- ReceivedItem
-} from "../../SeaportStructs.sol";
-
-import { UnavailableReason } from "../../SpaceEnums.sol";
-
-struct FulfillmentHelperCounterLayout {
- uint256 fulfillmentCounter;
-}
-
-// TODO: won't work for partial fulfills of criteria resolved
-// TODO: won't work for hybrid tokens that implement multiple token interfaces
-struct MatchFulfillmentStorageLayout {
- mapping(address /*tokenContract*/ => mapping(uint256 /*identifier*/ => mapping(address /*offerer*/ => mapping(bytes32 /*conduitKey*/ => MatchComponent[] /*components*/)))) offerMap;
- mapping(address /*recipient*/ => mapping(address /*tokenContract*/ => mapping(uint256 /*identifier*/ => MatchComponent[] /*components*/))) considerationMap;
- // a given aggregatable consideration component will have its own set of aggregatable offer components
- mapping(address /*token*/ => mapping(uint256 /*tokenId*/ => AggregatableOfferer[] /*offererEnumeration*/)) tokenToOffererEnumeration;
- // aggregatable consideration components can be enumerated normally
- AggregatableConsideration[] considerationEnumeration;
-}
-
-struct FulfillAvailableHelperStorageLayout {
- mapping(address /*tokenContract*/ => mapping(uint256 /*identifier*/ => mapping(address /*offerer*/ => mapping(bytes32 /*conduitKey*/ => FulfillmentComponent[] /*components*/)))) offerMap;
- mapping(address /*recipient*/ => mapping(address /*tokenContract*/ => mapping(uint256 /*identifier*/ => FulfillmentComponent[] /*components*/))) considerationMap;
- // a given aggregatable consideration component will have its own set of aggregatable offer components
- AggregatableOffer[] offerEnumeration;
- // aggregatable consideration components can be enumerated normally
- AggregatableConsideration[] considerationEnumeration;
-}
-
-/**
- * @notice Offers can only be aggregated if they share an offerer *and* conduitKey
- */
-struct AggregatableOfferer {
- address offerer;
- bytes32 conduitKey;
-}
-
-struct AggregatableOffer {
- address offerer;
- bytes32 conduitKey;
- address contractAddress;
- uint256 tokenId;
-}
-/**
- *
- * @notice Considerations can only be aggregated if they share a token address, id, and recipient (and itemType, but in the vast majority of cases, a token is only one type)
- */
-
-struct AggregatableConsideration {
- address recipient;
- address contractAddress;
- uint256 tokenId;
-}
-
-struct ProcessComponentParams {
- FulfillmentComponent[] offerFulfillmentComponents;
- FulfillmentComponent[] considerationFulfillmentComponents;
- uint256 offerItemIndex;
- uint256 considerationItemIndex;
- bool midCredit;
-}
-
-struct OrderDetails {
- address offerer;
- bytes32 conduitKey;
- SpentItem[] offer;
- ReceivedItem[] consideration;
- bool isContract;
- bytes32 orderHash;
- UnavailableReason unavailableReason;
-}
-
-/**
- * @dev Represents the details of a single fulfill/match call to Seaport.
- *
- * @param orders processed details of individual orders
- * @param recipient the explicit recipient of all offer items in
- * the fulfillAvailable case; implicit recipient
- * of excess offer items in the match case
- * @param fulfiller the explicit recipient of all unspent native
- * tokens; provides all consideration items in
- * the fulfillAvailable case
- * @param fulfillerConduitKey used to transfer tokens from the fulfiller
- * providing all consideration items in the
- * fulfillAvailable case
- */
-struct FulfillmentDetails {
- OrderDetails[] orders;
- address payable recipient;
- address payable fulfiller;
- uint256 nativeTokensSupplied;
- bytes32 fulfillerConduitKey;
- address seaport;
-}
diff --git a/contracts/helpers/sol/fulfillments/match/MatchFulfillmentHelper.sol b/contracts/helpers/sol/fulfillments/match/MatchFulfillmentHelper.sol
deleted file mode 100644
index be3ae1389..000000000
--- a/contracts/helpers/sol/fulfillments/match/MatchFulfillmentHelper.sol
+++ /dev/null
@@ -1,356 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- AggregatableConsideration,
- ProcessComponentParams,
- AggregatableOfferer,
- OrderDetails,
- MatchFulfillmentStorageLayout
-} from "../lib/Structs.sol";
-import {
- MatchComponent,
- MatchComponentType
-} from "../../lib/types/MatchComponentType.sol";
-import {
- FulfillmentComponent,
- Fulfillment,
- Order,
- AdvancedOrder,
- OrderParameters,
- SpentItem,
- ReceivedItem,
- CriteriaResolver
-} from "../../SeaportStructs.sol";
-import { UnavailableReason } from "../../SpaceEnums.sol";
-import { MatchFulfillmentLib } from "./MatchFulfillmentLib.sol";
-import { MatchFulfillmentLayout } from "./MatchFulfillmentLayout.sol";
-
-import {
- AmountDeriverHelper
-} from "../../lib/fulfillment/AmountDeriverHelper.sol";
-import { MatchArrays } from "../lib/MatchArrays.sol";
-
-contract MatchFulfillmentHelper is AmountDeriverHelper {
- /**
- * @notice Generate matched fulfillments for a list of orders
- * NOTE: this will break for multiple criteria items that resolve
- * to different identifiers
- * @param orders orders
- * @return fulfillments
- */
- function getMatchedFulfillments(
- Order[] memory orders,
- bytes32[] memory orderHashes,
- UnavailableReason[] memory unavailableReasons
- )
- public
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory remainingOfferComponents,
- MatchComponent[] memory remainingConsiderationComponents
- )
- {
- OrderDetails[] memory orderDetails = toOrderDetails(
- orders,
- orderHashes,
- unavailableReasons
- );
-
- return getMatchedFulfillments(orderDetails);
- }
-
- /**
- * @notice Generate matched fulfillments for a list of orders
- * NOTE: this will break for multiple criteria items that resolve
- * to different identifiers
- * @param orders orders
- * @param resolvers resolvers
- * @return fulfillments
- */
- function getMatchedFulfillments(
- AdvancedOrder[] memory orders,
- CriteriaResolver[] memory resolvers,
- bytes32[] memory orderHashes,
- UnavailableReason[] memory unavailableReasons
- )
- public
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory remainingOfferComponents,
- MatchComponent[] memory remainingConsiderationComponents
- )
- {
- OrderDetails[] memory details = toOrderDetails(
- orders,
- resolvers,
- orderHashes,
- unavailableReasons
- );
- return getMatchedFulfillments(details);
- }
-
- /**
- * @notice Generate matched fulfillments for a list of orders
- * NOTE: this will break for multiple criteria items that resolve
- * to different identifiers
- * @param orders orders
- * @return fulfillments
- */
- function getMatchedFulfillments(
- OrderDetails[] memory orders
- )
- public
- returns (
- Fulfillment[] memory fulfillments,
- MatchComponent[] memory remainingOfferComponents,
- MatchComponent[] memory remainingConsiderationComponents
- )
- {
- // increment counter to get clean mappings and enumeration
- MatchFulfillmentLayout.incrementFulfillmentCounter();
- // load the storage layout
- MatchFulfillmentStorageLayout storage layout = MatchFulfillmentLayout
- .getStorageLayout();
-
- // iterate over each order and process the offer and consideration components
- for (uint256 i; i < orders.length; ++i) {
- OrderDetails memory details = orders[i];
-
- // insert MatchComponents into the offer mapping, grouped by token, tokenId, offerer, and conduitKey
- // also update per-token+tokenId enumerations of AggregatableOfferer
-
- preProcessSpentItems(
- details.offer,
- details.offerer,
- details.conduitKey,
- i,
- layout
- );
- // insert MatchComponents into the offer mapping, grouped by token, tokenId, and recipient
- // also update AggregatableConsideration enumeration
- preProcessSpentItems(details.consideration, i, layout);
- }
-
- // iterate over groups of consideration components and find matching offer components
- uint256 considerationLength = layout.considerationEnumeration.length;
- for (uint256 i; i < considerationLength; ++i) {
- // get the token information
- AggregatableConsideration storage token = layout
- .considerationEnumeration[i];
- // load the consideration components
- MatchComponent[] storage considerationComponents = layout
- .considerationMap[token.recipient][token.contractAddress][
- token.tokenId
- ];
- // load the enumeration of offerer+conduit keys for offer components that match this token
- AggregatableOfferer[] storage offererEnumeration = layout
- .tokenToOffererEnumeration[token.contractAddress][
- token.tokenId
- ];
- // iterate over each offerer+conduit with offer components that match this token and create matching fulfillments
- // this will update considerationComponents in-place in storage, which we check at the beginning of each loop
- for (uint256 j; j < offererEnumeration.length; ++j) {
- // if all consideration components have been fulfilled, break
- if (considerationComponents.length == 0) {
- break;
- }
- // load the AggregatableOfferer
- AggregatableOfferer
- storage aggregatableOfferer = offererEnumeration[j];
- // load the associated offer components for this offerer+conduit
- MatchComponent[] storage offerComponents = layout.offerMap[
- token.contractAddress
- ][token.tokenId][aggregatableOfferer.offerer][
- aggregatableOfferer.conduitKey
- ];
- // if there are no offer components left, continue
- // TODO: remove from enumeration?
- if (offerComponents.length == 0) {
- continue;
- }
-
- // create a fulfillment matching the offer and consideration components until either or both are exhausted
- Fulfillment memory fulfillment = MatchFulfillmentLib
- .createFulfillment(
- offerComponents,
- considerationComponents
- );
- // append the fulfillment to the array of fulfillments
- fulfillments = MatchArrays.append(fulfillments, fulfillment);
- // loop back around in case not all considerationComponents have been completely fulfilled
- }
- }
-
- // get any remaining offer components
- for (uint256 i; i < orders.length; ++i) {
- OrderDetails memory details = orders[i];
-
- // insert MatchComponents into the offer mapping, grouped by token, tokenId, offerer, and conduitKey
- // also update per-token+tokenId enumerations of AggregatableOfferer
- remainingOfferComponents = MatchArrays.extend(
- remainingOfferComponents,
- postProcessSpentItems(
- details.offer,
- details.offerer,
- details.conduitKey,
- layout
- )
- );
-
- remainingConsiderationComponents = MatchArrays.extend(
- remainingConsiderationComponents,
- postProcessReceivedItems(details.consideration, layout)
- );
- }
- remainingOfferComponents = MatchFulfillmentLib.dedupe(
- remainingOfferComponents
- );
- remainingConsiderationComponents = MatchFulfillmentLib.dedupe(
- remainingConsiderationComponents
- );
- }
-
- /**
- * @notice Process offer items and insert them into enumeration and map
- * @param offer offer items
- * @param offerer offerer
- * @param orderIndex order index of processed items
- * @param layout storage layout of helper
- */
- function preProcessSpentItems(
- SpentItem[] memory offer,
- address offerer,
- bytes32 conduitKey,
- uint256 orderIndex,
- MatchFulfillmentStorageLayout storage layout
- ) private {
- // iterate over each offer item
- for (uint256 j; j < offer.length; ++j) {
- // grab offer item
- // TODO: spentItems?
- SpentItem memory item = offer[j];
- MatchComponent memory component = MatchComponentType
- .createMatchComponent({
- amount: uint240(item.amount),
- orderIndex: uint8(orderIndex),
- itemIndex: uint8(j)
- });
- AggregatableOfferer
- memory aggregatableOfferer = AggregatableOfferer({
- offerer: offerer,
- conduitKey: conduitKey
- });
-
- // if it does not exist in the map, add it to our per-token+id enumeration
- if (
- !MatchFulfillmentLib.aggregatableOffererExists(
- item.token,
- item.identifier,
- aggregatableOfferer,
- layout
- )
- ) {
- // add to enumeration for specific tokenhash (tokenAddress+tokenId)
- layout
- .tokenToOffererEnumeration[item.token][item.identifier].push(
- aggregatableOfferer
- );
- }
- // update aggregatable mapping array with this component
- layout
- .offerMap[item.token][item.identifier][offerer][conduitKey].push(
- component
- );
- }
- }
-
- function postProcessSpentItems(
- SpentItem[] memory offer,
- address offerer,
- bytes32 conduitKey,
- MatchFulfillmentStorageLayout storage layout
- ) private view returns (MatchComponent[] memory remainingOfferComponents) {
- // iterate over each offer item
- for (uint256 j; j < offer.length; ++j) {
- // grab offer item
- // TODO: spentItems?
- SpentItem memory item = offer[j];
-
- // update aggregatable mapping array with this component
- remainingOfferComponents = MatchArrays.extend(
- remainingOfferComponents,
- layout.offerMap[item.token][item.identifier][offerer][
- conduitKey
- ]
- );
- }
- }
-
- /**
- * @notice Process consideration items and insert them into enumeration and map
- * @param consideration consideration items
- * @param orderIndex order index of processed items
- * @param layout storage layout of helper
- */
- function preProcessSpentItems(
- ReceivedItem[] memory consideration,
- uint256 orderIndex,
- MatchFulfillmentStorageLayout storage layout
- ) private {
- // iterate over each consideration item
- for (uint256 j; j < consideration.length; ++j) {
- // grab consideration item
- ReceivedItem memory item = consideration[j];
- // TODO: use receivedItem here?
- MatchComponent memory component = MatchComponentType
- .createMatchComponent({
- amount: uint240(item.amount),
- orderIndex: uint8(orderIndex),
- itemIndex: uint8(j)
- });
- // create enumeration struct
- AggregatableConsideration memory token = AggregatableConsideration({
- recipient: item.recipient,
- contractAddress: item.token,
- tokenId: item.identifier
- });
- // if it does not exist in the map, add it to our enumeration
- if (
- !MatchFulfillmentLib.aggregatableConsiderationExists(
- token,
- layout
- )
- ) {
- layout.considerationEnumeration.push(token);
- }
- // update mapping with this component
- layout
- .considerationMap[token.recipient][token.contractAddress][
- token.tokenId
- ].push(component);
- }
- }
-
- function postProcessReceivedItems(
- ReceivedItem[] memory consideration,
- MatchFulfillmentStorageLayout storage layout
- )
- private
- view
- returns (MatchComponent[] memory remainingConsiderationComponents)
- {
- // iterate over each consideration item
- for (uint256 j; j < consideration.length; ++j) {
- // grab consideration item
- ReceivedItem memory item = consideration[j];
-
- remainingConsiderationComponents = MatchArrays.extend(
- remainingConsiderationComponents,
- layout.considerationMap[item.recipient][item.token][
- item.identifier
- ]
- );
- }
- }
-}
diff --git a/contracts/helpers/sol/fulfillments/match/MatchFulfillmentLayout.sol b/contracts/helpers/sol/fulfillments/match/MatchFulfillmentLayout.sol
deleted file mode 100644
index c0d06ed68..000000000
--- a/contracts/helpers/sol/fulfillments/match/MatchFulfillmentLayout.sol
+++ /dev/null
@@ -1,97 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- MatchComponent,
- MatchComponentType
-} from "../../lib/types/MatchComponentType.sol";
-import {
- MatchFulfillmentStorageLayout,
- FulfillmentHelperCounterLayout,
- AggregatableConsideration
-} from "../lib/Structs.sol";
-import {
- MATCH_FULFILLMENT_COUNTER_KEY,
- MATCH_FULFILLMENT_STORAGE_BASE_KEY
-} from "../lib/Constants.sol";
-
-library MatchFulfillmentLayout {
- /**
- * @notice load storage layout for the current fulfillmentCounter
- */
- function getStorageLayout()
- internal
- view
- returns (MatchFulfillmentStorageLayout storage layout)
- {
- FulfillmentHelperCounterLayout
- storage counterLayout = getCounterLayout();
- uint256 counter = counterLayout.fulfillmentCounter;
- bytes32 storageLayoutKey = MATCH_FULFILLMENT_STORAGE_BASE_KEY;
- assembly {
- mstore(0, counter)
- mstore(0x20, storageLayoutKey)
- layout.slot := keccak256(0, 0x40)
- }
- }
-
- /**
- * @notice load storage layout for the counter itself
- */
- function getCounterLayout()
- internal
- pure
- returns (FulfillmentHelperCounterLayout storage layout)
- {
- bytes32 counterLayoutKey = MATCH_FULFILLMENT_COUNTER_KEY;
- assembly {
- layout.slot := counterLayoutKey
- }
- }
-
- /**
- * @notice increment the fulfillmentCounter to effectively clear the mappings and enumerations between calls
- */
- function incrementFulfillmentCounter() internal {
- FulfillmentHelperCounterLayout
- storage counterLayout = getCounterLayout();
- counterLayout.fulfillmentCounter += 1;
- }
-
- /**
- * @notice Get the mapping of tokens for a given key (offer or consideration), derived from the hash of the key and the current fulfillmentCounter value
- * @param key Original key used to derive the slot of the enumeration
- */
- function getMap(
- bytes32 key
- )
- internal
- view
- returns (
- mapping(address /*offererOrRecipient*/ => mapping(address /*tokenContract*/ => mapping(uint256 /*identifier*/ => MatchComponent[] /*components*/)))
- storage map
- )
- {
- bytes32 counterKey = MATCH_FULFILLMENT_COUNTER_KEY;
- assembly {
- mstore(0, key)
- mstore(0x20, sload(counterKey))
- map.slot := keccak256(0, 0x40)
- }
- }
-
- /**
- * @notice Get the enumeration of AggregatableConsiderations for a given key (offer or consideration), derived from the hash of the key and the current fulfillmentCounter value
- * @param key Original key used to derive the slot of the enumeration
- */
- function getEnumeration(
- bytes32 key
- ) internal view returns (AggregatableConsideration[] storage tokens) {
- bytes32 counterKey = MATCH_FULFILLMENT_COUNTER_KEY;
- assembly {
- mstore(0, key)
- mstore(0x20, sload(counterKey))
- tokens.slot := keccak256(0, 0x40)
- }
- }
-}
diff --git a/contracts/helpers/sol/fulfillments/match/MatchFulfillmentLib.sol b/contracts/helpers/sol/fulfillments/match/MatchFulfillmentLib.sol
deleted file mode 100644
index e220f6894..000000000
--- a/contracts/helpers/sol/fulfillments/match/MatchFulfillmentLib.sol
+++ /dev/null
@@ -1,314 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- AggregatableConsideration,
- ProcessComponentParams,
- MatchFulfillmentStorageLayout,
- AggregatableOfferer
-} from "../lib/Structs.sol";
-import {
- MatchComponent,
- MatchComponentType
-} from "../../lib/types/MatchComponentType.sol";
-import { FulfillmentComponent, Fulfillment } from "../../SeaportStructs.sol";
-import { LibSort } from "solady/src/utils/LibSort.sol";
-import { MatchArrays } from "../lib/MatchArrays.sol";
-
-library MatchFulfillmentLib {
- using MatchComponentType for MatchComponent[];
- using MatchComponentType for MatchComponent;
-
- /**
- * @notice Check if a token already exists in a mapping by checking the length of the array at that slot
- * @param token token to check
- * @param layout storage layout
- */
- function aggregatableConsiderationExists(
- AggregatableConsideration memory token,
- MatchFulfillmentStorageLayout storage layout
- ) internal view returns (bool) {
- return
- layout
- .considerationMap[token.recipient][token.contractAddress][
- token.tokenId
- ].length > 0;
- }
-
- /**
- * @notice Check if an entry into the offer component mapping already exists by checking its length
- */
- function aggregatableOffererExists(
- address token,
- uint256 tokenId,
- AggregatableOfferer memory offerer,
- MatchFulfillmentStorageLayout storage layout
- ) internal view returns (bool) {
- return
- layout
- .offerMap[token][tokenId][offerer.offerer][offerer.conduitKey]
- .length > 0;
- }
-
- function processConsiderationComponent(
- MatchComponent[] storage offerComponents,
- MatchComponent[] storage considerationComponents,
- ProcessComponentParams memory params
- ) internal {
- while (params.offerItemIndex < offerComponents.length) {
- MatchComponent
- memory considerationComponent = considerationComponents[
- params.considerationItemIndex
- ];
-
- // if consideration has been completely credited, break to next consideration component
- if (considerationComponent.getAmount() == 0) {
- break;
- }
- processOfferComponent({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents,
- params: params
- });
- }
-
- MatchArrays.appendUnsafe(
- params.considerationFulfillmentComponents,
- considerationComponents[params.considerationItemIndex]
- .toFulfillmentComponent()
- );
- }
-
- function processOfferComponent(
- MatchComponent[] storage offerComponents,
- MatchComponent[] storage considerationComponents,
- ProcessComponentParams memory params
- ) internal {
- // re-load components each iteration as they may have been modified
- MatchComponent memory offerComponent = offerComponents[
- params.offerItemIndex
- ];
- MatchComponent memory considerationComponent = considerationComponents[
- params.considerationItemIndex
- ];
-
- if (offerComponent.getAmount() > considerationComponent.getAmount()) {
- // if offer amount is greater than consideration amount, set consideration to zero and credit from offer amount
- offerComponent = offerComponent.subtractAmount(
- considerationComponent
- );
- considerationComponent = considerationComponent.setAmount(0);
- offerComponents[params.offerItemIndex] = offerComponent;
- considerationComponents[
- params.considerationItemIndex
- ] = considerationComponent;
- // note that this offerItemIndex should be included when consolidating
- params.midCredit = true;
- } else {
- // otherwise deplete offer amount and credit consideration amount
-
- considerationComponent = considerationComponent.subtractAmount(
- offerComponent
- );
- offerComponent = offerComponent.setAmount(0);
-
- considerationComponents[
- params.considerationItemIndex
- ] = considerationComponent;
-
- offerComponents[params.offerItemIndex] = offerComponent;
- ++params.offerItemIndex;
- // note that this offerItemIndex should not be included when consolidating
- params.midCredit = false;
- }
- // an offer component may have already been added if it was not depleted by an earlier consideration item
- if (
- !previouslyAdded(
- params.offerFulfillmentComponents,
- offerComponent.toFulfillmentComponent()
- )
- ) {
- MatchArrays.appendUnsafe(
- params.offerFulfillmentComponents,
- offerComponent.toFulfillmentComponent()
- );
- }
- }
-
- function scuffLength(
- FulfillmentComponent[] memory components,
- uint256 newLength
- ) internal pure {
- assembly {
- mstore(components, newLength)
- }
- }
-
- function previouslyAdded(
- FulfillmentComponent[] memory components,
- FulfillmentComponent memory fulfillmentComponent
- ) internal pure returns (bool) {
- if (components.length == 0) {
- return false;
- }
-
- FulfillmentComponent memory lastComponent = components[
- components.length - 1
- ];
- return
- lastComponent.orderIndex == fulfillmentComponent.orderIndex &&
- lastComponent.itemIndex == fulfillmentComponent.itemIndex;
- }
-
- /**
- * Credit offer components to consideration components until either or both are exhausted
- * Updates arrays in storage to remove 0-item components after credits
- * @param offerComponents Aggregatable offer components
- * @param considerationComponents Aggregatable consideration components
- */
- function createFulfillment(
- MatchComponent[] storage offerComponents,
- MatchComponent[] storage considerationComponents
- ) internal returns (Fulfillment memory) {
- // optimistically allocate arrays of fulfillment components
- FulfillmentComponent[] memory offerFulfillmentComponents = MatchArrays
- .allocateFulfillmentComponents(offerComponents.length);
- FulfillmentComponent[]
- memory considerationFulfillmentComponents = MatchArrays
- .allocateFulfillmentComponents(considerationComponents.length);
- // iterate over consideration components
- ProcessComponentParams memory params = ProcessComponentParams({
- offerFulfillmentComponents: offerFulfillmentComponents,
- considerationFulfillmentComponents: considerationFulfillmentComponents,
- offerItemIndex: 0,
- considerationItemIndex: 0,
- midCredit: false
- });
-
- // iterate over all consideration components eligible to be fulfilled
- // in a single transfer; this means that any uncredited amounts will be
- // consolidated into the first component for later fulfillments
- // TODO: this may not be optimal in some cases with partial
- // fulfillments
- for (
- uint256 considerationItemIndex;
- considerationItemIndex < considerationComponents.length;
- ++considerationItemIndex
- ) {
- // params will be updated directly by called functions except for considerationItemIndex
- params.considerationItemIndex = considerationItemIndex;
- processConsiderationComponent({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents,
- params: params
- });
- }
-
- // remove any zero-amount components so they are skipped in future
- // fulfillments, and consolidate any remaining offer amounts used
- // in this fulfillment into the first component.
- consolidateComponents(
- offerComponents,
- // if mid-credit, offerItemIndex should be included in consolidation
- (params.midCredit)
- ? params.offerItemIndex + 1
- : params.offerItemIndex
- );
- // all eligible consideration components will be processed when matched
- // with the first eligible offer components, whether or not there are
- // enough offer items to credit each consideration item. This means
- // that all remaining amounts will be consolidated into the first
- // consideration component for later fulfillments.
- consolidateComponents(
- considerationComponents,
- considerationComponents.length
- );
-
- // return a discrete fulfillment since either or both of the sets of components have been exhausted
- // if offer or consideration items remain, they will be revisited in subsequent calls
- return
- Fulfillment({
- offerComponents: offerFulfillmentComponents,
- considerationComponents: considerationFulfillmentComponents
- });
- }
-
- /**
- * @dev Consolidate any remaining amounts
- * @param components Components to consolidate
- * @param excludeIndex First index to exclude from consolidation. For
- * offerComponents this is the index after the last credited item,
- * for considerationComponents, this is the length of the array
- */
- function consolidateComponents(
- MatchComponent[] storage components,
- uint256 excludeIndex
- ) internal {
- // cache components in memory
- MatchComponent[] memory cachedComponents = components;
- if (cachedComponents.length == 0) {
- return;
- } else if (cachedComponents.length == 1) {
- // check if there is only one component
- // if it is zero, remove it
- if (cachedComponents[0].getAmount() == 0) {
- components.pop();
- }
- // otherwise do nothing
- return;
- }
- // otherwise clear the storage array
- while (components.length > 0) {
- components.pop();
- }
-
- // consolidate the amounts of credited non-zero components into the
- // first component. This is what Seaport does internally when a
- // fulfillment is credited.
- MatchComponent memory first = cachedComponents[0];
-
- // consolidate all non-zero components used in this fulfillment into the
- // first component
- for (uint256 i = 1; i < excludeIndex; ++i) {
- first = first.addAmount(cachedComponents[i]);
- }
-
- // push the first component back into storage if it is non-zero
- if (first.getAmount() > 0) {
- components.push(first);
- }
- // push any remaining non-zero components back into storage
- for (uint256 i = excludeIndex; i < cachedComponents.length; ++i) {
- MatchComponent memory component = cachedComponents[i];
- if (component.getAmount() > 0) {
- components.push(component);
- }
- }
- }
-
- function dedupe(
- MatchComponent[] memory components
- ) internal pure returns (MatchComponent[] memory dedupedComponents) {
- if (components.length == 0 || components.length == 1) {
- return components;
- }
- // sort components
- // uint256[] memory cast = components.toUints();
- // LibSort.sort(cast);
- // components = MatchComponentType.fromUints(cast);
- // create a new array of same size; it will be truncated if necessary
- MatchArrays.sortByIndex(components);
- dedupedComponents = new MatchComponent[](components.length);
- dedupedComponents[0] = components[0];
- uint256 dedupedIndex = 1;
- for (uint256 i = 1; i < components.length; i++) {
- // compare current component to last deduped component
- if (!components[i].equals(dedupedComponents[dedupedIndex - 1])) {
- // if it is different, add it to the deduped array and increment the index
- dedupedComponents[dedupedIndex] = components[i];
- ++dedupedIndex;
- }
- }
- return MatchArrays.truncate(dedupedComponents, dedupedIndex);
- }
-}
diff --git a/contracts/helpers/sol/lib/AdditionalRecipientLib.sol b/contracts/helpers/sol/lib/AdditionalRecipientLib.sol
deleted file mode 100644
index b86ac4230..000000000
--- a/contracts/helpers/sol/lib/AdditionalRecipientLib.sol
+++ /dev/null
@@ -1,264 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { AdditionalRecipient } from "../../../lib/ConsiderationStructs.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title AdditionalRecipientLib
- * @author James Wenzel (emo.eth)
- * @notice AdditionalRecipientLib is a library for managing AdditionalRecipient
- * structs and arrays. It allows chaining of functions to make
- * struct creation more readable.
- */
-library AdditionalRecipientLib {
- bytes32 private constant ADDITIONAL_RECIPIENT_MAP_POSITION =
- keccak256("seaport.AdditionalRecipientDefaults");
- bytes32 private constant ADDITIONAL_RECIPIENTS_MAP_POSITION =
- keccak256("seaport.AdditionalRecipientsDefaults");
- bytes32 private constant EMPTY_ADDITIONAL_RECIPIENT =
- keccak256(
- abi.encode(
- AdditionalRecipient({
- amount: 0,
- recipient: payable(address(0))
- })
- )
- );
-
- /**
- * @dev Clears a default AdditionalRecipient from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => AdditionalRecipient)
- storage additionalRecipientMap = _additionalRecipientMap();
- AdditionalRecipient storage item = additionalRecipientMap[defaultName];
- clear(item);
- }
-
- /**
- * @dev Clears all fields on an AdditionalRecipient.
- *
- * @param item the AdditionalRecipient to clear
- */
- function clear(AdditionalRecipient storage item) internal {
- // clear all fields
- item.amount = 0;
- item.recipient = payable(address(0));
- }
-
- /**
- * @dev Clears an array of AdditionalRecipients from storage.
- *
- * @param items the name of the default to clear
- */
- function clear(AdditionalRecipient[] storage items) internal {
- while (items.length > 0) {
- clear(items[items.length - 1]);
- items.pop();
- }
- }
-
- /**
- * @dev Gets a default AdditionalRecipient from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the AdditionalRecipient retrieved from storage
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (AdditionalRecipient memory item) {
- mapping(string => AdditionalRecipient)
- storage additionalRecipientMap = _additionalRecipientMap();
- item = additionalRecipientMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_ADDITIONAL_RECIPIENT) {
- revert("Empty AdditionalRecipient selected.");
- }
- }
-
- /**
- * @dev Gets an array of default AdditionalRecipients from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the AdditionalRecipients retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (AdditionalRecipient[] memory items) {
- mapping(string => AdditionalRecipient[])
- storage additionalRecipientsMap = _additionalRecipientsMap();
- items = additionalRecipientsMap[defaultName];
-
- if (items.length == 0) {
- revert("Empty AdditionalRecipient array selected.");
- }
- }
-
- /**
- * @dev Saves an AdditionalRecipient as a named default.
- *
- * @param additionalRecipient the AdditionalRecipient to save as a default
- * @param defaultName the name of the new default
- *
- * @return _additionalRecipient the AdditionalRecipient saved as a default
- */
- function saveDefault(
- AdditionalRecipient memory additionalRecipient,
- string memory defaultName
- ) internal returns (AdditionalRecipient memory _additionalRecipient) {
- mapping(string => AdditionalRecipient)
- storage additionalRecipientMap = _additionalRecipientMap();
- additionalRecipientMap[defaultName] = additionalRecipient;
- return additionalRecipient;
- }
-
- /**
- * @dev Saves an array of AdditionalRecipients as a named default.
- *
- * @param additionalRecipients the AdditionalRecipients to save as a default
- * @param defaultName the name of the new default
- *
- * @return _additionalRecipients the AdditionalRecipients saved as a default
- */
- function saveDefaultMany(
- AdditionalRecipient[] memory additionalRecipients,
- string memory defaultName
- ) internal returns (AdditionalRecipient[] memory _additionalRecipients) {
- mapping(string => AdditionalRecipient[])
- storage additionalRecipientsMap = _additionalRecipientsMap();
- StructCopier.setAdditionalRecipients(
- additionalRecipientsMap[defaultName],
- additionalRecipients
- );
- return additionalRecipients;
- }
-
- /**
- * @dev Makes a copy of an AdditionalRecipient in-memory.
- *
- * @param item the AdditionalRecipient to make a copy of in-memory
- *
- * @custom:return additionalRecipient the copy of the AdditionalRecipient
- */
- function copy(
- AdditionalRecipient memory item
- ) internal pure returns (AdditionalRecipient memory) {
- return
- AdditionalRecipient({
- amount: item.amount,
- recipient: item.recipient
- });
- }
-
- /**
- * @dev Makes a copy of an array of AdditionalRecipients in-memory.
- *
- * @param items the AdditionalRecipients to make a copy of in-memory
- *
- * @custom:return additionalRecipients the copy of the AdditionalRecipients
- */
- function copy(
- AdditionalRecipient[] memory items
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory copiedItems = new AdditionalRecipient[](
- items.length
- );
- for (uint256 i = 0; i < items.length; i++) {
- copiedItems[i] = copy(items[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Returns an empty AdditionalRecipient.
- *
- * @custom:return item the empty AdditionalRecipient
- */
- function empty() internal pure returns (AdditionalRecipient memory) {
- return
- AdditionalRecipient({ amount: 0, recipient: payable(address(0)) });
- }
-
- /**
- * @dev Gets the storage position of the default AdditionalRecipient map.
- *
- * @custom:return additionalRecipientMap the storage position of the default
- * AdditionalRecipient map
- */
- function _additionalRecipientMap()
- private
- pure
- returns (
- mapping(string => AdditionalRecipient)
- storage additionalRecipientMap
- )
- {
- bytes32 position = ADDITIONAL_RECIPIENT_MAP_POSITION;
- assembly {
- additionalRecipientMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default AdditionalRecipients array
- * map.
- *
- * @custom:return additionalRecipientsMap the storage position of the
- * default AdditionalRecipient array
- * map
- */
- function _additionalRecipientsMap()
- private
- pure
- returns (
- mapping(string => AdditionalRecipient[])
- storage additionalRecipientsMap
- )
- {
- bytes32 position = ADDITIONAL_RECIPIENTS_MAP_POSITION;
- assembly {
- additionalRecipientsMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of an AdditionalRecipient's
- // fields, which modify the AdditionalRecipient in-place and return it.
-
- /**
- * @dev Sets the amount field of an AdditionalRecipient.
- *
- * @param item the AdditionalRecipient to modify
- * @param amount the amount to set
- *
- * @custom:return _item the modified AdditionalRecipient
- */
- function withAmount(
- AdditionalRecipient memory item,
- uint256 amount
- ) internal pure returns (AdditionalRecipient memory) {
- item.amount = amount;
- return item;
- }
-
- /**
- * @dev Sets the recipient field of an AdditionalRecipient.
- *
- * @param item the AdditionalRecipient to modify
- * @param recipient the recipient to set
- *
- * @custom:return _item the modified AdditionalRecipient
- */
- function withRecipient(
- AdditionalRecipient memory item,
- address recipient
- ) internal pure returns (AdditionalRecipient memory) {
- item.recipient = payable(recipient);
- return item;
- }
-}
diff --git a/contracts/helpers/sol/lib/AdvancedOrderLib.sol b/contracts/helpers/sol/lib/AdvancedOrderLib.sol
deleted file mode 100644
index 68abf444e..000000000
--- a/contracts/helpers/sol/lib/AdvancedOrderLib.sol
+++ /dev/null
@@ -1,793 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- AdditionalRecipient,
- AdvancedOrder,
- BasicOrderParameters,
- ConsiderationItem,
- CriteriaResolver,
- OfferItem,
- Order,
- OrderComponents,
- OrderParameters,
- OrderType,
- ReceivedItem,
- SpentItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { BasicOrderType, ItemType } from "../../../lib/ConsiderationEnums.sol";
-
-import { UnavailableReason } from "../SpaceEnums.sol";
-
-import { OrderParametersLib } from "./OrderParametersLib.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-import { SeaportInterface } from "../SeaportInterface.sol";
-
-import { OrderDetails } from "../fulfillments/lib/Structs.sol";
-
-struct ContractNonceDetails {
- bool set;
- address offerer;
- uint256 currentNonce;
-}
-
-/**
- * @title AdvancedOrderLib
- * @author James Wenzel (emo.eth)
- * @notice AdditionalRecipientLib is a library for managing AdvancedOrder
- * structs and arrays. It allows chaining of functions to make struct
- * creation more readable.
- */
-library AdvancedOrderLib {
- bytes32 private constant ADVANCED_ORDER_MAP_POSITION =
- keccak256("seaport.AdvancedOrderDefaults");
- bytes32 private constant ADVANCED_ORDERS_MAP_POSITION =
- keccak256("seaport.AdvancedOrdersDefaults");
- bytes32 private constant EMPTY_ADVANCED_ORDER =
- keccak256(
- abi.encode(
- AdvancedOrder({
- parameters: OrderParameters({
- offerer: address(0),
- zone: address(0),
- offer: new OfferItem[](0),
- consideration: new ConsiderationItem[](0),
- orderType: OrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- conduitKey: bytes32(0),
- totalOriginalConsiderationItems: 0
- }),
- numerator: 0,
- denominator: 0,
- signature: new bytes(0),
- extraData: new bytes(0)
- })
- )
- );
-
- using OrderParametersLib for OrderParameters;
-
- /**
- * @dev Clears a default AdvancedOrder from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => AdvancedOrder)
- storage advancedOrderMap = _advancedOrderMap();
- AdvancedOrder storage item = advancedOrderMap[defaultName];
- clear(item);
- }
-
- /**
- * @dev Clears all fields on an AdvancedOrder.
- *
- * @param item the AdvancedOrder to clear
- */
- function clear(AdvancedOrder storage item) internal {
- // clear all fields
- item.parameters.clear();
- item.signature = "";
- item.numerator = 0;
- item.denominator = 0;
- item.extraData = "";
- }
-
- /**
- * @dev Clears an array of AdvancedOrders from storage.
- *
- * @param items the AdvancedOrders to clear
- */
- function clear(AdvancedOrder[] storage items) internal {
- while (items.length > 0) {
- clear(items[items.length - 1]);
- items.pop();
- }
- }
-
- /**
- * @dev Gets a default AdvancedOrder from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the AdvancedOrder retrieved from storage
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (AdvancedOrder memory item) {
- mapping(string => AdvancedOrder)
- storage advancedOrderMap = _advancedOrderMap();
- item = advancedOrderMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_ADVANCED_ORDER) {
- revert("Empty AdvancedOrder selected.");
- }
- }
-
- /**
- * @dev Gets an array of default AdvancedOrders from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the AdvancedOrders retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (AdvancedOrder[] memory items) {
- mapping(string => AdvancedOrder[])
- storage advancedOrdersMap = _advancedOrdersMap();
- items = advancedOrdersMap[defaultName];
-
- if (items.length == 0) {
- revert("Empty AdvancedOrder array selected.");
- }
- }
-
- /**
- * @dev Returns an empty AdvancedOrder.
- *
- * @custom:return item the empty AdvancedOrder
- */
- function empty() internal pure returns (AdvancedOrder memory) {
- return AdvancedOrder(OrderParametersLib.empty(), 0, 0, "", "");
- }
-
- /**
- * @dev Saves an AdvancedOrder as a named default.
- *
- * @param advancedOrder the AdvancedOrder to save as a default
- * @param defaultName the name of the new default
- *
- * @return _advancedOrder the AdvancedOrder saved as a default
- */
- function saveDefault(
- AdvancedOrder memory advancedOrder,
- string memory defaultName
- ) internal returns (AdvancedOrder memory _advancedOrder) {
- mapping(string => AdvancedOrder)
- storage advancedOrderMap = _advancedOrderMap();
- StructCopier.setAdvancedOrder(
- advancedOrderMap[defaultName],
- advancedOrder
- );
- return advancedOrder;
- }
-
- /**
- * @dev Saves an array of AdvancedOrders as a named default.
- *
- * @param advancedOrders the AdvancedOrders to save as a default
- * @param defaultName the name of the new default
- *
- * @return _advancedOrders the AdvancedOrders saved as a default
- */
- function saveDefaultMany(
- AdvancedOrder[] memory advancedOrders,
- string memory defaultName
- ) internal returns (AdvancedOrder[] memory _advancedOrders) {
- mapping(string => AdvancedOrder[])
- storage advancedOrdersMap = _advancedOrdersMap();
- StructCopier.setAdvancedOrders(
- advancedOrdersMap[defaultName],
- advancedOrders
- );
- return advancedOrders;
- }
-
- /**
- * @dev Makes a copy of an AdvancedOrder in-memory.
- *
- * @param item the AdvancedOrder to make a copy of in-memory
- *
- * @custom:return item the copied AdvancedOrder
- */
- function copy(
- AdvancedOrder memory item
- ) internal pure returns (AdvancedOrder memory) {
- return
- AdvancedOrder({
- parameters: item.parameters.copy(),
- numerator: item.numerator,
- denominator: item.denominator,
- signature: item.signature,
- extraData: item.extraData
- });
- }
-
- /**
- * @dev Makes a copy of an array of AdvancedOrders in-memory.
- *
- * @param items the AdvancedOrders to make a copy of in-memory
- *
- * @custom:return items the copied AdvancedOrders
- */
- function copy(
- AdvancedOrder[] memory items
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory copiedItems = new AdvancedOrder[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- copiedItems[i] = copy(items[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Gets the storage position of the default AdvancedOrder map.
- *
- * @return advancedOrderMap the storage position of the default
- * AdvancedOrder map
- */
- function _advancedOrderMap()
- private
- pure
- returns (mapping(string => AdvancedOrder) storage advancedOrderMap)
- {
- bytes32 position = ADVANCED_ORDER_MAP_POSITION;
- assembly {
- advancedOrderMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default AdvancedOrder array map.
- *
- * @return advancedOrdersMap the storage position of the default
- * AdvancedOrder array map
- */
- function _advancedOrdersMap()
- private
- pure
- returns (mapping(string => AdvancedOrder[]) storage advancedOrdersMap)
- {
- bytes32 position = ADVANCED_ORDERS_MAP_POSITION;
- assembly {
- advancedOrdersMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of an AdvancedOrder's fields,
- // which modify the AdvancedOrder in-place and return it.
-
- /**
- * @dev Configures an AdvancedOrder's parameters.
- *
- * @param advancedOrder the AdvancedOrder to configure
- * @param parameters the parameters to set
- *
- * @custom:return _advancedOrder the configured AdvancedOrder
- */
- function withParameters(
- AdvancedOrder memory advancedOrder,
- OrderParameters memory parameters
- ) internal pure returns (AdvancedOrder memory) {
- advancedOrder.parameters = parameters.copy();
- return advancedOrder;
- }
-
- /**
- * @dev Configures an AdvancedOrder's numerator.
- *
- * @param advancedOrder the AdvancedOrder to configure
- * @param numerator the numerator to set
- *
- * @custom:return _advancedOrder the configured AdvancedOrder
- */
- function withNumerator(
- AdvancedOrder memory advancedOrder,
- uint120 numerator
- ) internal pure returns (AdvancedOrder memory) {
- advancedOrder.numerator = numerator;
- return advancedOrder;
- }
-
- /**
- * @dev Configures an AdvancedOrder's denominator.
- *
- * @param advancedOrder the AdvancedOrder to configure
- * @param denominator the denominator to set
- *
- * @custom:return _advancedOrder the configured AdvancedOrder
- */
- function withDenominator(
- AdvancedOrder memory advancedOrder,
- uint120 denominator
- ) internal pure returns (AdvancedOrder memory) {
- advancedOrder.denominator = denominator;
- return advancedOrder;
- }
-
- /**
- * @dev Configures an AdvancedOrder's signature.
- *
- * @param advancedOrder the AdvancedOrder to configure
- * @param signature the signature to set
- *
- * @custom:return _advancedOrder the configured AdvancedOrder
- */
- function withSignature(
- AdvancedOrder memory advancedOrder,
- bytes memory signature
- ) internal pure returns (AdvancedOrder memory) {
- advancedOrder.signature = signature;
- return advancedOrder;
- }
-
- /**
- * @dev Configures an AdvancedOrder's extra data.
- *
- * @param advancedOrder the AdvancedOrder to configure
- * @param extraData the extra data to set
- *
- * @custom:return _advancedOrder the configured AdvancedOrder
- */
- function withExtraData(
- AdvancedOrder memory advancedOrder,
- bytes memory extraData
- ) internal pure returns (AdvancedOrder memory) {
- advancedOrder.extraData = extraData;
- return advancedOrder;
- }
-
- /**
- * @dev Converts an AdvancedOrder to an Order.
- *
- * @param advancedOrder the AdvancedOrder to convert
- *
- * @return order the converted Order
- */
- function toOrder(
- AdvancedOrder memory advancedOrder
- ) internal pure returns (Order memory order) {
- order.parameters = advancedOrder.parameters.copy();
- order.signature = advancedOrder.signature;
- }
-
- /**
- * @dev Converts an AdvancedOrder[] to an Order[].
- *
- * @param advancedOrders the AdvancedOrder[] to convert
- *
- * @return the converted Order[]
- */
- function toOrders(
- AdvancedOrder[] memory advancedOrders
- ) internal pure returns (Order[] memory) {
- Order[] memory orders = new Order[](advancedOrders.length);
-
- for (uint256 i; i < advancedOrders.length; ++i) {
- orders[i] = toOrder(advancedOrders[i]);
- }
- return orders;
- }
-
- /**
- * @dev Converts an AdvancedOrder to a BasicOrderParameters.
- *
- * @param advancedOrder the AdvancedOrder to convert
- * @param basicOrderType the BasicOrderType to convert to
- *
- * @return basicOrderParameters the BasicOrderParameters
- */
- function toBasicOrderParameters(
- AdvancedOrder memory advancedOrder,
- BasicOrderType basicOrderType
- ) internal pure returns (BasicOrderParameters memory basicOrderParameters) {
- basicOrderParameters.considerationToken = advancedOrder
- .parameters
- .consideration[0]
- .token;
- basicOrderParameters.considerationIdentifier = advancedOrder
- .parameters
- .consideration[0]
- .identifierOrCriteria;
- basicOrderParameters.considerationAmount = advancedOrder
- .parameters
- .consideration[0]
- .endAmount;
- basicOrderParameters.offerer = payable(
- advancedOrder.parameters.offerer
- );
- basicOrderParameters.zone = advancedOrder.parameters.zone;
- basicOrderParameters.offerToken = advancedOrder
- .parameters
- .offer[0]
- .token;
- basicOrderParameters.offerIdentifier = advancedOrder
- .parameters
- .offer[0]
- .identifierOrCriteria;
- basicOrderParameters.offerAmount = advancedOrder
- .parameters
- .offer[0]
- .endAmount;
- basicOrderParameters.basicOrderType = basicOrderType;
- basicOrderParameters.startTime = advancedOrder.parameters.startTime;
- basicOrderParameters.endTime = advancedOrder.parameters.endTime;
- basicOrderParameters.zoneHash = advancedOrder.parameters.zoneHash;
- basicOrderParameters.salt = advancedOrder.parameters.salt;
- basicOrderParameters.offererConduitKey = advancedOrder
- .parameters
- .conduitKey;
- basicOrderParameters.fulfillerConduitKey = advancedOrder
- .parameters
- .conduitKey;
- basicOrderParameters.totalOriginalAdditionalRecipients =
- advancedOrder.parameters.totalOriginalConsiderationItems -
- 1;
-
- AdditionalRecipient[]
- memory additionalRecipients = new AdditionalRecipient[](
- advancedOrder.parameters.consideration.length - 1
- );
- for (
- uint256 i = 1;
- i < advancedOrder.parameters.consideration.length;
- i++
- ) {
- additionalRecipients[i - 1] = AdditionalRecipient({
- recipient: advancedOrder.parameters.consideration[i].recipient,
- amount: advancedOrder.parameters.consideration[i].startAmount
- });
- }
-
- basicOrderParameters.additionalRecipients = additionalRecipients;
- basicOrderParameters.signature = advancedOrder.signature;
-
- return basicOrderParameters;
- }
-
- function withCoercedAmountsForPartialFulfillment(
- AdvancedOrder memory order
- ) internal pure returns (AdvancedOrder memory) {
- OrderParameters memory orderParams = order.parameters;
- for (uint256 i = 0; i < orderParams.offer.length; ++i) {
- uint256 newStartAmount;
- uint256 newEndAmount;
- OfferItem memory item = orderParams.offer[i];
-
- if (
- item.itemType == ItemType.ERC721 ||
- item.itemType == ItemType.ERC721_WITH_CRITERIA
- ) {
- uint256 amount = uint256(order.denominator / order.numerator);
- newStartAmount = amount;
- newEndAmount = amount;
- } else {
- (
- newStartAmount,
- newEndAmount
- ) = deriveFractionCompatibleAmounts(
- item.startAmount,
- item.endAmount,
- orderParams.startTime,
- orderParams.endTime,
- order.numerator,
- order.denominator
- );
- }
-
- order.parameters.offer[i].startAmount = newStartAmount;
- order.parameters.offer[i].endAmount = newEndAmount;
- }
-
- // Adjust consideration item amounts based on the fraction
- for (uint256 i = 0; i < orderParams.consideration.length; ++i) {
- uint256 newStartAmount;
- uint256 newEndAmount;
- ConsiderationItem memory item = orderParams.consideration[i];
-
- if (
- item.itemType == ItemType.ERC721 ||
- item.itemType == ItemType.ERC721_WITH_CRITERIA
- ) {
- uint256 amount = uint256(order.denominator / order.numerator);
- newStartAmount = amount;
- newEndAmount = amount;
- } else {
- (
- newStartAmount,
- newEndAmount
- ) = deriveFractionCompatibleAmounts(
- item.startAmount,
- item.endAmount,
- orderParams.startTime,
- orderParams.endTime,
- order.numerator,
- order.denominator
- );
- }
-
- order.parameters.consideration[i].startAmount = newStartAmount;
- order.parameters.consideration[i].endAmount = newEndAmount;
- }
-
- return order;
- }
-
- function deriveFractionCompatibleAmounts(
- uint256 originalStartAmount,
- uint256 originalEndAmount,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) internal pure returns (uint256 newStartAmount, uint256 newEndAmount) {
- if (
- startTime >= endTime ||
- numerator > denominator ||
- numerator == 0 ||
- denominator == 0 ||
- (originalStartAmount == 0 && originalEndAmount == 0)
- ) {
- revert(
- "AdvancedOrderLib: bad inputs to deriveFractionCompatibleAmounts"
- );
- }
-
- bool ensureNotHuge = originalStartAmount != originalEndAmount;
-
- newStartAmount = minimalChange(
- originalStartAmount,
- numerator,
- denominator,
- ensureNotHuge
- );
-
- newEndAmount = minimalChange(
- originalEndAmount,
- numerator,
- denominator,
- ensureNotHuge
- );
-
- if (newStartAmount == 0 && newEndAmount == 0) {
- revert("AdvancedOrderLib: derived amount will always be zero");
- }
- }
-
- // Function to find the minimal change in the value so that it results in a
- // new value with no remainder when the numerator and the denominator are
- // applied.
- function minimalChange(
- uint256 value,
- uint256 numerator,
- uint256 denominator,
- bool ensureNotHuge
- ) public pure returns (uint256 newValue) {
- require(denominator != 0, "AdvancedOrderLib: no denominator supplied.");
-
- if (ensureNotHuge) {
- value %= type(uint208).max;
- }
-
- uint256 remainder = (value * numerator) % denominator;
-
- uint256 diffToNextMultiple = denominator - remainder;
- uint256 diffToPrevMultiple = remainder;
-
- newValue = 0;
- if (diffToNextMultiple > diffToPrevMultiple) {
- newValue = value - (diffToPrevMultiple / numerator);
- }
-
- if (newValue == 0) {
- newValue = value + (diffToNextMultiple / numerator);
- }
-
- if ((newValue * numerator) % denominator != 0) {
- revert("AdvancedOrderLib: minimal change failed");
- }
- }
-
- /**
- * @dev Get the orderHashes of an array of orders.
- */
- function getOrderHashes(
- AdvancedOrder[] memory orders,
- address seaport
- ) internal view returns (bytes32[] memory) {
- SeaportInterface seaportInterface = SeaportInterface(seaport);
-
- bytes32[] memory orderHashes = new bytes32[](orders.length);
-
- // Array of (contract offerer, currentNonce)
- ContractNonceDetails[] memory detailsArray = new ContractNonceDetails[](
- orders.length
- );
-
- for (uint256 i = 0; i < orders.length; ++i) {
- OrderParameters memory order = orders[i].parameters;
- bytes32 orderHash;
- if (
- order.orderType == OrderType.CONTRACT &&
- _hasValidTime(order.startTime, order.endTime)
- ) {
- bool noneYetLocated = false;
- uint256 j = 0;
- uint256 currentNonce;
- for (; j < detailsArray.length; ++j) {
- ContractNonceDetails memory details = detailsArray[j];
- if (!details.set) {
- noneYetLocated = true;
- break;
- } else if (details.offerer == order.offerer) {
- currentNonce = ++(details.currentNonce);
- break;
- }
- }
-
- if (noneYetLocated) {
- currentNonce = seaportInterface.getContractOffererNonce(
- order.offerer
- );
-
- detailsArray[j] = ContractNonceDetails({
- set: true,
- offerer: order.offerer,
- currentNonce: currentNonce
- });
- }
-
- uint256 shiftedOfferer = uint256(uint160(order.offerer)) << 96;
-
- orderHash = bytes32(shiftedOfferer ^ currentNonce);
- } else {
- orderHash = getTipNeutralizedOrderHash(
- orders[i],
- seaportInterface
- );
- }
-
- orderHashes[i] = orderHash;
- }
-
- return orderHashes;
- }
-
- function _hasValidTime(
- uint256 startTime,
- uint256 endTime
- ) internal view returns (bool) {
- return block.timestamp >= startTime && block.timestamp < endTime;
- }
-
- /**
- * @dev Get the orderHash for an AdvancedOrders and return the orderHash.
- * This function can be treated as a wrapper around Seaport's
- * getOrderHash function. It is used to get the orderHash of an
- * AdvancedOrder that has a tip added onto it. Calling it on an
- * AdvancedOrder that does not have a tip will return the same
- * orderHash as calling Seaport's getOrderHash function directly.
- * Seaport handles tips gracefully inside of the top level fulfill and
- * match functions, but since we're adding tips early in the fuzz test
- * lifecycle, it's necessary to flip them back and forth when we need
- * to pass order components into getOrderHash. Note: they're two
- * different orders, so e.g. cancelling or validating order with a tip
- * on it is not the same as cancelling the order without a tip on it.
- */
- function getTipNeutralizedOrderHash(
- AdvancedOrder memory order,
- SeaportInterface seaport
- ) internal view returns (bytes32 orderHash) {
- // Get the counter of the order offerer.
- uint256 counter = seaport.getCounter(order.parameters.offerer);
-
- return getTipNeutralizedOrderHash(order, seaport, counter);
- }
-
- function getTipNeutralizedOrderHash(
- AdvancedOrder memory order,
- SeaportInterface seaport,
- uint256 counter
- ) internal view returns (bytes32 orderHash) {
- // Get the OrderComponents from the OrderParameters.
- OrderComponents memory components = (
- order.parameters.toOrderComponents(counter)
- );
-
- // Get the length of the consideration array (which might have
- // additional consideration items set as tips).
- uint256 lengthWithTips = components.consideration.length;
-
- // Get the length of the consideration array without tips, which is
- // stored in the totalOriginalConsiderationItems field.
- uint256 lengthSansTips = (
- order.parameters.totalOriginalConsiderationItems
- );
-
- // Get a reference to the consideration array.
- ConsiderationItem[] memory considerationSansTips = (
- components.consideration
- );
-
- // Set proper length of the considerationSansTips array.
- assembly {
- mstore(considerationSansTips, lengthSansTips)
- }
-
- // Get the orderHash using the tweaked OrderComponents.
- orderHash = seaport.getOrderHash(components);
-
- // Restore the length of the considerationSansTips array.
- assembly {
- mstore(considerationSansTips, lengthWithTips)
- }
- }
-
- function getOrderDetails(
- AdvancedOrder[] memory advancedOrders,
- CriteriaResolver[] memory criteriaResolvers,
- bytes32[] memory orderHashes,
- UnavailableReason[] memory unavailableReasons
- ) internal view returns (OrderDetails[] memory) {
- OrderDetails[] memory orderDetails = new OrderDetails[](
- advancedOrders.length
- );
-
- for (uint256 i = 0; i < advancedOrders.length; i++) {
- orderDetails[i] = toOrderDetails(
- advancedOrders[i],
- i,
- criteriaResolvers,
- orderHashes[i],
- unavailableReasons[i]
- );
- }
-
- return orderDetails;
- }
-
- function toOrderDetails(
- AdvancedOrder memory order,
- uint256 orderIndex,
- CriteriaResolver[] memory resolvers,
- bytes32 orderHash,
- UnavailableReason unavailableReason
- ) internal view returns (OrderDetails memory) {
- (SpentItem[] memory offer, ReceivedItem[] memory consideration) = order
- .parameters
- .getSpentAndReceivedItems(
- order.numerator,
- order.denominator,
- orderIndex,
- resolvers
- );
-
- return
- OrderDetails({
- offerer: order.parameters.offerer,
- conduitKey: order.parameters.conduitKey,
- offer: offer,
- consideration: consideration,
- isContract: order.parameters.orderType == OrderType.CONTRACT,
- orderHash: orderHash,
- unavailableReason: unavailableReason
- });
- }
-}
diff --git a/contracts/helpers/sol/lib/ArrayLib.sol b/contracts/helpers/sol/lib/ArrayLib.sol
deleted file mode 100644
index 8c74c1fa8..000000000
--- a/contracts/helpers/sol/lib/ArrayLib.sol
+++ /dev/null
@@ -1,44 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-/**
- * @title ArrayLib
- * @author James Wenzel (emo.eth)
- * @notice ArrayLib is a library for managing arrays.
- */
-library ArrayLib {
- /**
- * @dev Sets the values of an array.
- *
- * @param array the array to set
- * @param values the values to set
- */
- function setBytes32s(
- bytes32[] storage array,
- bytes32[] memory values
- ) internal {
- while (array.length > 0) {
- array.pop();
- }
- for (uint256 i = 0; i < values.length; i++) {
- array.push(values[i]);
- }
- }
-
- /**
- * @dev Makes a copy of an array.
- *
- * @param array the array to copy
- *
- * @custom:return copiedArray the copied array
- */
- function copy(
- bytes32[] memory array
- ) internal pure returns (bytes32[] memory) {
- bytes32[] memory copiedArray = new bytes32[](array.length);
- for (uint256 i = 0; i < array.length; i++) {
- copiedArray[i] = array[i];
- }
- return copiedArray;
- }
-}
diff --git a/contracts/helpers/sol/lib/BasicOrderParametersLib.sol b/contracts/helpers/sol/lib/BasicOrderParametersLib.sol
deleted file mode 100644
index 4436a3a13..000000000
--- a/contracts/helpers/sol/lib/BasicOrderParametersLib.sol
+++ /dev/null
@@ -1,632 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- AdditionalRecipient,
- BasicOrderParameters,
- OrderParameters
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { BasicOrderType } from "../../../lib/ConsiderationEnums.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-import { AdditionalRecipientLib } from "./AdditionalRecipientLib.sol";
-
-/**
- * @title BasicOrderParametersLib
- * @author James Wenzel (emo.eth)
- * @notice BasicOrderParametersLib is a library for managing
- * BasicOrderParameters structs and arrays. It allows chaining of
- * functions to make struct creation more readable.
- */
-library BasicOrderParametersLib {
- using BasicOrderParametersLib for BasicOrderParameters;
- using AdditionalRecipientLib for AdditionalRecipient[];
-
- bytes32 private constant BASIC_ORDER_PARAMETERS_MAP_POSITION =
- keccak256("seaport.BasicOrderParametersDefaults");
- bytes32 private constant BASIC_ORDER_PARAMETERS_ARRAY_MAP_POSITION =
- keccak256("seaport.BasicOrderParametersArrayDefaults");
- bytes32 private constant EMPTY_BASIC_ORDER_PARAMETERS =
- keccak256(
- abi.encode(
- BasicOrderParameters({
- considerationToken: address(0),
- considerationIdentifier: 0,
- considerationAmount: 0,
- offerer: payable(address(0)),
- zone: address(0),
- offerToken: address(0),
- offerIdentifier: 0,
- offerAmount: 0,
- basicOrderType: BasicOrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- offererConduitKey: bytes32(0),
- fulfillerConduitKey: bytes32(0),
- totalOriginalAdditionalRecipients: 0,
- additionalRecipients: new AdditionalRecipient[](0),
- signature: ""
- })
- )
- );
-
- /**
- * @dev Clears a default BasicOrderParameters from storage.
- *
- * @param basicParameters the BasicOrderParameters to clear
- */
- function clear(BasicOrderParameters storage basicParameters) internal {
- // uninitialized pointers take up no new memory (versus one word for initializing length-0)
- AdditionalRecipient[] memory additionalRecipients;
-
- basicParameters.considerationToken = address(0);
- basicParameters.considerationIdentifier = 0;
- basicParameters.considerationAmount = 0;
- basicParameters.offerer = payable(address(0));
- basicParameters.zone = address(0);
- basicParameters.offerToken = address(0);
- basicParameters.offerIdentifier = 0;
- basicParameters.offerAmount = 0;
- basicParameters.basicOrderType = BasicOrderType(0);
- basicParameters.startTime = 0;
- basicParameters.endTime = 0;
- basicParameters.zoneHash = bytes32(0);
- basicParameters.salt = 0;
- basicParameters.offererConduitKey = bytes32(0);
- basicParameters.fulfillerConduitKey = bytes32(0);
- basicParameters.totalOriginalAdditionalRecipients = 0;
- StructCopier.setAdditionalRecipients(
- basicParameters.additionalRecipients,
- additionalRecipients
- );
- basicParameters.signature = new bytes(0);
- }
-
- /**
- * @dev Clears an array of BasicOrderParameters from storage.
- *
- * @param basicParametersArray the name of the default to clear
- */
- function clear(
- BasicOrderParameters[] storage basicParametersArray
- ) internal {
- while (basicParametersArray.length > 0) {
- basicParametersArray[basicParametersArray.length - 1].clear();
- basicParametersArray.pop();
- }
- }
-
- /**
- * @dev Clears a default BasicOrderParameters from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => BasicOrderParameters)
- storage orderParametersMap = _orderParametersMap();
- BasicOrderParameters storage basicParameters = orderParametersMap[
- defaultName
- ];
- basicParameters.clear();
- }
-
- /**
- * @dev Creates an empty BasicOrderParameters.
- *
- * @return item the default BasicOrderParameters
- */
- function empty() internal pure returns (BasicOrderParameters memory item) {
- AdditionalRecipient[] memory additionalRecipients;
- item = BasicOrderParameters({
- considerationToken: address(0),
- considerationIdentifier: 0,
- considerationAmount: 0,
- offerer: payable(address(0)),
- zone: address(0),
- offerToken: address(0),
- offerIdentifier: 0,
- offerAmount: 0,
- basicOrderType: BasicOrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- offererConduitKey: bytes32(0),
- fulfillerConduitKey: bytes32(0),
- totalOriginalAdditionalRecipients: 0,
- additionalRecipients: additionalRecipients,
- signature: new bytes(0)
- });
- }
-
- /**
- * @dev Gets a default BasicOrderParameters from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the selected default BasicOrderParameters
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (BasicOrderParameters memory item) {
- mapping(string => BasicOrderParameters)
- storage orderParametersMap = _orderParametersMap();
- item = orderParametersMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_BASIC_ORDER_PARAMETERS) {
- revert("Empty BasicOrderParameters selected.");
- }
- }
-
- /**
- * @dev Gets a default BasicOrderParameters array from storage.
- *
- * @param defaultName the name of the default array for retrieval
- *
- * @return items the selected default BasicOrderParameters array
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (BasicOrderParameters[] memory items) {
- mapping(string => BasicOrderParameters[])
- storage orderParametersArrayMap = _orderParametersArrayMap();
- items = orderParametersArrayMap[defaultName];
-
- if (items.length == 0) {
- revert("Empty BasicOrderParameters array selected.");
- }
- }
-
- /**
- * @dev Saves a BasicOrderParameters as a named default.
- *
- * @param orderParameters the BasicOrderParameters to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _orderParameters the saved BasicOrderParameters
- */
- function saveDefault(
- BasicOrderParameters memory orderParameters,
- string memory defaultName
- ) internal returns (BasicOrderParameters memory _orderParameters) {
- mapping(string => BasicOrderParameters)
- storage orderParametersMap = _orderParametersMap();
- BasicOrderParameters storage destination = orderParametersMap[
- defaultName
- ];
- StructCopier.setBasicOrderParameters(destination, orderParameters);
- return orderParameters;
- }
-
- /**
- * @dev Saves an BasicOrderParameters array as a named default.
- *
- * @param orderParameters the BasicOrderParameters array to save as a default
- * @param defaultName the name of the default array for retrieval
- *
- * @return _orderParameters the saved BasicOrderParameters array
- */
- function saveDefaultMany(
- BasicOrderParameters[] memory orderParameters,
- string memory defaultName
- ) internal returns (BasicOrderParameters[] memory _orderParameters) {
- mapping(string => BasicOrderParameters[])
- storage orderParametersArrayMap = _orderParametersArrayMap();
- BasicOrderParameters[] storage destination = orderParametersArrayMap[
- defaultName
- ];
- StructCopier.setBasicOrderParameters(destination, orderParameters);
- return orderParameters;
- }
-
- /**
- * @dev Makes a copy of an BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to make a copy of in-memory
- *
- * @return copy the copied BasicOrderParameters
- */
- function copy(
- BasicOrderParameters memory item
- ) internal pure returns (BasicOrderParameters memory) {
- return
- BasicOrderParameters({
- considerationToken: item.considerationToken,
- considerationIdentifier: item.considerationIdentifier,
- considerationAmount: item.considerationAmount,
- offerer: item.offerer,
- zone: item.zone,
- offerToken: item.offerToken,
- offerIdentifier: item.offerIdentifier,
- offerAmount: item.offerAmount,
- basicOrderType: item.basicOrderType,
- startTime: item.startTime,
- endTime: item.endTime,
- zoneHash: item.zoneHash,
- salt: item.salt,
- offererConduitKey: item.offererConduitKey,
- fulfillerConduitKey: item.fulfillerConduitKey,
- totalOriginalAdditionalRecipients: item
- .totalOriginalAdditionalRecipients,
- additionalRecipients: item.additionalRecipients.copy(),
- signature: item.signature
- });
- }
-
- /**
- * @dev Gets the storage position of the default BasicOrderParameters map.
- *
- * @return orderParametersMap the storage position of the default
- * BasicOrderParameters map
- */
- function _orderParametersMap()
- private
- pure
- returns (
- mapping(string => BasicOrderParameters) storage orderParametersMap
- )
- {
- bytes32 position = BASIC_ORDER_PARAMETERS_MAP_POSITION;
- assembly {
- orderParametersMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default BasicOrderParameters array
- * map.
- *
- * @return orderParametersArrayMap the storage position of the default
- * BasicOrderParameters array map
- */
- function _orderParametersArrayMap()
- private
- pure
- returns (
- mapping(string => BasicOrderParameters[])
- storage orderParametersArrayMap
- )
- {
- bytes32 position = BASIC_ORDER_PARAMETERS_ARRAY_MAP_POSITION;
- assembly {
- orderParametersArrayMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of an in-memory
- // BasicOrderParameters's fields, which modify the BasicOrderParameters
- // struct in-memory and return it.
-
- /**
- * @dev Sets the considerationToken field of a BasicOrderParameters
- * in-memory.
- *
- * @param item the BasicOrderParameters to set the considerationToken field
- * of in-memory.
- * @param value the value to set the considerationToken field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withConsiderationToken(
- BasicOrderParameters memory item,
- address value
- ) internal pure returns (BasicOrderParameters memory) {
- item.considerationToken = value;
- return item;
- }
-
- /**
- * @dev Sets the considerationIdentifier field of a BasicOrderParameters
- * in-memory.
- *
- * @param item the BasicOrderParameters to set the considerationIdentifier
- * field of in-memory.
- * @param value the value to set the considerationIdentifier field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withConsiderationIdentifier(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.considerationIdentifier = value;
- return item;
- }
-
- /**
- * @dev Sets the considerationAmount field of a BasicOrderParameters
- * in-memory.
- *
- * @param item the BasicOrderParameters to set the considerationAmount field
- * of in-memory.
- * @param value the value to set the considerationAmount field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withConsiderationAmount(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.considerationAmount = value;
- return item;
- }
-
- /**
- * @dev Sets the offerer field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the offerer field of
- * in-memory.
- * @param value the value to set the offerer field of the BasicOrderParameters
- * to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withOfferer(
- BasicOrderParameters memory item,
- address value
- ) internal pure returns (BasicOrderParameters memory) {
- item.offerer = payable(value);
- return item;
- }
-
- /**
- * @dev Sets the zone field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the zone field of
- * in-memory.
- * @param value the value to set the zone field of the BasicOrderParameters
- * to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withZone(
- BasicOrderParameters memory item,
- address value
- ) internal pure returns (BasicOrderParameters memory) {
- item.zone = value;
- return item;
- }
-
- /**
- * @dev Sets the offerToken field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the offerToken field of
- * in-memory.
- * @param value the value to set the offerToken field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withOfferToken(
- BasicOrderParameters memory item,
- address value
- ) internal pure returns (BasicOrderParameters memory) {
- item.offerToken = value;
- return item;
- }
-
- /**
- * @dev Sets the offerIdentifier field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the offerIdentifier field of
- * in-memory.
- * @param value the value to set the offerIdentifier field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withOfferIdentifier(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.offerIdentifier = value;
- return item;
- }
-
- /**
- * @dev Sets the offerAmount field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the offerAmount field of
- * in-memory.
- * @param value the value to set the offerAmount field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withOfferAmount(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.offerAmount = value;
- return item;
- }
-
- /**
- * @dev Sets the basicOrderType field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the basicOrderType field of
- * in-memory.
- * @param value the value to set the basicOrderType field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withBasicOrderType(
- BasicOrderParameters memory item,
- BasicOrderType value
- ) internal pure returns (BasicOrderParameters memory) {
- item.basicOrderType = value;
- return item;
- }
-
- /**
- * @dev Sets the startTime field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the startTime field of
- * in-memory.
- * @param value the value to set the startTime field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withStartTime(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.startTime = value;
- return item;
- }
-
- /**
- * @dev Sets the endTime field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the endTime field of
- * in-memory.
- * @param value the value to set the endTime field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withEndTime(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.endTime = value;
- return item;
- }
-
- /**
- * @dev Sets the zoneHash field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the zoneHash field of
- * in-memory.
- * @param value the value to set the zoneHash field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withZoneHash(
- BasicOrderParameters memory item,
- bytes32 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.zoneHash = value;
- return item;
- }
-
- /**
- * @dev Sets the salt field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the salt field of
- * in-memory.
- * @param value the value to set the salt field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withSalt(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.salt = value;
- return item;
- }
-
- /**
- * @dev Sets the offererConduitKey field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the offererConduitKey field of
- * in-memory.
- * @param value the value to set the offererConduitKey field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withOffererConduitKey(
- BasicOrderParameters memory item,
- bytes32 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.offererConduitKey = value;
- return item;
- }
-
- /**
- * @dev Sets the fulfillerConduitKey field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the fulfillerConduitKey field of
- * in-memory.
- * @param value the value to set the fulfillerConduitKey field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withFulfillerConduitKey(
- BasicOrderParameters memory item,
- bytes32 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.fulfillerConduitKey = value;
- return item;
- }
-
- /**
- * @dev Sets the totalOriginalAdditionalRecipients field of a
- * BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the
- * totalOriginalAdditionalRecipients field of in-memory.
- * @param value the value to set the totalOriginalAdditionalRecipients field
- * of the BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withTotalOriginalAdditionalRecipients(
- BasicOrderParameters memory item,
- uint256 value
- ) internal pure returns (BasicOrderParameters memory) {
- item.totalOriginalAdditionalRecipients = value;
- return item;
- }
-
- /**
- * @dev Sets the additionalRecipients field of a BasicOrderParameters
- * in-memory.
- *
- * @param item the BasicOrderParameters to set the additionalRecipients
- * field of in-memory.
- * @param value the value to set the additionalRecipients field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withAdditionalRecipients(
- BasicOrderParameters memory item,
- AdditionalRecipient[] memory value
- ) internal pure returns (BasicOrderParameters memory) {
- item.additionalRecipients = value;
- return item;
- }
-
- /**
- * @dev Sets the signature field of a BasicOrderParameters in-memory.
- *
- * @param item the BasicOrderParameters to set the signature field of
- * in-memory.
- * @param value the value to set the signature field of the
- * BasicOrderParameters to set in-memory.
- *
- * @custom:return item the modified BasicOrderParameters
- */
- function withSignature(
- BasicOrderParameters memory item,
- bytes memory value
- ) internal pure returns (BasicOrderParameters memory) {
- item.signature = value;
- return item;
- }
-}
diff --git a/contracts/helpers/sol/lib/ConsiderationItemLib.sol b/contracts/helpers/sol/lib/ConsiderationItemLib.sol
deleted file mode 100644
index 5f08dc4bd..000000000
--- a/contracts/helpers/sol/lib/ConsiderationItemLib.sol
+++ /dev/null
@@ -1,444 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- ConsiderationItem,
- OfferItem,
- ReceivedItem,
- SpentItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { ItemType } from "../../../lib/ConsiderationEnums.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title ConsiderationItemLib
- * @author James Wenzel (emo.eth)
- * @notice ConsiderationItemLib is a library for managing ConsiderationItem
- * structs and arrays. It allows chaining of functions to make
- * struct creation more readable.
- */
-library ConsiderationItemLib {
- bytes32 private constant CONSIDERATION_ITEM_MAP_POSITION =
- keccak256("seaport.ConsiderationItemDefaults");
- bytes32 private constant CONSIDERATION_ITEMS_MAP_POSITION =
- keccak256("seaport.ConsiderationItemsDefaults");
- bytes32 private constant EMPTY_CONSIDERATION_ITEM =
- keccak256(
- abi.encode(
- ConsiderationItem({
- itemType: ItemType(0),
- token: address(0),
- identifierOrCriteria: 0,
- startAmount: 0,
- endAmount: 0,
- recipient: payable(address(0))
- })
- )
- );
-
- /**
- * @dev Clears a ConsiderationItem from storage.
- *
- * @param item the ConsiderationItem to clear.
- */
- function _clear(ConsiderationItem storage item) internal {
- // clear all fields
- item.itemType = ItemType.NATIVE;
- item.token = address(0);
- item.identifierOrCriteria = 0;
- item.startAmount = 0;
- item.endAmount = 0;
- item.recipient = payable(address(0));
- }
-
- /**
- * @dev Clears a named default ConsiderationItem from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => ConsiderationItem)
- storage considerationItemMap = _considerationItemMap();
- ConsiderationItem storage item = considerationItemMap[defaultName];
- _clear(item);
- }
-
- /**
- * @dev Clears an array of ConsiderationItems from storage.
- *
- * @param defaultsName the name of the array to clear
- */
- function clearMany(string memory defaultsName) internal {
- mapping(string => ConsiderationItem[])
- storage considerationItemsMap = _considerationItemsMap();
- ConsiderationItem[] storage items = considerationItemsMap[defaultsName];
- while (items.length > 0) {
- _clear(items[items.length - 1]);
- items.pop();
- }
- }
-
- /**
- * @dev Gets a default ConsiderationItem from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the ConsiderationItem retrieved from storage
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (ConsiderationItem memory item) {
- mapping(string => ConsiderationItem)
- storage considerationItemMap = _considerationItemMap();
- item = considerationItemMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_CONSIDERATION_ITEM) {
- revert("Empty ConsiderationItem selected.");
- }
- }
-
- /**
- * @dev Gets an array of default ConsiderationItems from storage.
- *
- * @param defaultsName the name of the array for retrieval
- *
- * @return items the array of ConsiderationItems retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultsName
- ) internal view returns (ConsiderationItem[] memory items) {
- mapping(string => ConsiderationItem[])
- storage considerationItemsMap = _considerationItemsMap();
- items = considerationItemsMap[defaultsName];
-
- if (items.length == 0) {
- revert("Empty ConsiderationItem array selected.");
- }
- }
-
- /**
- * @dev Creates an empty ConsiderationItem.
- *
- * @custom:return considerationItemMap the storage location of the default
- * ConsiderationItem map
- */
- function empty() internal pure returns (ConsiderationItem memory) {
- return
- ConsiderationItem({
- itemType: ItemType(0),
- token: address(0),
- identifierOrCriteria: 0,
- startAmount: 0,
- endAmount: 0,
- recipient: payable(address(0))
- });
- }
-
- /**
- * @dev Saves a ConsiderationItem as a named default.
- *
- * @param considerationItem the ConsiderationItem to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _considerationItem the saved ConsiderationItem
- */
- function saveDefault(
- ConsiderationItem memory considerationItem,
- string memory defaultName
- ) internal returns (ConsiderationItem memory _considerationItem) {
- mapping(string => ConsiderationItem)
- storage considerationItemMap = _considerationItemMap();
- considerationItemMap[defaultName] = considerationItem;
- return considerationItem;
- }
-
- /**
- * @dev Saves an array of ConsiderationItems as a named default.
- *
- * @param considerationItems the array of ConsiderationItems to save as a
- * default
- * @param defaultsName the name of the default array for retrieval
- *
- * @return _considerationItems the saved array of ConsiderationItems
- */
- function saveDefaultMany(
- ConsiderationItem[] memory considerationItems,
- string memory defaultsName
- ) internal returns (ConsiderationItem[] memory _considerationItems) {
- mapping(string => ConsiderationItem[])
- storage considerationItemsMap = _considerationItemsMap();
- ConsiderationItem[] storage items = considerationItemsMap[defaultsName];
- clearMany(defaultsName);
- StructCopier.setConsiderationItems(items, considerationItems);
- return considerationItems;
- }
-
- /**
- * @dev Makes a copy of an ConsiderationItem in-memory.
- *
- * @param item the ConsiderationItem to make a copy of in-memory
- *
- * @custom:return copy the copy of the ConsiderationItem
- */
- function copy(
- ConsiderationItem memory item
- ) internal pure returns (ConsiderationItem memory) {
- return
- ConsiderationItem({
- itemType: item.itemType,
- token: item.token,
- identifierOrCriteria: item.identifierOrCriteria,
- startAmount: item.startAmount,
- endAmount: item.endAmount,
- recipient: item.recipient
- });
- }
-
- /**
- * @dev Makes a copy of an array of ConsiderationItems in-memory.
- *
- * @param items the array of ConsiderationItems to make a copy of in-memory
- *
- * @custom:return copy the copy of the array of ConsiderationItems
- */
- function copy(
- ConsiderationItem[] memory items
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory copies = new ConsiderationItem[](
- items.length
- );
- for (uint256 i = 0; i < items.length; i++) {
- copies[i] = ConsiderationItem({
- itemType: items[i].itemType,
- token: items[i].token,
- identifierOrCriteria: items[i].identifierOrCriteria,
- startAmount: items[i].startAmount,
- endAmount: items[i].endAmount,
- recipient: items[i].recipient
- });
- }
- return copies;
- }
-
- /**
- * @dev Gets the storage position of the default ConsiderationItem map.
- *
- * @custom:return considerationItemMap the storage location of the default
- * ConsiderationItem map
- */
- function _considerationItemMap()
- private
- pure
- returns (
- mapping(string => ConsiderationItem) storage considerationItemMap
- )
- {
- bytes32 position = CONSIDERATION_ITEM_MAP_POSITION;
- assembly {
- considerationItemMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default array of ConsiderationItems
- * map.
- *
- * @custom:return considerationItemsMap the storage location of the default
- * array of ConsiderationItems map
- */
- function _considerationItemsMap()
- private
- pure
- returns (
- mapping(string => ConsiderationItem[]) storage considerationItemsMap
- )
- {
- bytes32 position = CONSIDERATION_ITEMS_MAP_POSITION;
- assembly {
- considerationItemsMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of an ConsiderationItem's
- // fields, which modify the ConsiderationItem in-place and return it.
-
- /**
- * @dev Sets the item type.
- *
- * @param item the ConsiderationItem to modify
- * @param itemType the item type to set
- *
- * @custom:return item the modified ConsiderationItem
- */
- function withItemType(
- ConsiderationItem memory item,
- ItemType itemType
- ) internal pure returns (ConsiderationItem memory) {
- item.itemType = itemType;
- return item;
- }
-
- /**
- * @dev Sets the token address.
- *
- * @param item the ConsiderationItem to modify
- * @param token the token address to set
- *
- * @custom:return item the modified ConsiderationItem
- */
- function withToken(
- ConsiderationItem memory item,
- address token
- ) internal pure returns (ConsiderationItem memory) {
- item.token = token;
- return item;
- }
-
- /**
- * @dev Sets the identifier or criteria.
- *
- * @param item the ConsiderationItem to modify
- * @param identifierOrCriteria the identifier or criteria to set
- *
- * @custom:return item the modified ConsiderationItem
- */
- function withIdentifierOrCriteria(
- ConsiderationItem memory item,
- uint256 identifierOrCriteria
- ) internal pure returns (ConsiderationItem memory) {
- item.identifierOrCriteria = identifierOrCriteria;
- return item;
- }
-
- /**
- * @dev Sets the start amount.
- *
- * @param item the ConsiderationItem to modify
- * @param startAmount the start amount to set
- *
- * @custom:return item the modified ConsiderationItem
- */
- function withStartAmount(
- ConsiderationItem memory item,
- uint256 startAmount
- ) internal pure returns (ConsiderationItem memory) {
- item.startAmount = startAmount;
- return item;
- }
-
- /**
- * @dev Sets the end amount.
- *
- * @param item the ConsiderationItem to modify
- * @param endAmount the end amount to set
- *
- * @custom:return item the modified ConsiderationItem
- */
- function withEndAmount(
- ConsiderationItem memory item,
- uint256 endAmount
- ) internal pure returns (ConsiderationItem memory) {
- item.endAmount = endAmount;
- return item;
- }
-
- /**
- * @dev Sets the startAmount and endAmount of an ConsiderationItem.
- *
- * @param item the ConsiderationItem to modify
- * @param amount the amount to set for the start and end amounts
- *
- * @custom:return item the modified ConsiderationItem
- */
- function withAmount(
- ConsiderationItem memory item,
- uint256 amount
- ) internal pure returns (ConsiderationItem memory) {
- item.startAmount = amount;
- item.endAmount = amount;
- return item;
- }
-
- /**
- * @dev Sets the recipient.
- *
- * @param item the ConsiderationItem to modify
- * @param recipient the recipient to set
- *
- * @custom:return item the modified ConsiderationItem
- */
- function withRecipient(
- ConsiderationItem memory item,
- address recipient
- ) internal pure returns (ConsiderationItem memory) {
- item.recipient = payable(recipient);
- return item;
- }
-
- /**
- * @dev Converts an ConsiderationItem to a ReceivedItem.
- *
- * @param item the ConsiderationItem to convert
- *
- * @custom:return receivedItem the converted ReceivedItem
- */
- function toReceivedItem(
- ConsiderationItem memory item
- ) internal pure returns (ReceivedItem memory) {
- return
- ReceivedItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifierOrCriteria,
- amount: item.startAmount,
- recipient: item.recipient
- });
- }
-
- function toReceivedItemArray(
- ConsiderationItem[] memory items
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory receivedItems = new ReceivedItem[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- receivedItems[i] = toReceivedItem(items[i]);
- }
- return receivedItems;
- }
-
- function toSpentItem(
- ConsiderationItem memory item
- ) internal pure returns (SpentItem memory) {
- return
- SpentItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifierOrCriteria,
- amount: item.startAmount
- });
- }
-
- function toSpentItemArray(
- ConsiderationItem[] memory items
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory spentItems = new SpentItem[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- spentItems[i] = toSpentItem(items[i]);
- }
- return spentItems;
- }
-
- function toOfferItem(
- ConsiderationItem memory item
- ) internal pure returns (OfferItem memory) {
- return
- OfferItem({
- itemType: item.itemType,
- token: item.token,
- identifierOrCriteria: item.identifierOrCriteria,
- startAmount: item.startAmount,
- endAmount: item.endAmount
- });
- }
-}
diff --git a/contracts/helpers/sol/lib/CriteriaResolverLib.sol b/contracts/helpers/sol/lib/CriteriaResolverLib.sol
deleted file mode 100644
index 31cacce5a..000000000
--- a/contracts/helpers/sol/lib/CriteriaResolverLib.sol
+++ /dev/null
@@ -1,342 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { CriteriaResolver } from "../../../lib/ConsiderationStructs.sol";
-
-import { Side } from "../../../lib/ConsiderationEnums.sol";
-
-import { ArrayLib } from "./ArrayLib.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title CriteriaResolverLib
- * @author James Wenzel (emo.eth)
- * @notice CriteriaResolverLib is a library for managing CriteriaResolver
- * structs and arrays. It allows chaining of functions to make
- * struct creation more readable.
- */
-library CriteriaResolverLib {
- bytes32 private constant CRITERIA_RESOLVER_MAP_POSITION =
- keccak256("seaport.CriteriaResolverDefaults");
- bytes32 private constant CRITERIA_RESOLVERS_MAP_POSITION =
- keccak256("seaport.CriteriaResolversDefaults");
- bytes32 private constant EMPTY_CRITERIA_RESOLVER =
- keccak256(
- abi.encode(
- CriteriaResolver({
- orderIndex: 0,
- side: Side(0),
- index: 0,
- identifier: 0,
- criteriaProof: new bytes32[](0)
- })
- )
- );
-
- using ArrayLib for bytes32[];
-
- /**
- * @dev Clears a default CriteriaResolver from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => CriteriaResolver)
- storage criteriaResolverMap = _criteriaResolverMap();
- CriteriaResolver storage resolver = criteriaResolverMap[defaultName];
- // clear all fields
- clear(resolver);
- }
-
- /**
- * @dev Clears all fields on a CriteriaResolver.
- *
- * @param resolver the CriteriaResolver to clear
- */
- function clear(CriteriaResolver storage resolver) internal {
- bytes32[] memory criteriaProof;
- resolver.orderIndex = 0;
- resolver.side = Side(0);
- resolver.index = 0;
- resolver.identifier = 0;
- ArrayLib.setBytes32s(resolver.criteriaProof, criteriaProof);
- }
-
- /**
- * @dev Clears an array of CriteriaResolvers from storage.
- *
- * @param resolvers the CriteriaResolvers to clear
- */
- function clear(CriteriaResolver[] storage resolvers) internal {
- while (resolvers.length > 0) {
- clear(resolvers[resolvers.length - 1]);
- resolvers.pop();
- }
- }
-
- /**
- * @dev Gets a default CriteriaResolver from storage.
- *
- * @param item the name of the default for retrieval
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (CriteriaResolver memory item) {
- mapping(string => CriteriaResolver)
- storage criteriaResolverMap = _criteriaResolverMap();
- item = criteriaResolverMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_CRITERIA_RESOLVER) {
- revert("Empty CriteriaResolver selected.");
- }
- }
-
- /**
- * @dev Gets an array of CriteriaResolvers from storage.
- *
- * @param defaultsName the name of the default array for retrieval
- *
- * @return items the CriteriaResolvers retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultsName
- ) internal view returns (CriteriaResolver[] memory items) {
- mapping(string => CriteriaResolver[])
- storage criteriaResolversMap = _criteriaResolversMap();
- items = criteriaResolversMap[defaultsName];
-
- if (items.length == 0) {
- revert("Empty CriteriaResolver array selected.");
- }
- }
-
- /**
- * @dev Saves an CriteriaResolver as a named default.
- *
- * @param criteriaResolver the CriteriaResolver to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _criteriaResolver the CriteriaResolver that was saved
- */
- function saveDefault(
- CriteriaResolver memory criteriaResolver,
- string memory defaultName
- ) internal returns (CriteriaResolver memory _criteriaResolver) {
- mapping(string => CriteriaResolver)
- storage criteriaResolverMap = _criteriaResolverMap();
- CriteriaResolver storage resolver = criteriaResolverMap[defaultName];
- resolver.orderIndex = criteriaResolver.orderIndex;
- resolver.side = criteriaResolver.side;
- resolver.index = criteriaResolver.index;
- resolver.identifier = criteriaResolver.identifier;
- ArrayLib.setBytes32s(
- resolver.criteriaProof,
- criteriaResolver.criteriaProof
- );
- return criteriaResolver;
- }
-
- /**
- * @dev Saves an array of CriteriaResolvers as a named default.
- *
- * @param criteriaResolvers the CriteriaResolvers to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _criteriaResolvers the CriteriaResolvers that were saved
- */
- function saveDefaultMany(
- CriteriaResolver[] memory criteriaResolvers,
- string memory defaultName
- ) internal returns (CriteriaResolver[] memory _criteriaResolvers) {
- mapping(string => CriteriaResolver[])
- storage criteriaResolversMap = _criteriaResolversMap();
- CriteriaResolver[] storage resolvers = criteriaResolversMap[
- defaultName
- ];
- // todo: make sure we do this elsewhere
- clear(resolvers);
- StructCopier.setCriteriaResolvers(resolvers, criteriaResolvers);
- return criteriaResolvers;
- }
-
- /**
- * @dev Makes a copy of a CriteriaResolver in-memory.
- *
- * @param resolver the CriteriaResolver to make a copy of in-memory
- *
- * @custom:return copiedItem the copied CriteriaResolver
- */
- function copy(
- CriteriaResolver memory resolver
- ) internal pure returns (CriteriaResolver memory) {
- return
- CriteriaResolver({
- orderIndex: resolver.orderIndex,
- side: resolver.side,
- index: resolver.index,
- identifier: resolver.identifier,
- criteriaProof: resolver.criteriaProof.copy()
- });
- }
-
- /**
- * @dev Makes a copy of an array of CriteriaResolvers in-memory.
- *
- * @param resolvers the CriteriaResolvers to make a copy of in-memory
- *
- * @custom:return copiedItems the copied CriteriaResolvers
- */
- function copy(
- CriteriaResolver[] memory resolvers
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory copiedItems = new CriteriaResolver[](
- resolvers.length
- );
- for (uint256 i = 0; i < resolvers.length; i++) {
- copiedItems[i] = copy(resolvers[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Creates an empty CriteriaResolver.
- *
- * @custom:return emptyResolver the empty CriteriaResolver
- */
- function empty() internal pure returns (CriteriaResolver memory) {
- bytes32[] memory proof;
- return
- CriteriaResolver({
- orderIndex: 0,
- side: Side(0),
- index: 0,
- identifier: 0,
- criteriaProof: proof
- });
- }
-
- /**
- * @dev Gets the storage position of the default CriteriaResolver map.
- *
- * @custom:return position the storage position of the default
- * CriteriaResolver map.
- *
- */
- function _criteriaResolverMap()
- private
- pure
- returns (
- mapping(string => CriteriaResolver) storage criteriaResolverMap
- )
- {
- bytes32 position = CRITERIA_RESOLVER_MAP_POSITION;
- assembly {
- criteriaResolverMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default CriteriaResolver array map.
- *
- * @custom:return position the storage position of the default
- * CriteriaResolver array map.
- *
- */
- function _criteriaResolversMap()
- private
- pure
- returns (
- mapping(string => CriteriaResolver[]) storage criteriaResolversMap
- )
- {
- bytes32 position = CRITERIA_RESOLVERS_MAP_POSITION;
- assembly {
- criteriaResolversMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of an CriteriaResolver's fields,
- // which modify the CriteriaResolver in-place and return it.
-
- /**
- * @dev Sets the orderIndex of a CriteriaResolver.
- *
- * @param resolver the CriteriaResolver to set the orderIndex of
- * @param orderIndex the orderIndex to set
- *
- * @return _resolver the CriteriaResolver with the orderIndex set
- */
- function withOrderIndex(
- CriteriaResolver memory resolver,
- uint256 orderIndex
- ) internal pure returns (CriteriaResolver memory) {
- resolver.orderIndex = orderIndex;
- return resolver;
- }
-
- /**
- * @dev Sets the side of a CriteriaResolver.
- *
- * @param resolver the CriteriaResolver to set the side of
- * @param side the side to set
- *
- * @return _resolver the CriteriaResolver with the side set
- */
- function withSide(
- CriteriaResolver memory resolver,
- Side side
- ) internal pure returns (CriteriaResolver memory) {
- resolver.side = side;
- return resolver;
- }
-
- /**
- * @dev Sets the index of a CriteriaResolver.
- *
- * @param resolver the CriteriaResolver to set the index of
- * @param index the index to set
- *
- * @return _resolver the CriteriaResolver with the index set
- */
- function withIndex(
- CriteriaResolver memory resolver,
- uint256 index
- ) internal pure returns (CriteriaResolver memory) {
- resolver.index = index;
- return resolver;
- }
-
- /**
- * @dev Sets the identifier of a CriteriaResolver.
- *
- * @param resolver the CriteriaResolver to set the identifier of
- * @param identifier the identifier to set
- *
- * @return _resolver the CriteriaResolver with the identifier set
- */
- function withIdentifier(
- CriteriaResolver memory resolver,
- uint256 identifier
- ) internal pure returns (CriteriaResolver memory) {
- resolver.identifier = identifier;
- return resolver;
- }
-
- /**
- * @dev Sets the criteriaProof of a CriteriaResolver.
- *
- * @param resolver the CriteriaResolver to set the criteriaProof of
- * @param criteriaProof the criteriaProof to set
- *
- * @return _resolver the CriteriaResolver with the criteriaProof set
- */
- function withCriteriaProof(
- CriteriaResolver memory resolver,
- bytes32[] memory criteriaProof
- ) internal pure returns (CriteriaResolver memory) {
- // todo: consider copying?
- resolver.criteriaProof = criteriaProof;
- return resolver;
- }
-}
diff --git a/contracts/helpers/sol/lib/ExecutionLib.sol b/contracts/helpers/sol/lib/ExecutionLib.sol
deleted file mode 100644
index 142eba411..000000000
--- a/contracts/helpers/sol/lib/ExecutionLib.sol
+++ /dev/null
@@ -1,282 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- Execution,
- ItemType,
- ReceivedItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { ReceivedItemLib } from "./ReceivedItemLib.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title ExecutionLib
- * @author James Wenzel (emo.eth)
- * @notice ExecutionLib is a library for managing Execution structs and arrays.
- * It allows chaining of functions to make struct creation more
- * readable.
- */
-library ExecutionLib {
- bytes32 private constant EXECUTION_MAP_POSITION =
- keccak256("seaport.ExecutionDefaults");
- bytes32 private constant EXECUTIONS_MAP_POSITION =
- keccak256("seaport.ExecutionsDefaults");
- bytes32 private constant EMPTY_EXECUTION =
- keccak256(
- abi.encode(
- Execution({
- item: ReceivedItem({
- itemType: ItemType(0),
- token: address(0),
- identifier: 0,
- amount: 0,
- recipient: payable(address(0))
- }),
- offerer: address(0),
- conduitKey: bytes32(0)
- })
- )
- );
-
- using ReceivedItemLib for ReceivedItem;
- using ReceivedItemLib for ReceivedItem[];
-
- /**
- * @dev Clears a default Execution from storage.
- *
- * @param defaultName the name of the default to clear.
- */
- function clear(string memory defaultName) internal {
- mapping(string => Execution) storage executionMap = _executionMap();
- Execution storage item = executionMap[defaultName];
- clear(item);
- }
-
- /**
- * @dev Clears all fields on an Execution.
- *
- * @param execution the Execution to clear
- */
- function clear(Execution storage execution) internal {
- // clear all fields
- execution.item = ReceivedItemLib.empty();
- execution.offerer = address(0);
- execution.conduitKey = bytes32(0);
- }
-
- /**
- * @dev Clears an array of Executions from storage.
- *
- * @param executions the name of the default to clear
- */
- function clear(Execution[] storage executions) internal {
- while (executions.length > 0) {
- clear(executions[executions.length - 1]);
- executions.pop();
- }
- }
-
- /**
- * @dev Gets a default Execution from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the Execution retrieved from storage
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (Execution memory item) {
- mapping(string => Execution) storage executionMap = _executionMap();
- item = executionMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_EXECUTION) {
- revert("Empty Execution selected.");
- }
- }
-
- /**
- * @dev Gets an array of default Executions from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the Executions retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (Execution[] memory items) {
- mapping(string => Execution[]) storage executionsMap = _executionsMap();
- items = executionsMap[defaultName];
-
- if (items.length == 0) {
- revert("Empty Execution array selected.");
- }
- }
-
- /**
- * @dev Saves an Execution as a named default.
- *
- * @param execution the Execution to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _execution the Execution saved as a default
- */
- function saveDefault(
- Execution memory execution,
- string memory defaultName
- ) internal returns (Execution memory _execution) {
- mapping(string => Execution) storage executionMap = _executionMap();
- executionMap[defaultName] = execution;
- return execution;
- }
-
- /**
- * @dev Saves an array of Executions as a named default.
- *
- * @param executions the Executions to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _executions the Executions saved as a default
- */
- function saveDefaultMany(
- Execution[] memory executions,
- string memory defaultName
- ) internal returns (Execution[] memory _executions) {
- mapping(string => Execution[]) storage executionsMap = _executionsMap();
- StructCopier.setExecutions(executionsMap[defaultName], executions);
- return executions;
- }
-
- /**
- * @dev Makes a copy of an Execution in-memory.
- *
- * @param item the Execution to make a copy of in-memory
- *
- * @custom:return copy the copy of the Execution in-memory
- */
- function copy(
- Execution memory item
- ) internal pure returns (Execution memory) {
- return
- Execution({
- item: item.item.copy(),
- offerer: item.offerer,
- conduitKey: item.conduitKey
- });
- }
-
- /**
- * @dev Makes a copy of an array of Executions in-memory.
- *
- * @param items the array of Executions to make a copy of in-memory
- *
- * @custom:return copy the copy of the array of Executions in-memory
- */
- function copy(
- Execution[] memory items
- ) internal pure returns (Execution[] memory) {
- Execution[] memory copies = new Execution[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- copies[i] = copy(items[i]);
- }
- return copies;
- }
-
- /**
- * @dev Creates an empty Execution.
- *
- * @custom:return empty the empty Execution
- */
- function empty() internal pure returns (Execution memory) {
- return
- Execution({
- item: ReceivedItemLib.empty(),
- offerer: address(0),
- conduitKey: bytes32(0)
- });
- }
-
- /**
- * @dev Gets the storage position of the default Execution map.
- *
- * @return executionMap the storage position of the default Execution map
- */
- function _executionMap()
- private
- pure
- returns (mapping(string => Execution) storage executionMap)
- {
- bytes32 position = EXECUTION_MAP_POSITION;
- assembly {
- executionMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default array of Executions map.
- *
- * @return executionsMap the storage position of the default Executions map
- */
- function _executionsMap()
- private
- pure
- returns (mapping(string => Execution[]) storage executionsMap)
- {
- bytes32 position = EXECUTIONS_MAP_POSITION;
- assembly {
- executionsMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of an Execution's fields, which
- // modify the Execution in-place and return it.
-
- /**
- * @dev Configures an Execution's item field.
- *
- * @param execution the Execution to configure
- * @param item the value to set the Execution's item field to
- *
- * @return _execution the configured Execution
- */
- function withItem(
- Execution memory execution,
- ReceivedItem memory item
- ) internal pure returns (Execution memory) {
- execution.item = item.copy();
- return execution;
- }
-
- /**
- * @dev Configures an Execution's offerer field.
- *
- * @param execution the Execution to configure
- * @param offerer the value to set the Execution's offerer field to
- *
- * @return _execution the configured Execution
- */
- function withOfferer(
- Execution memory execution,
- address offerer
- ) internal pure returns (Execution memory) {
- execution.offerer = offerer;
- return execution;
- }
-
- /**
- * @dev Configures an Execution's conduitKey field.
- *
- * @param execution the Execution to configure
- * @param conduitKey the value to set the Execution's conduitKey field to
- *
- * @return _execution the configured Execution
- */
- function withConduitKey(
- Execution memory execution,
- bytes32 conduitKey
- ) internal pure returns (Execution memory) {
- execution.conduitKey = conduitKey;
- return execution;
- }
-}
diff --git a/contracts/helpers/sol/lib/FulfillmentComponentLib.sol b/contracts/helpers/sol/lib/FulfillmentComponentLib.sol
deleted file mode 100644
index 160ae03c4..000000000
--- a/contracts/helpers/sol/lib/FulfillmentComponentLib.sol
+++ /dev/null
@@ -1,263 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { FulfillmentComponent } from "../../../lib/ConsiderationStructs.sol";
-
-import { ArrayLib } from "./ArrayLib.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title FulfillmentComponentLib
- * @author James Wenzel (emo.eth)
- * @notice FulfillmentComponentLib is a library for managing FulfillmentComponent
- * structs and arrays. It allows chaining of functions to make
- * struct creation more readable.
- */
-library FulfillmentComponentLib {
- bytes32 private constant FULFILLMENT_COMPONENT_MAP_POSITION =
- keccak256("seaport.FulfillmentComponentDefaults");
- bytes32 private constant FULFILLMENT_COMPONENTS_MAP_POSITION =
- keccak256("seaport.FulfillmentComponentsDefaults");
-
- using ArrayLib for bytes32[];
-
- /**
- * @dev Clears a default FulfillmentComponent from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => FulfillmentComponent)
- storage fulfillmentComponentMap = _fulfillmentComponentMap();
- FulfillmentComponent storage component = fulfillmentComponentMap[
- defaultName
- ];
- clear(component);
- }
-
- /**
- * @dev Clears all fields on a FulfillmentComponent.
- *
- * @param component the FulfillmentComponent to clear
- */
- function clear(FulfillmentComponent storage component) internal {
- component.orderIndex = 0;
- component.itemIndex = 0;
- }
-
- /**
- * @dev Clears an array of FulfillmentComponents from storage.
- *
- * @param components the FulfillmentComponents to clear
- */
- function clear(FulfillmentComponent[] storage components) internal {
- while (components.length > 0) {
- clear(components[components.length - 1]);
- components.pop();
- }
- }
-
- /**
- * @dev Gets a default FulfillmentComponent from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the FulfillmentComponent retrieved from storage
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (FulfillmentComponent memory item) {
- mapping(string => FulfillmentComponent)
- storage fulfillmentComponentMap = _fulfillmentComponentMap();
- item = fulfillmentComponentMap[defaultName];
- }
-
- /**
- * @dev Gets an array of default FulfillmentComponents from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the FulfillmentComponents retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (FulfillmentComponent[] memory items) {
- mapping(string => FulfillmentComponent[])
- storage fulfillmentComponentMap = _fulfillmentComponentsMap();
- items = fulfillmentComponentMap[defaultName];
- }
-
- /**
- * @dev Saves an FulfillmentComponent as a named default.
- *
- * @param fulfillmentComponent the FulfillmentComponent to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _fulfillmentComponent the FulfillmentComponent saved as a default
- */
- function saveDefault(
- FulfillmentComponent memory fulfillmentComponent,
- string memory defaultName
- ) internal returns (FulfillmentComponent memory _fulfillmentComponent) {
- mapping(string => FulfillmentComponent)
- storage fulfillmentComponentMap = _fulfillmentComponentMap();
- FulfillmentComponent storage component = fulfillmentComponentMap[
- defaultName
- ];
- component.orderIndex = fulfillmentComponent.orderIndex;
- component.itemIndex = fulfillmentComponent.itemIndex;
- return fulfillmentComponent;
- }
-
- /**
- * @dev Saves an array of FulfillmentComponents as a named default.
- *
- * @param fulfillmentComponents the FulfillmentComponents to save as a
- * default
- * @param defaultName the name of the default for retrieval
- *
- * @return _fulfillmentComponents the FulfillmentComponents saved as a
- * default
- */
- function saveDefaultMany(
- FulfillmentComponent[] memory fulfillmentComponents,
- string memory defaultName
- ) internal returns (FulfillmentComponent[] memory _fulfillmentComponents) {
- mapping(string => FulfillmentComponent[])
- storage fulfillmentComponentsMap = _fulfillmentComponentsMap();
- FulfillmentComponent[] storage components = fulfillmentComponentsMap[
- defaultName
- ];
- clear(components);
- StructCopier.setFulfillmentComponents(
- components,
- fulfillmentComponents
- );
-
- return fulfillmentComponents;
- }
-
- /**
- * @dev Makes a copy of an FulfillmentComponent in-memory.
- *
- * @param component the FulfillmentComponent to make a copy of in-memory.
- *
- * @return copiedComponent the copied FulfillmentComponent
- */
- function copy(
- FulfillmentComponent memory component
- ) internal pure returns (FulfillmentComponent memory) {
- return
- FulfillmentComponent({
- orderIndex: component.orderIndex,
- itemIndex: component.itemIndex
- });
- }
-
- /**
- * @dev Makes a copy of an array of FulfillmentComponents in-memory.
- *
- * @param components the FulfillmentComponents to make a copy of in-memory.
- *
- * @return copiedComponents the copied FulfillmentComponents
- */
- function copy(
- FulfillmentComponent[] memory components
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory copiedItems = new FulfillmentComponent[](
- components.length
- );
- for (uint256 i = 0; i < components.length; i++) {
- copiedItems[i] = copy(components[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Creates an empty FulfillmentComponent.
- *
- * @return component the empty FulfillmentComponent
- *
- * @custom:return emptyComponent the empty FulfillmentComponent
- */
- function empty() internal pure returns (FulfillmentComponent memory) {
- return FulfillmentComponent({ orderIndex: 0, itemIndex: 0 });
- }
-
- /**
- * @dev Gets the storage position of the default FulfillmentComponent map.
- *
- * @custom:return position the storage position of the default
- * FulfillmentComponent
- */
- function _fulfillmentComponentMap()
- private
- pure
- returns (
- mapping(string => FulfillmentComponent)
- storage fulfillmentComponentMap
- )
- {
- bytes32 position = FULFILLMENT_COMPONENT_MAP_POSITION;
- assembly {
- fulfillmentComponentMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default FulfillmentComponent array
- * map.
- *
- * @custom:return position the storage position of the default
- * FulfillmentComponent array
- */
- function _fulfillmentComponentsMap()
- private
- pure
- returns (
- mapping(string => FulfillmentComponent[])
- storage fulfillmentComponentsMap
- )
- {
- bytes32 position = FULFILLMENT_COMPONENTS_MAP_POSITION;
- assembly {
- fulfillmentComponentsMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of a FulfillmentComponent's
- // fields, which modify the FulfillmentComponent in-place and return it.
-
- /**
- * @dev Sets the orderIndex of a FulfillmentComponent.
- *
- * @param component the FulfillmentComponent to set the orderIndex of
- * @param orderIndex the orderIndex to set
- *
- * @return component the FulfillmentComponent with the orderIndex set
- */
- function withOrderIndex(
- FulfillmentComponent memory component,
- uint256 orderIndex
- ) internal pure returns (FulfillmentComponent memory) {
- component.orderIndex = orderIndex;
- return component;
- }
-
- /**
- * @dev Sets the itemIndex of a FulfillmentComponent.
- *
- * @param component the FulfillmentComponent to set the itemIndex of
- * @param itemIndex the itemIndex to set
- *
- * @return component the FulfillmentComponent with the itemIndex set
- */
- function withItemIndex(
- FulfillmentComponent memory component,
- uint256 itemIndex
- ) internal pure returns (FulfillmentComponent memory) {
- component.itemIndex = itemIndex;
- return component;
- }
-}
diff --git a/contracts/helpers/sol/lib/FulfillmentLib.sol b/contracts/helpers/sol/lib/FulfillmentLib.sol
deleted file mode 100644
index 392a85d0e..000000000
--- a/contracts/helpers/sol/lib/FulfillmentLib.sol
+++ /dev/null
@@ -1,240 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- Fulfillment,
- FulfillmentComponent
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { FulfillmentComponentLib } from "./FulfillmentComponentLib.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title FulfillmentLib
- * @author James Wenzel (emo.eth)
- * @notice FulfillmentLib is a library for managing Fulfillment structs and
- * arrays. It allows chaining of functions to make struct creation more
- * readable.
- */
-library FulfillmentLib {
- bytes32 private constant FULFILLMENT_MAP_POSITION =
- keccak256("seaport.FulfillmentDefaults");
- bytes32 private constant FULFILLMENTS_MAP_POSITION =
- keccak256("seaport.FulfillmentsDefaults");
-
- using FulfillmentComponentLib for FulfillmentComponent[];
- using StructCopier for FulfillmentComponent[];
-
- /**
- * @dev Clears a default Fulfillment from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => Fulfillment)
- storage fulfillmentMap = _fulfillmentMap();
- Fulfillment storage _fulfillment = fulfillmentMap[defaultName];
- // clear all fields
- FulfillmentComponent[] memory components;
- _fulfillment.offerComponents.setFulfillmentComponents(components);
- _fulfillment.considerationComponents.setFulfillmentComponents(
- components
- );
- }
-
- /**
- * @dev Gets a default Fulfillment from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the Fulfillment retrieved from storage
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (Fulfillment memory item) {
- mapping(string => Fulfillment)
- storage fulfillmentMap = _fulfillmentMap();
- item = fulfillmentMap[defaultName];
- }
-
- /**
- * @dev Gets a default Fulfillment array from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the Fulfillment array retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (Fulfillment[] memory items) {
- mapping(string => Fulfillment[])
- storage fulfillmentsMap = _fulfillmentsMap();
- items = fulfillmentsMap[defaultName];
- }
-
- /**
- * @dev Saves a Fulfillment as a named default.
- *
- * @param fulfillment the Fulfillment to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _fulfillment the Fulfillment saved as a default
- */
- function saveDefault(
- Fulfillment memory fulfillment,
- string memory defaultName
- ) internal returns (Fulfillment memory _fulfillment) {
- mapping(string => Fulfillment)
- storage fulfillmentMap = _fulfillmentMap();
- StructCopier.setFulfillment(fulfillmentMap[defaultName], fulfillment);
-
- return fulfillment;
- }
-
- /**
- * @dev Saves a Fulfillment array as a named default.
- *
- * @param fulfillments the Fulfillment array to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _fulfillments the Fulfillment array saved as a default
- */
- function saveDefaultMany(
- Fulfillment[] memory fulfillments,
- string memory defaultName
- ) internal returns (Fulfillment[] memory _fulfillments) {
- mapping(string => Fulfillment[])
- storage fulfillmentsMap = _fulfillmentsMap();
- StructCopier.setFulfillments(
- fulfillmentsMap[defaultName],
- fulfillments
- );
- return fulfillments;
- }
-
- /**
- * @dev Makes a copy of a Fulfillment in-memory.
- *
- * @param _fulfillment the Fulfillment to make a copy of in-memory
- *
- * @custom:return copiedFulfillment the copied Fulfillment
- */
- function copy(
- Fulfillment memory _fulfillment
- ) internal pure returns (Fulfillment memory) {
- return
- Fulfillment({
- offerComponents: _fulfillment.offerComponents.copy(),
- considerationComponents: _fulfillment
- .considerationComponents
- .copy()
- });
- }
-
- /**
- * @dev Makes a copy of a Fulfillment array in-memory.
- *
- * @param _fulfillments the Fulfillment array to make a copy of in-memory
- *
- * @custom:return copiedFulfillments the copied Fulfillment array
- */
- function copy(
- Fulfillment[] memory _fulfillments
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory copiedItems = new Fulfillment[](
- _fulfillments.length
- );
- for (uint256 i = 0; i < _fulfillments.length; i++) {
- copiedItems[i] = copy(_fulfillments[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Creates an empty Fulfillment in-memory.
- *
- * @custom:return emptyFulfillment the empty Fulfillment
- */
- function empty() internal pure returns (Fulfillment memory) {
- FulfillmentComponent[] memory components;
- return
- Fulfillment({
- offerComponents: components,
- considerationComponents: components
- });
- }
-
- /**
- * @dev Gets the storage position of the default Fulfillment map
- *
- * @return fulfillmentMap the storage position of the default Fulfillment
- * map
- */
- function _fulfillmentMap()
- private
- pure
- returns (mapping(string => Fulfillment) storage fulfillmentMap)
- {
- bytes32 position = FULFILLMENT_MAP_POSITION;
- assembly {
- fulfillmentMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default Fulfillment array map
- *
- * @return fulfillmentsMap the storage position of the default Fulfillment
- * array map
- */
- function _fulfillmentsMap()
- private
- pure
- returns (mapping(string => Fulfillment[]) storage fulfillmentsMap)
- {
- bytes32 position = FULFILLMENTS_MAP_POSITION;
- assembly {
- fulfillmentsMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of a Fulfillment's fields, which
- // modify the FulfillmentComponent in-place and return it.
-
- /**
- * @dev Sets the offer components of a Fulfillment in-place.
- *
- * @param _fulfillment the Fulfillment to set the offer components of
- * @param components the FulfillmentComponent array to set as the offer
- * components
- *
- * @custom:return _fulfillment the Fulfillment with the offer components set
- */
- function withOfferComponents(
- Fulfillment memory _fulfillment,
- FulfillmentComponent[] memory components
- ) internal pure returns (Fulfillment memory) {
- _fulfillment.offerComponents = components.copy();
- return _fulfillment;
- }
-
- /**
- * @dev Sets the consideration components of a Fulfillment in-place.
- *
- * @param _fulfillment the Fulfillment to set the consideration components
- * of
- * @param components the FulfillmentComponent array to set as the
- * consideration components
- *
- * @custom:return _fulfillment the Fulfillment with the consideration
- * components set
- */
- function withConsiderationComponents(
- Fulfillment memory _fulfillment,
- FulfillmentComponent[] memory components
- ) internal pure returns (Fulfillment memory) {
- _fulfillment.considerationComponents = components.copy();
- return _fulfillment;
- }
-}
diff --git a/contracts/helpers/sol/lib/OfferItemLib.sol b/contracts/helpers/sol/lib/OfferItemLib.sol
deleted file mode 100644
index e98fbdc00..000000000
--- a/contracts/helpers/sol/lib/OfferItemLib.sol
+++ /dev/null
@@ -1,392 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- ConsiderationItem,
- OfferItem,
- SpentItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { ItemType } from "../../../lib/ConsiderationEnums.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title OfferItemLib
- * @author James Wenzel (emo.eth)
- * @notice OfferItemLib is a library for managing OfferItem structs and arrays.
- * It allows chaining of functions to make struct creation more readable.
- */
-library OfferItemLib {
- bytes32 private constant OFFER_ITEM_MAP_POSITION =
- keccak256("seaport.OfferItemDefaults");
- bytes32 private constant OFFER_ITEMS_MAP_POSITION =
- keccak256("seaport.OfferItemsDefaults");
- bytes32 private constant EMPTY_OFFER_ITEM =
- keccak256(
- abi.encode(
- OfferItem({
- itemType: ItemType(0),
- token: address(0),
- identifierOrCriteria: 0,
- startAmount: 0,
- endAmount: 0
- })
- )
- );
-
- /**
- * @dev Clears an OfferItem from storage.
- *
- * @param item the item to clear
- */
- function _clear(OfferItem storage item) internal {
- // clear all fields
- item.itemType = ItemType.NATIVE;
- item.token = address(0);
- item.identifierOrCriteria = 0;
- item.startAmount = 0;
- item.endAmount = 0;
- }
-
- /**
- * @dev Clears an OfferItem from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => OfferItem) storage offerItemMap = _offerItemMap();
- OfferItem storage item = offerItemMap[defaultName];
- _clear(item);
- }
-
- /**
- * @dev Clears an array of OfferItems from storage.
- *
- * @param defaultsName the name of the default to clear
- */
- function clearMany(string memory defaultsName) internal {
- mapping(string => OfferItem[]) storage offerItemsMap = _offerItemsMap();
- OfferItem[] storage items = offerItemsMap[defaultsName];
- while (items.length > 0) {
- _clear(items[items.length - 1]);
- items.pop();
- }
- }
-
- /**
- * @dev Gets a default OfferItem from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the OfferItem retrieved from storage
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (OfferItem memory item) {
- mapping(string => OfferItem) storage offerItemMap = _offerItemMap();
- item = offerItemMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_OFFER_ITEM) {
- revert("Empty OfferItem selected.");
- }
- }
-
- /**
- * @dev Gets a default OfferItem from storage.
- *
- * @param defaultsName the name of the default for retrieval
- *
- * @return items the OfferItems retrieved from storage
- */
- function fromDefaultMany(
- string memory defaultsName
- ) internal view returns (OfferItem[] memory items) {
- mapping(string => OfferItem[]) storage offerItemsMap = _offerItemsMap();
- items = offerItemsMap[defaultsName];
-
- if (items.length == 0) {
- revert("Empty OfferItem array selected.");
- }
- }
-
- /**
- * @dev Saves an OfferItem as a named default.
- *
- * @param offerItem the OfferItem to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _offerItem the OfferItem saved as a default
- */
- function saveDefault(
- OfferItem memory offerItem,
- string memory defaultName
- ) internal returns (OfferItem memory _offerItem) {
- mapping(string => OfferItem) storage offerItemMap = _offerItemMap();
- offerItemMap[defaultName] = offerItem;
- return offerItem;
- }
-
- /**
- * @dev Saves an array of OfferItems as a named default.
- *
- * @param offerItems the OfferItems to save as a default
- * @param defaultsName the name of the default for retrieval
- *
- * @return _offerItems the OfferItems saved as a default
- */
- function saveDefaultMany(
- OfferItem[] memory offerItems,
- string memory defaultsName
- ) internal returns (OfferItem[] memory _offerItems) {
- mapping(string => OfferItem[]) storage offerItemsMap = _offerItemsMap();
- OfferItem[] storage items = offerItemsMap[defaultsName];
- clearMany(defaultsName);
- StructCopier.setOfferItems(items, offerItems);
- return offerItems;
- }
-
- /**
- * @dev Makes a copy of an OfferItem in-memory.
- *
- * @param item the OfferItem to make a copy of in-memory
- *
- * @custom:return copiedItem the copied OfferItem
- */
- function copy(
- OfferItem memory item
- ) internal pure returns (OfferItem memory) {
- return
- OfferItem({
- itemType: item.itemType,
- token: item.token,
- identifierOrCriteria: item.identifierOrCriteria,
- startAmount: item.startAmount,
- endAmount: item.endAmount
- });
- }
-
- /**
- * @dev Makes a copy of an array of OfferItems in-memory.
- *
- * @param items the OfferItems to make a copy of in-memory
- *
- * @custom:return copiedItems the copied OfferItems
- */
- function copy(
- OfferItem[] memory items
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory copiedItems = new OfferItem[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- copiedItems[i] = copy(items[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Creates an empty OfferItem.
- *
- * @custom:return emptyItem the empty OfferItem
- */
- function empty() internal pure returns (OfferItem memory) {
- return
- OfferItem({
- itemType: ItemType.NATIVE,
- token: address(0),
- identifierOrCriteria: 0,
- startAmount: 0,
- endAmount: 0
- });
- }
-
- /**
- * @dev Gets the storage position of the default OfferItem map.
- *
- * @custom:return offerItemMap the default OfferItem map position
- */
- function _offerItemMap()
- private
- pure
- returns (mapping(string => OfferItem) storage offerItemMap)
- {
- bytes32 position = OFFER_ITEM_MAP_POSITION;
- assembly {
- offerItemMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default OfferItem array map
- *
- * @custom:return offerItemMap the default OfferItem array map position
- */
- function _offerItemsMap()
- private
- pure
- returns (mapping(string => OfferItem[]) storage offerItemMap)
- {
- bytes32 position = OFFER_ITEMS_MAP_POSITION;
- assembly {
- offerItemMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of a OfferItem's fields, which
- // modify the OfferItem in-place and return it.
-
- /**
- * @dev Sets the item type of an OfferItem.
- *
- * @param item the OfferItem to modify
- * @param itemType the item type to set
- *
- * @custom:return _offerItem the modified OfferItem
- */
- function withItemType(
- OfferItem memory item,
- ItemType itemType
- ) internal pure returns (OfferItem memory) {
- item.itemType = itemType;
- return item;
- }
-
- /**
- * @dev Sets the token of an OfferItem.
- *
- * @param item the OfferItem to modify
- * @param token the token to set
- *
- * @custom:return _offerItem the modified OfferItem
- */
- function withToken(
- OfferItem memory item,
- address token
- ) internal pure returns (OfferItem memory) {
- item.token = token;
- return item;
- }
-
- /**
- * @dev Sets the identifierOrCriteria of an OfferItem.
- *
- * @param item the OfferItem to modify
- * @param identifierOrCriteria the identifier or criteria to set
- *
- * @custom:return _offerItem the modified OfferItem
- */
- function withIdentifierOrCriteria(
- OfferItem memory item,
- uint256 identifierOrCriteria
- ) internal pure returns (OfferItem memory) {
- item.identifierOrCriteria = identifierOrCriteria;
- return item;
- }
-
- /**
- * @dev Sets the startAmount of an OfferItem.
- *
- * @param item the OfferItem to modify
- * @param startAmount the start amount to set
- *
- * @custom:return _offerItem the modified OfferItem
- */
- function withStartAmount(
- OfferItem memory item,
- uint256 startAmount
- ) internal pure returns (OfferItem memory) {
- item.startAmount = startAmount;
- return item;
- }
-
- /**
- * @dev Sets the endAmount of an OfferItem.
- *
- * @param item the OfferItem to modify
- * @param endAmount the end amount to set
- *
- * @custom:return _offerItem the modified OfferItem
- */
- function withEndAmount(
- OfferItem memory item,
- uint256 endAmount
- ) internal pure returns (OfferItem memory) {
- item.endAmount = endAmount;
- return item;
- }
-
- /**
- * @dev Sets the startAmount and endAmount of an OfferItem.
- *
- * @param item the OfferItem to modify
- * @param amount the amount to set for the start and end amounts
- *
- * @custom:return _offerItem the modified OfferItem
- */
- function withAmount(
- OfferItem memory item,
- uint256 amount
- ) internal pure returns (OfferItem memory) {
- item.startAmount = amount;
- item.endAmount = amount;
- return item;
- }
-
- /**
- * @dev Converts an OfferItem to a SpentItem.
- *
- * @param item the OfferItem to convert
- *
- * @custom:return spentItem the converted SpentItem
- */
- function toSpentItem(
- OfferItem memory item
- ) internal pure returns (SpentItem memory) {
- return
- SpentItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifierOrCriteria,
- amount: item.startAmount
- });
- }
-
- /**
- * @dev Converts an OfferItem[] to a SpentItem[].
- *
- * @param items the OfferItem[] to convert
- *
- * @custom:return spentItems the converted SpentItem[]
- */
- function toSpentItemArray(
- OfferItem[] memory items
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory spentItems = new SpentItem[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- spentItems[i] = toSpentItem(items[i]);
- }
-
- return spentItems;
- }
-
- /**
- * @dev Converts an OfferItem to a ConsiderationItem.
- *
- * @param item the OfferItem to convert
- *
- * @custom:return considerationItem the converted ConsiderationItem
- */
- function toConsiderationItem(
- OfferItem memory item,
- address recipient
- ) internal pure returns (ConsiderationItem memory) {
- return
- ConsiderationItem({
- itemType: item.itemType,
- token: item.token,
- identifierOrCriteria: item.identifierOrCriteria,
- startAmount: item.startAmount,
- endAmount: item.endAmount,
- recipient: payable(recipient)
- });
- }
-}
diff --git a/contracts/helpers/sol/lib/OrderComponentsLib.sol b/contracts/helpers/sol/lib/OrderComponentsLib.sol
deleted file mode 100644
index 98b0779a0..000000000
--- a/contracts/helpers/sol/lib/OrderComponentsLib.sol
+++ /dev/null
@@ -1,475 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- ConsiderationItem,
- OfferItem,
- OrderComponents,
- OrderParameters
-} from "../../../lib/ConsiderationStructs.sol";
-
-import {
- BasicOrderType,
- ItemType,
- OrderType
-} from "../../../lib/ConsiderationEnums.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-import { OfferItemLib } from "./OfferItemLib.sol";
-
-import { ConsiderationItemLib } from "./ConsiderationItemLib.sol";
-
-/**
- * @title OrderComponentsLib
- * @author James Wenzel (emo.eth)
- * @notice OrderComponentsLib is a library for managing OrderComponents structs
- * and arrays. It allows chaining of functions to make struct creation
- * more readable.
- */
-library OrderComponentsLib {
- using OrderComponentsLib for OrderComponents;
- using OfferItemLib for OfferItem[];
- using ConsiderationItemLib for ConsiderationItem[];
-
- bytes32 private constant ORDER_COMPONENTS_MAP_POSITION =
- keccak256("seaport.OrderComponentsDefaults");
- bytes32 private constant ORDER_COMPONENTS_ARRAY_MAP_POSITION =
- keccak256("seaport.OrderComponentsArrayDefaults");
- bytes32 private constant EMPTY_ORDER_COMPONENTS =
- keccak256(
- abi.encode(
- OrderComponents({
- offerer: address(0),
- zone: address(0),
- offer: new OfferItem[](0),
- consideration: new ConsiderationItem[](0),
- orderType: OrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- conduitKey: bytes32(0),
- counter: 0
- })
- )
- );
-
- /**
- * @dev Clears anOrderComponents from storage.
- *
- * @param components the OrderComponents to clear
- */
- function clear(OrderComponents storage components) internal {
- // uninitialized pointers take up no new memory (versus one word for initializing length-0)
- OfferItem[] memory offer;
- ConsiderationItem[] memory consideration;
-
- // clear all fields
- components.offerer = address(0);
- components.zone = address(0);
- StructCopier.setOfferItems(components.offer, offer);
- StructCopier.setConsiderationItems(
- components.consideration,
- consideration
- );
- components.orderType = OrderType(0);
- components.startTime = 0;
- components.endTime = 0;
- components.zoneHash = bytes32(0);
- components.salt = 0;
- components.conduitKey = bytes32(0);
- components.counter = 0;
- }
-
- /**
- * @dev Clears an array of OrderComponents from storage.
- *
- * @param components the OrderComponents to clear
- */
- function clear(OrderComponents[] storage components) internal {
- while (components.length > 0) {
- clear(components[components.length - 1]);
- components.pop();
- }
- }
-
- /**
- * @dev Clears a default OrderComponents from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => OrderComponents)
- storage orderComponentsMap = _orderComponentsMap();
- OrderComponents storage components = orderComponentsMap[defaultName];
- components.clear();
- }
-
- /**
- * @dev Creates a new OrderComponents struct.
- *
- * @return item the new OrderComponents struct
- */
- function empty() internal pure returns (OrderComponents memory item) {
- OfferItem[] memory offer;
- ConsiderationItem[] memory consideration;
- item = OrderComponents({
- offerer: address(0),
- zone: address(0),
- offer: offer,
- consideration: consideration,
- orderType: OrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- conduitKey: bytes32(0),
- counter: 0
- });
- }
-
- /**
- * @dev Gets a default OrderComponents from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the default OrderComponents
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (OrderComponents memory item) {
- mapping(string => OrderComponents)
- storage orderComponentsMap = _orderComponentsMap();
- item = orderComponentsMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_ORDER_COMPONENTS) {
- revert("Empty OrderComponents selected.");
- }
- }
-
- /**
- * @dev Gets a default OrderComponents array from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the default OrderComponents array
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (OrderComponents[] memory items) {
- mapping(string => OrderComponents[])
- storage orderComponentsArrayMap = _orderComponentsArrayMap();
- items = orderComponentsArrayMap[defaultName];
-
- if (items.length == 0) {
- revert("Empty OrderComponents array selected.");
- }
- }
-
- /**
- * @dev Saves an OrderComponents as a named default.
- *
- * @param orderComponents the OrderComponents to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _orderComponents the OrderComponents that was saved
- */
- function saveDefault(
- OrderComponents memory orderComponents,
- string memory defaultName
- ) internal returns (OrderComponents memory _orderComponents) {
- mapping(string => OrderComponents)
- storage orderComponentsMap = _orderComponentsMap();
- OrderComponents storage destination = orderComponentsMap[defaultName];
- StructCopier.setOrderComponents(destination, orderComponents);
- return orderComponents;
- }
-
- /**
- * @dev Saves an OrderComponents array as a named default.
- *
- * @param orderComponents the OrderComponents array to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _orderComponents the OrderComponents array that was saved
- */
- function saveDefaultMany(
- OrderComponents[] memory orderComponents,
- string memory defaultName
- ) internal returns (OrderComponents[] memory _orderComponents) {
- mapping(string => OrderComponents[])
- storage orderComponentsArrayMap = _orderComponentsArrayMap();
- OrderComponents[] storage destination = orderComponentsArrayMap[
- defaultName
- ];
- StructCopier.setOrderComponents(destination, orderComponents);
- return orderComponents;
- }
-
- /**
- * @dev Makes a copy of an OrderComponents in-memory.
- *
- * @param item the OrderComponents to make a copy of in-memory
- *
- * @return the copy of the OrderComponents
- */
- function copy(
- OrderComponents memory item
- ) internal pure returns (OrderComponents memory) {
- return
- OrderComponents({
- offerer: item.offerer,
- zone: item.zone,
- offer: item.offer.copy(),
- consideration: item.consideration.copy(),
- orderType: item.orderType,
- startTime: item.startTime,
- endTime: item.endTime,
- zoneHash: item.zoneHash,
- salt: item.salt,
- conduitKey: item.conduitKey,
- counter: item.counter
- });
- }
-
- /**
- * @dev Gets the storage position of the default OrderComponents map.
- *
- * @custom:return position the storage position of the default
- * OrderComponents map
- */
- function _orderComponentsMap()
- private
- pure
- returns (mapping(string => OrderComponents) storage orderComponentsMap)
- {
- bytes32 position = ORDER_COMPONENTS_MAP_POSITION;
- assembly {
- orderComponentsMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default OrderComponents array map.
- *
- * @custom:return position the storage position of the default
- * OrderComponents array map
- */
- function _orderComponentsArrayMap()
- private
- pure
- returns (
- mapping(string => OrderComponents[]) storage orderComponentsArrayMap
- )
- {
- bytes32 position = ORDER_COMPONENTS_ARRAY_MAP_POSITION;
- assembly {
- orderComponentsArrayMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of a OrderComponents's fields,
- // which modify the OrderComponents struct in-place and return it.
-
- /**
- * @dev Sets the offerer field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param offerer the new value for the offerer field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withOfferer(
- OrderComponents memory components,
- address offerer
- ) internal pure returns (OrderComponents memory) {
- components.offerer = offerer;
- return components;
- }
-
- /**
- * @dev Sets the zone field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param zone the new value for the zone field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withZone(
- OrderComponents memory components,
- address zone
- ) internal pure returns (OrderComponents memory) {
- components.zone = zone;
- return components;
- }
-
- /**
- * @dev Sets the offer field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param offer the new value for the offer field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withOffer(
- OrderComponents memory components,
- OfferItem[] memory offer
- ) internal pure returns (OrderComponents memory) {
- components.offer = offer;
- return components;
- }
-
- /**
- * @dev Sets the consideration field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param consideration the new value for the consideration field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withConsideration(
- OrderComponents memory components,
- ConsiderationItem[] memory consideration
- ) internal pure returns (OrderComponents memory) {
- components.consideration = consideration;
- return components;
- }
-
- /**
- * @dev Sets the orderType field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param orderType the new value for the orderType field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withOrderType(
- OrderComponents memory components,
- OrderType orderType
- ) internal pure returns (OrderComponents memory) {
- components.orderType = orderType;
- return components;
- }
-
- /**
- * @dev Sets the startTime field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param startTime the new value for the startTime field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withStartTime(
- OrderComponents memory components,
- uint256 startTime
- ) internal pure returns (OrderComponents memory) {
- components.startTime = startTime;
- return components;
- }
-
- /**
- * @dev Sets the endTime field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param endTime the new value for the endTime field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withEndTime(
- OrderComponents memory components,
- uint256 endTime
- ) internal pure returns (OrderComponents memory) {
- components.endTime = endTime;
- return components;
- }
-
- /**
- * @dev Sets the zoneHash field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param zoneHash the new value for the zoneHash field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withZoneHash(
- OrderComponents memory components,
- bytes32 zoneHash
- ) internal pure returns (OrderComponents memory) {
- components.zoneHash = zoneHash;
- return components;
- }
-
- /**
- * @dev Sets the salt field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param salt the new value for the salt field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withSalt(
- OrderComponents memory components,
- uint256 salt
- ) internal pure returns (OrderComponents memory) {
- components.salt = salt;
- return components;
- }
-
- /**
- * @dev Sets the conduitKey field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param conduitKey the new value for the conduitKey field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withConduitKey(
- OrderComponents memory components,
- bytes32 conduitKey
- ) internal pure returns (OrderComponents memory) {
- components.conduitKey = conduitKey;
- return components;
- }
-
- /**
- * @dev Sets the counter field of an OrderComponents struct in-place.
- *
- * @param components the OrderComponents struct to modify
- * @param counter the new value for the counter field
- *
- * @custom:return _orderComponents the modified OrderComponents struct
- */
- function withCounter(
- OrderComponents memory components,
- uint256 counter
- ) internal pure returns (OrderComponents memory) {
- components.counter = counter;
- return components;
- }
-
- /**
- * @dev Converts an OrderComponents struct into an OrderParameters struct.
- *
- * @param components the OrderComponents struct to convert
- *
- * @custom:return _orderParameters the converted OrderParameters struct
- */
- function toOrderParameters(
- OrderComponents memory components
- ) internal pure returns (OrderParameters memory parameters) {
- parameters.offerer = components.offerer;
- parameters.zone = components.zone;
- parameters.offer = components.offer.copy();
- parameters.consideration = components.consideration.copy();
- parameters.orderType = components.orderType;
- parameters.startTime = components.startTime;
- parameters.endTime = components.endTime;
- parameters.zoneHash = components.zoneHash;
- parameters.salt = components.salt;
- parameters.conduitKey = components.conduitKey;
- parameters.totalOriginalConsiderationItems = components
- .consideration
- .length;
- }
-}
diff --git a/contracts/helpers/sol/lib/OrderLib.sol b/contracts/helpers/sol/lib/OrderLib.sol
deleted file mode 100644
index e7551adc9..000000000
--- a/contracts/helpers/sol/lib/OrderLib.sol
+++ /dev/null
@@ -1,381 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- AdditionalRecipient,
- AdvancedOrder,
- BasicOrderParameters,
- ConsiderationItem,
- OfferItem,
- Order,
- OrderParameters,
- OrderType
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { BasicOrderType } from "../../../lib/ConsiderationEnums.sol";
-
-import { OrderParametersLib } from "./OrderParametersLib.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title AdvancedOrderLib
- * @author James Wenzel (emo.eth)
- * @notice AdvancedOrderLib is a library for managing AdvancedOrder
- * structs and arrays. It allows chaining of functions to make struct
- * creation more readable.
- */
-library OrderLib {
- bytes32 private constant ORDER_MAP_POSITION =
- keccak256("seaport.OrderDefaults");
- bytes32 private constant ORDERS_MAP_POSITION =
- keccak256("seaport.OrdersDefaults");
- bytes32 private constant EMPTY_ORDER =
- keccak256(
- abi.encode(
- Order({
- parameters: OrderParameters({
- offerer: address(0),
- zone: address(0),
- offer: new OfferItem[](0),
- consideration: new ConsiderationItem[](0),
- orderType: OrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- conduitKey: bytes32(0),
- totalOriginalConsiderationItems: 0
- }),
- signature: ""
- })
- )
- );
-
- using OrderParametersLib for OrderParameters;
-
- /**
- * @dev Clears a default Order from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => Order) storage orderMap = _orderMap();
- Order storage item = orderMap[defaultName];
- clear(item);
- }
-
- /**
- * @dev Clears all fields on an Order.
- *
- * @param order the Order to clear
- */
- function clear(Order storage order) internal {
- // clear all fields
- order.parameters.clear();
- order.signature = "";
- }
-
- /**
- * @dev Clears an array of Orders from storage.
- *
- * @param order the Orders to clear
- */
- function clear(Order[] storage order) internal {
- while (order.length > 0) {
- clear(order[order.length - 1]);
- order.pop();
- }
- }
-
- /**
- * @dev Gets a default Order from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the default Order
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (Order memory item) {
- mapping(string => Order) storage orderMap = _orderMap();
- item = orderMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_ORDER) {
- revert("Empty Order selected.");
- }
- }
-
- /**
- * @dev Gets a default Order array from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the default Order array
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (Order[] memory) {
- mapping(string => Order[]) storage ordersMap = _ordersMap();
- Order[] memory items = ordersMap[defaultName];
-
- if (items.length == 0) {
- revert("Empty Order array selected.");
- }
-
- return items;
- }
-
- /**
- * @dev Saves an Order as a named default.
- *
- * @param order the Order to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _order the Order saved as a default
- */
- function saveDefault(
- Order memory order,
- string memory defaultName
- ) internal returns (Order memory _order) {
- mapping(string => Order) storage orderMap = _orderMap();
- StructCopier.setOrder(orderMap[defaultName], order);
- return order;
- }
-
- /**
- * @dev Saves an Order array as a named default.
- *
- * @param orders the Order array to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _orders the Order array saved as a default
- */
- function saveDefaultMany(
- Order[] memory orders,
- string memory defaultName
- ) internal returns (Order[] memory _orders) {
- mapping(string => Order[]) storage ordersMap = _ordersMap();
- StructCopier.setOrders(ordersMap[defaultName], orders);
- return orders;
- }
-
- /**
- * @dev Makes a copy of an Order in-memory.
- *
- * @param item the Order to make a copy of in-memory
- *
- * @custom:return copiedOrder the copied Order
- */
- function copy(Order memory item) internal pure returns (Order memory) {
- return
- Order({
- parameters: item.parameters.copy(),
- signature: item.signature
- });
- }
-
- /**
- * @dev Makes a copy of an Order array in-memory.
- *
- * @param items the Order array to make a copy of in-memory
- *
- * @custom:return copiedOrders the copied Order array
- */
- function copy(Order[] memory items) internal pure returns (Order[] memory) {
- Order[] memory copiedItems = new Order[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- copiedItems[i] = copy(items[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Create an empty Order.
- *
- * @custom:return emptyOrder the empty Order
- */
- function empty() internal pure returns (Order memory) {
- return Order({ parameters: OrderParametersLib.empty(), signature: "" });
- }
-
- /**
- * @dev Gets the storage position of the default Order map.
- *
- * @return orderMap the storage position of the default Order map
- */
- function _orderMap()
- private
- pure
- returns (mapping(string => Order) storage orderMap)
- {
- bytes32 position = ORDER_MAP_POSITION;
- assembly {
- orderMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default Order array map.
- *
- * @return ordersMap the storage position of the default Order array map
- */
- function _ordersMap()
- private
- pure
- returns (mapping(string => Order[]) storage ordersMap)
- {
- bytes32 position = ORDERS_MAP_POSITION;
- assembly {
- ordersMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of an Order's fields, which
- // modify the Order in-place and return it.
-
- /**
- * @dev Sets the parameters of an Order.
- *
- * @param order the Order to set the parameters of
- * @param parameters the parameters to set
- *
- * @return _order the Order with the parameters set
- */
- function withParameters(
- Order memory order,
- OrderParameters memory parameters
- ) internal pure returns (Order memory) {
- order.parameters = parameters.copy();
- return order;
- }
-
- /**
- * @dev Sets the signature of an Order.
- *
- * @param order the Order to set the signature of
- * @param signature the signature to set
- *
- * @return _order the Order with the signature set
- */
- function withSignature(
- Order memory order,
- bytes memory signature
- ) internal pure returns (Order memory) {
- order.signature = signature;
- return order;
- }
-
- /**
- * @dev Converts an Order to an AdvancedOrder.
- *
- * @param order the Order to convert
- * @param numerator the numerator to set
- * @param denominator the denominator to set
- * @param extraData the extra data to set
- *
- * @return advancedOrder the AdvancedOrder
- */
- function toAdvancedOrder(
- Order memory order,
- uint120 numerator,
- uint120 denominator,
- bytes memory extraData
- ) internal pure returns (AdvancedOrder memory advancedOrder) {
- advancedOrder.parameters = order.parameters.copy();
- advancedOrder.numerator = numerator;
- advancedOrder.denominator = denominator;
- advancedOrder.signature = order.signature;
- advancedOrder.extraData = extraData;
- }
-
- /**
- * @dev Converts Orders to AdvancedOrders in bulk.
- *
- * @param orders the Orders to convert
- * @param numerator the numerator to set for all
- * @param denominator the denominator to set for all
- * @param extraData the extra data to set for all
- *
- * @return _advancedOrders the AdvancedOrders
- */
- function toAdvancedOrders(
- Order[] memory orders,
- uint120 numerator,
- uint120 denominator,
- bytes memory extraData
- ) internal pure returns (AdvancedOrder[] memory _advancedOrders) {
- AdvancedOrder[] memory advancedOrders = new AdvancedOrder[](
- orders.length
- );
- for (uint256 i = 0; i < orders.length; i++) {
- advancedOrders[i] = toAdvancedOrder(
- orders[i],
- numerator,
- denominator,
- extraData
- );
- }
- return advancedOrders;
- }
-
- /**
- * @dev Converts an Order to a BasicOrderParameters.
- *
- * @param order the Order to convert
- * @param basicOrderType the BasicOrderType to set
- *
- * @return basicOrderParameters the BasicOrderParameters
- */
- function toBasicOrderParameters(
- Order memory order,
- BasicOrderType basicOrderType
- ) internal pure returns (BasicOrderParameters memory basicOrderParameters) {
- basicOrderParameters.considerationToken = order
- .parameters
- .consideration[0]
- .token;
- basicOrderParameters.considerationIdentifier = order
- .parameters
- .consideration[0]
- .identifierOrCriteria;
- basicOrderParameters.considerationAmount = order
- .parameters
- .consideration[0]
- .endAmount;
- basicOrderParameters.offerer = payable(order.parameters.offerer);
- basicOrderParameters.zone = order.parameters.zone;
- basicOrderParameters.offerToken = order.parameters.offer[0].token;
- basicOrderParameters.offerIdentifier = order
- .parameters
- .offer[0]
- .identifierOrCriteria;
- basicOrderParameters.offerAmount = order.parameters.offer[0].endAmount;
- basicOrderParameters.basicOrderType = basicOrderType;
- basicOrderParameters.startTime = order.parameters.startTime;
- basicOrderParameters.endTime = order.parameters.endTime;
- basicOrderParameters.zoneHash = order.parameters.zoneHash;
- basicOrderParameters.salt = order.parameters.salt;
- basicOrderParameters.offererConduitKey = order.parameters.conduitKey;
- basicOrderParameters.fulfillerConduitKey = order.parameters.conduitKey;
- basicOrderParameters.totalOriginalAdditionalRecipients =
- order.parameters.totalOriginalConsiderationItems -
- 1;
-
- AdditionalRecipient[]
- memory additionalRecipients = new AdditionalRecipient[](
- order.parameters.consideration.length - 1
- );
- for (uint256 i = 1; i < order.parameters.consideration.length; i++) {
- additionalRecipients[i - 1] = AdditionalRecipient({
- recipient: order.parameters.consideration[i].recipient,
- amount: order.parameters.consideration[i].startAmount
- });
- }
-
- basicOrderParameters.additionalRecipients = additionalRecipients;
- basicOrderParameters.signature = order.signature;
-
- return basicOrderParameters;
- }
-}
diff --git a/contracts/helpers/sol/lib/OrderParametersLib.sol b/contracts/helpers/sol/lib/OrderParametersLib.sol
deleted file mode 100644
index 1656707e1..000000000
--- a/contracts/helpers/sol/lib/OrderParametersLib.sol
+++ /dev/null
@@ -1,807 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { ItemType, Side } from "../../../lib/ConsiderationEnums.sol";
-
-import {
- ConsiderationItem,
- CriteriaResolver,
- OrderComponents,
- OrderParameters,
- OfferItem,
- ReceivedItem,
- SpentItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { OrderType } from "../../../lib/ConsiderationEnums.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-import { OfferItemLib } from "./OfferItemLib.sol";
-
-import { ConsiderationItemLib } from "./ConsiderationItemLib.sol";
-
-/**
- * @title OrderParametersLib
- * @author James Wenzel (emo.eth)
- * @notice OrderParametersLib is a library for managing OrderParameters structs
- * and arrays. It allows chaining of functions to make struct creation
- * more readable.
- */
-library OrderParametersLib {
- using OrderParametersLib for OrderParameters;
- using OfferItemLib for OfferItem[];
- using ConsiderationItemLib for ConsiderationItem[];
- using ConsiderationItemLib for ConsiderationItem;
- using OfferItemLib for OfferItem;
-
- bytes32 private constant ORDER_PARAMETERS_MAP_POSITION =
- keccak256("seaport.OrderParametersDefaults");
- bytes32 private constant ORDER_PARAMETERS_ARRAY_MAP_POSITION =
- keccak256("seaport.OrderParametersArrayDefaults");
- bytes32 private constant EMPTY_ORDER_PARAMETERS =
- keccak256(
- abi.encode(
- OrderParameters({
- offerer: address(0),
- zone: address(0),
- offer: new OfferItem[](0),
- consideration: new ConsiderationItem[](0),
- orderType: OrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- conduitKey: bytes32(0),
- totalOriginalConsiderationItems: 0
- })
- )
- );
-
- /**
- * @dev Clears an OrderParameters from storage.
- *
- * @param parameters the OrderParameters to clear
- */
- function clear(OrderParameters storage parameters) internal {
- // uninitialized pointers take up no new memory (versus one word for initializing length-0)
- OfferItem[] memory offer;
- ConsiderationItem[] memory consideration;
-
- // clear all fields
- parameters.offerer = address(0);
- parameters.zone = address(0);
- StructCopier.setOfferItems(parameters.offer, offer);
- StructCopier.setConsiderationItems(
- parameters.consideration,
- consideration
- );
- parameters.orderType = OrderType(0);
- parameters.startTime = 0;
- parameters.endTime = 0;
- parameters.zoneHash = bytes32(0);
- parameters.salt = 0;
- parameters.conduitKey = bytes32(0);
- parameters.totalOriginalConsiderationItems = 0;
- }
-
- /**
- * @dev Clears an array of OrderParameters from storage.
- *
- * @param parameters the OrderParameters array to clear
- */
- function clear(OrderParameters[] storage parameters) internal {
- while (parameters.length > 0) {
- clear(parameters[parameters.length - 1]);
- parameters.pop();
- }
- }
-
- /**
- * @dev Clears a default OrderParameters from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => OrderParameters)
- storage orderParametersMap = _orderParametersMap();
- OrderParameters storage parameters = orderParametersMap[defaultName];
- parameters.clear();
- }
-
- /**
- * @dev Creates a new empty OrderParameters struct.
- *
- * @return item the new OrderParameters
- */
- function empty() internal pure returns (OrderParameters memory item) {
- OfferItem[] memory offer;
- ConsiderationItem[] memory consideration;
- item = OrderParameters({
- offerer: address(0),
- zone: address(0),
- offer: offer,
- consideration: consideration,
- orderType: OrderType(0),
- startTime: 0,
- endTime: 0,
- zoneHash: bytes32(0),
- salt: 0,
- conduitKey: bytes32(0),
- totalOriginalConsiderationItems: 0
- });
- }
-
- /**
- * @dev Gets a default OrderParameters from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the default OrderParameters
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (OrderParameters memory item) {
- mapping(string => OrderParameters)
- storage orderParametersMap = _orderParametersMap();
- item = orderParametersMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_ORDER_PARAMETERS) {
- revert("Empty OrderParameters selected.");
- }
- }
-
- /**
- * @dev Gets a default OrderParameters array from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return items the default OrderParameters array
- */
- function fromDefaultMany(
- string memory defaultName
- ) internal view returns (OrderParameters[] memory items) {
- mapping(string => OrderParameters[])
- storage orderParametersArrayMap = _orderParametersArrayMap();
- items = orderParametersArrayMap[defaultName];
-
- if (items.length == 0) {
- revert("Empty OrderParameters array selected.");
- }
- }
-
- /**
- * @dev Saves an OrderParameters as a named default.
- *
- * @param orderParameters the OrderParameters to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _orderParameters the OrderParameters that was saved
- */
- function saveDefault(
- OrderParameters memory orderParameters,
- string memory defaultName
- ) internal returns (OrderParameters memory _orderParameters) {
- mapping(string => OrderParameters)
- storage orderParametersMap = _orderParametersMap();
- OrderParameters storage destination = orderParametersMap[defaultName];
- StructCopier.setOrderParameters(destination, orderParameters);
- return orderParameters;
- }
-
- /**
- * @dev Saves an OrderParameters array as a named default.
- *
- * @param orderParameters the OrderParameters array to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _orderParameters the OrderParameters array that was saved
- */
- function saveDefaultMany(
- OrderParameters[] memory orderParameters,
- string memory defaultName
- ) internal returns (OrderParameters[] memory _orderParameters) {
- mapping(string => OrderParameters[])
- storage orderParametersArrayMap = _orderParametersArrayMap();
- OrderParameters[] storage destination = orderParametersArrayMap[
- defaultName
- ];
- StructCopier.setOrderParameters(destination, orderParameters);
- return orderParameters;
- }
-
- /**
- * @dev Makes a copy of an OrderParameters in-memory.
- *
- * @param item the OrderParameters to make a copy of in-memory
- *
- * @custom:return copiedOrderParameters the copied OrderParameters
- */
- function copy(
- OrderParameters memory item
- ) internal pure returns (OrderParameters memory) {
- return
- OrderParameters({
- offerer: item.offerer,
- zone: item.zone,
- offer: item.offer.copy(),
- consideration: item.consideration.copy(),
- orderType: item.orderType,
- startTime: item.startTime,
- endTime: item.endTime,
- zoneHash: item.zoneHash,
- salt: item.salt,
- conduitKey: item.conduitKey,
- totalOriginalConsiderationItems: item
- .totalOriginalConsiderationItems
- });
- }
-
- /**
- * @dev Gets the storage position of the default OrderParameters map.
- *
- * @custom:return position the storage position of the default
- * OrderParameters map
- */
- function _orderParametersMap()
- private
- pure
- returns (mapping(string => OrderParameters) storage orderParametersMap)
- {
- bytes32 position = ORDER_PARAMETERS_MAP_POSITION;
- assembly {
- orderParametersMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default OrderParameters array map.
- *
- * @custom:return position the storage position of the default
- * OrderParameters array map
- */
- function _orderParametersArrayMap()
- private
- pure
- returns (
- mapping(string => OrderParameters[]) storage orderParametersArrayMap
- )
- {
- bytes32 position = ORDER_PARAMETERS_ARRAY_MAP_POSITION;
- assembly {
- orderParametersArrayMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of a OrderParameters's fields,
- // which modify the OrderParameters struct in-place and return it.
-
- /**
- * @dev Sets the offerer field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param offerer the new value for the offerer field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withOfferer(
- OrderParameters memory parameters,
- address offerer
- ) internal pure returns (OrderParameters memory) {
- parameters.offerer = offerer;
- return parameters;
- }
-
- /**
- * @dev Sets the zone field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param zone the new value for the zone field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withZone(
- OrderParameters memory parameters,
- address zone
- ) internal pure returns (OrderParameters memory) {
- parameters.zone = zone;
- return parameters;
- }
-
- /**
- * @dev Sets the offer field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param offer the new value for the offer field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withOffer(
- OrderParameters memory parameters,
- OfferItem[] memory offer
- ) internal pure returns (OrderParameters memory) {
- parameters.offer = offer;
- return parameters;
- }
-
- /**
- * @dev Sets the consideration field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param consideration the new value for the consideration field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withConsideration(
- OrderParameters memory parameters,
- ConsiderationItem[] memory consideration
- ) internal pure returns (OrderParameters memory) {
- parameters.consideration = consideration;
- return parameters;
- }
-
- /**
- * @dev Sets the consideration field of a OrderParameters struct in-place
- * and updates the totalOriginalConsiderationItems field accordingly.
- *
- * @param parameters the OrderParameters struct to modify
- * @param consideration the new value for the consideration field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withTotalConsideration(
- OrderParameters memory parameters,
- ConsiderationItem[] memory consideration
- ) internal pure returns (OrderParameters memory) {
- parameters.consideration = consideration;
- parameters.totalOriginalConsiderationItems = consideration.length;
- return parameters;
- }
-
- /**
- * @dev Sets the orderType field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param orderType the new value for the orderType field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withOrderType(
- OrderParameters memory parameters,
- OrderType orderType
- ) internal pure returns (OrderParameters memory) {
- parameters.orderType = orderType;
- return parameters;
- }
-
- /**
- * @dev Sets the startTime field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param startTime the new value for the startTime field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withStartTime(
- OrderParameters memory parameters,
- uint256 startTime
- ) internal pure returns (OrderParameters memory) {
- parameters.startTime = startTime;
- return parameters;
- }
-
- /**
- * @dev Sets the endTime field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param endTime the new value for the endTime field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withEndTime(
- OrderParameters memory parameters,
- uint256 endTime
- ) internal pure returns (OrderParameters memory) {
- parameters.endTime = endTime;
- return parameters;
- }
-
- /**
- * @dev Sets the zoneHash field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param zoneHash the new value for the zoneHash field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withZoneHash(
- OrderParameters memory parameters,
- bytes32 zoneHash
- ) internal pure returns (OrderParameters memory) {
- parameters.zoneHash = zoneHash;
- return parameters;
- }
-
- /**
- * @dev Sets the salt field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param salt the new value for the salt field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withSalt(
- OrderParameters memory parameters,
- uint256 salt
- ) internal pure returns (OrderParameters memory) {
- parameters.salt = salt;
- return parameters;
- }
-
- /**
- * @dev Sets the conduitKey field of a OrderParameters struct in-place.
- *
- * @param parameters the OrderParameters struct to modify
- * @param conduitKey the new value for the conduitKey field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withConduitKey(
- OrderParameters memory parameters,
- bytes32 conduitKey
- ) internal pure returns (OrderParameters memory) {
- parameters.conduitKey = conduitKey;
- return parameters;
- }
-
- /**
- * @dev Sets the totalOriginalConsiderationItems field of a OrderParameters
- * struct in-place.
- *
- * @param parameters the OrderParameters struct to
- * modify
- * @param totalOriginalConsiderationItems the new value for the
- * totalOriginalConsiderationItems
- * field
- *
- * @custom:return _parameters the modified OrderParameters struct
- */
- function withTotalOriginalConsiderationItems(
- OrderParameters memory parameters,
- uint256 totalOriginalConsiderationItems
- ) internal pure returns (OrderParameters memory) {
- parameters
- .totalOriginalConsiderationItems = totalOriginalConsiderationItems;
- return parameters;
- }
-
- /**
- * @dev Converts an OrderParameters struct into an OrderComponents struct.
- *
- * @param parameters the OrderParameters struct to convert
- * @param counter the counter to use for the OrderComponents struct
- *
- * @return components the OrderComponents struct
- */
- function toOrderComponents(
- OrderParameters memory parameters,
- uint256 counter
- ) internal pure returns (OrderComponents memory components) {
- components.offerer = parameters.offerer;
- components.zone = parameters.zone;
- components.offer = parameters.offer.copy();
- components.consideration = parameters.consideration.copy();
- components.orderType = parameters.orderType;
- components.startTime = parameters.startTime;
- components.endTime = parameters.endTime;
- components.zoneHash = parameters.zoneHash;
- components.salt = parameters.salt;
- components.conduitKey = parameters.conduitKey;
- components.counter = counter;
- }
-
- function isAvailable(
- OrderParameters memory parameters
- ) internal view returns (bool) {
- return
- block.timestamp >= parameters.startTime &&
- block.timestamp < parameters.endTime;
- }
-
- function getSpentAndReceivedItems(
- OrderParameters memory parameters,
- uint256 numerator,
- uint256 denominator,
- uint256 orderIndex,
- CriteriaResolver[] memory criteriaResolvers
- )
- internal
- view
- returns (SpentItem[] memory spent, ReceivedItem[] memory received)
- {
- if (isAvailable(parameters)) {
- spent = getSpentItems(parameters, numerator, denominator);
- received = getReceivedItems(parameters, numerator, denominator);
-
- applyCriteriaResolvers(
- spent,
- received,
- orderIndex,
- criteriaResolvers
- );
- }
- }
-
- function applyCriteriaResolvers(
- SpentItem[] memory spentItems,
- ReceivedItem[] memory receivedItems,
- uint256 orderIndex,
- CriteriaResolver[] memory criteriaResolvers
- ) internal pure {
- for (uint256 i = 0; i < criteriaResolvers.length; i++) {
- CriteriaResolver memory resolver = criteriaResolvers[i];
- if (resolver.orderIndex != orderIndex) {
- continue;
- }
- if (resolver.side == Side.OFFER) {
- SpentItem memory item = spentItems[resolver.index];
- item.itemType = convertCriteriaItemType(item.itemType);
- item.identifier = resolver.identifier;
- } else {
- ReceivedItem memory item = receivedItems[resolver.index];
- item.itemType = convertCriteriaItemType(item.itemType);
- item.identifier = resolver.identifier;
- }
- }
- }
-
- function convertCriteriaItemType(
- ItemType itemType
- ) internal pure returns (ItemType) {
- if (itemType == ItemType.ERC721_WITH_CRITERIA) {
- return ItemType.ERC721;
- } else if (itemType == ItemType.ERC1155_WITH_CRITERIA) {
- return ItemType.ERC1155;
- } else {
- revert(
- "OrderParametersLib: amount deriver helper resolving non criteria item type"
- );
- }
- }
-
- function getSpentItems(
- OrderParameters memory parameters,
- uint256 numerator,
- uint256 denominator
- ) internal view returns (SpentItem[] memory) {
- return
- getSpentItems(
- parameters.offer,
- parameters.startTime,
- parameters.endTime,
- numerator,
- denominator
- );
- }
-
- function getReceivedItems(
- OrderParameters memory parameters,
- uint256 numerator,
- uint256 denominator
- ) internal view returns (ReceivedItem[] memory) {
- return
- getReceivedItems(
- parameters.consideration,
- parameters.startTime,
- parameters.endTime,
- numerator,
- denominator
- );
- }
-
- function getSpentItems(
- OfferItem[] memory items,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) internal view returns (SpentItem[] memory) {
- SpentItem[] memory spentItems = new SpentItem[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- spentItems[i] = getSpentItem(
- items[i],
- startTime,
- endTime,
- numerator,
- denominator
- );
- }
- return spentItems;
- }
-
- function getReceivedItems(
- ConsiderationItem[] memory considerationItems,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) internal view returns (ReceivedItem[] memory) {
- ReceivedItem[] memory receivedItems = new ReceivedItem[](
- considerationItems.length
- );
- for (uint256 i = 0; i < considerationItems.length; i++) {
- receivedItems[i] = getReceivedItem(
- considerationItems[i],
- startTime,
- endTime,
- numerator,
- denominator
- );
- }
- return receivedItems;
- }
-
- function getSpentItem(
- OfferItem memory item,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) internal view returns (SpentItem memory spent) {
- spent = SpentItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifierOrCriteria,
- amount: _applyFraction({
- numerator: numerator,
- denominator: denominator,
- startAmount: item.startAmount,
- endAmount: item.endAmount,
- startTime: startTime,
- endTime: endTime,
- roundUp: false
- })
- });
- }
-
- function getReceivedItem(
- ConsiderationItem memory considerationItem,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) internal view returns (ReceivedItem memory received) {
- received = ReceivedItem({
- itemType: considerationItem.itemType,
- token: considerationItem.token,
- identifier: considerationItem.identifierOrCriteria,
- amount: _applyFraction({
- numerator: numerator,
- denominator: denominator,
- startAmount: considerationItem.startAmount,
- endAmount: considerationItem.endAmount,
- startTime: startTime,
- endTime: endTime,
- roundUp: true
- }),
- recipient: considerationItem.recipient
- });
- }
-
- function _applyFraction(
- uint256 startAmount,
- uint256 endAmount,
- uint256 numerator,
- uint256 denominator,
- uint256 startTime,
- uint256 endTime,
- bool roundUp
- ) internal view returns (uint256 amount) {
- // If start amount equals end amount, apply fraction to end amount.
- if (startAmount == endAmount) {
- // Apply fraction to end amount.
- amount = _getFraction(numerator, denominator, endAmount);
- } else {
- // Otherwise, apply fraction to both and interpolated final amount.
- amount = _locateCurrentAmount(
- _getFraction(numerator, denominator, startAmount),
- _getFraction(numerator, denominator, endAmount),
- startTime,
- endTime,
- roundUp
- );
- }
- }
-
- function _getFraction(
- uint256 numerator,
- uint256 denominator,
- uint256 value
- ) internal pure returns (uint256 newValue) {
- // Return value early in cases where the fraction resolves to 1.
- if (numerator == denominator) {
- return value;
- }
-
- bool failure = false;
-
- // Ensure fraction can be applied to the value with no remainder. Note
- // that the denominator cannot be zero.
- assembly {
- // Ensure new value contains no remainder via mulmod operator.
- // Credit to @hrkrshnn + @axic for proposing this optimal solution.
- if mulmod(value, numerator, denominator) {
- failure := true
- }
- }
-
- if (failure) {
- revert("OrderParametersLib: bad fraction");
- }
-
- // Multiply the numerator by the value and ensure no overflow occurs.
- uint256 valueTimesNumerator = value * numerator;
-
- // Divide and check for remainder. Note that denominator cannot be zero.
- assembly {
- // Perform division without zero check.
- newValue := div(valueTimesNumerator, denominator)
- }
- }
-
- function _locateCurrentAmount(
- uint256 startAmount,
- uint256 endAmount,
- uint256 startTime,
- uint256 endTime,
- bool roundUp
- ) internal view returns (uint256 amount) {
- // Only modify end amount if it doesn't already equal start amount.
- if (startAmount != endAmount) {
- // Declare variables to derive in the subsequent unchecked scope.
- uint256 duration;
- uint256 elapsed;
- uint256 remaining;
-
- // Skip underflow checks as startTime <= block.timestamp < endTime.
- unchecked {
- // Derive the duration for the order and place it on the stack.
- duration = endTime - startTime;
-
- // Derive time elapsed since the order started & place on stack.
- elapsed = block.timestamp - startTime;
-
- // Derive time remaining until order expires and place on stack.
- remaining = duration - elapsed;
- }
-
- // Aggregate new amounts weighted by time with rounding factor.
- uint256 totalBeforeDivision = ((startAmount * remaining) +
- (endAmount * elapsed));
-
- // Use assembly to combine operations and skip divide-by-zero check.
- assembly {
- // Multiply by iszero(iszero(totalBeforeDivision)) to ensure
- // amount is set to zero if totalBeforeDivision is zero,
- // as intermediate overflow can occur if it is zero.
- amount := mul(
- iszero(iszero(totalBeforeDivision)),
- // Subtract 1 from the numerator and add 1 to the result if
- // roundUp is true to get the proper rounding direction.
- // Division is performed with no zero check as duration
- // cannot be zero as long as startTime < endTime.
- add(
- div(sub(totalBeforeDivision, roundUp), duration),
- roundUp
- )
- )
- }
-
- // Return the current amount.
- return amount;
- }
-
- // Return the original amount as startAmount == endAmount.
- return endAmount;
- }
-}
diff --git a/contracts/helpers/sol/lib/ReceivedItemLib.sol b/contracts/helpers/sol/lib/ReceivedItemLib.sol
deleted file mode 100644
index ce7c72d3d..000000000
--- a/contracts/helpers/sol/lib/ReceivedItemLib.sol
+++ /dev/null
@@ -1,371 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- ConsiderationItem,
- ReceivedItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { ItemType } from "../../../lib/ConsiderationEnums.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-/**
- * @title ReceivedItemLib
- * @author James Wenzel (emo.eth)
- * @notice ReceivedItemLib is a library for managing ReceivedItem structs and
- * arrays. It allows chaining of functions to make struct creation more
- * readable.
- */
-library ReceivedItemLib {
- bytes32 private constant RECEIVED_ITEM_MAP_POSITION =
- keccak256("seaport.ReceivedItemDefaults");
- bytes32 private constant RECEIVED_ITEMS_MAP_POSITION =
- keccak256("seaport.ReceivedItemsDefaults");
- bytes32 private constant EMPTY_RECEIVED_ITEM =
- keccak256(
- abi.encode(
- ReceivedItem({
- itemType: ItemType(0),
- token: address(0),
- identifier: 0,
- amount: 0,
- recipient: payable(address(0))
- })
- )
- );
-
- /**
- * @dev Clears a default ReceivedItem from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => ReceivedItem)
- storage receivedItemMap = _receivedItemMap();
- ReceivedItem storage item = receivedItemMap[defaultName];
- clear(item);
- }
-
- /**
- * @dev Clears all fields on a ReceivedItem.
- *
- * @param item the ReceivedItem to clear
- */
- function clear(ReceivedItem storage item) internal {
- // clear all fields
- item.itemType = ItemType.NATIVE;
- item.token = address(0);
- item.identifier = 0;
- item.amount = 0;
- item.recipient = payable(address(0));
- }
-
- /**
- * @dev Clears an array of ReceivedItems from storage.
- *
- * @param defaultsName the name of the default to clear
- */
- function clearMany(string memory defaultsName) internal {
- mapping(string => ReceivedItem[])
- storage receivedItemsMap = _receivedItemsMap();
- ReceivedItem[] storage items = receivedItemsMap[defaultsName];
- clearMany(items);
- }
-
- /**
- * @dev Clears an array of ReceivedItems from storage.
- *
- * @param items the ReceivedItems to clear
- */
- function clearMany(ReceivedItem[] storage items) internal {
- while (items.length > 0) {
- clear(items[items.length - 1]);
- items.pop();
- }
- }
-
- /**
- * @dev Creates an empty ReceivedItem.
- *
- * @return the empty ReceivedItem
- */
- function empty() internal pure returns (ReceivedItem memory) {
- return
- ReceivedItem({
- itemType: ItemType(0),
- token: address(0),
- identifier: 0,
- amount: 0,
- recipient: payable(address(0))
- });
- }
-
- /**
- * @dev Gets a default ReceivedItem from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the default ReceivedItem
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (ReceivedItem memory item) {
- mapping(string => ReceivedItem)
- storage receivedItemMap = _receivedItemMap();
- item = receivedItemMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_RECEIVED_ITEM) {
- revert("Empty ReceivedItem selected.");
- }
- }
-
- /**
- * @dev Gets a default ReceivedItem from storage.
- *
- * @param defaultsName the name of the default for retrieval
- *
- * @return items the default ReceivedItem
- */
- function fromDefaultMany(
- string memory defaultsName
- ) internal view returns (ReceivedItem[] memory items) {
- mapping(string => ReceivedItem[])
- storage receivedItemsMap = _receivedItemsMap();
- items = receivedItemsMap[defaultsName];
-
- if (items.length == 0) {
- revert("Empty ReceivedItem array selected.");
- }
- }
-
- /**
- * @dev Saves an ReceivedItem as a named default.
- *
- * @param receivedItem the ReceivedItem to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _receivedItem the saved ReceivedItem
- */
- function saveDefault(
- ReceivedItem memory receivedItem,
- string memory defaultName
- ) internal returns (ReceivedItem memory _receivedItem) {
- mapping(string => ReceivedItem)
- storage receivedItemMap = _receivedItemMap();
- receivedItemMap[defaultName] = receivedItem;
- return receivedItem;
- }
-
- /**
- * @dev Saves an ReceivedItem as a named default.
- *
- * @param receivedItems the ReceivedItem to save as a default
- * @param defaultsName the name of the default for retrieval
- *
- * @return _receivedItems the saved ReceivedItem
- */
- function saveDefaultMany(
- ReceivedItem[] memory receivedItems,
- string memory defaultsName
- ) internal returns (ReceivedItem[] memory _receivedItems) {
- mapping(string => ReceivedItem[])
- storage receivedItemsMap = _receivedItemsMap();
- ReceivedItem[] storage items = receivedItemsMap[defaultsName];
- setReceivedItems(items, receivedItems);
- return receivedItems;
- }
-
- /**
- * @dev Sets an array of in-memory ReceivedItems to an array of
- * ReceivedItems in storage.
- *
- * @param items the ReceivedItems array in storage to push to
- * @param newItems the ReceivedItems array in memory to push onto the items
- * array
- */
- function setReceivedItems(
- ReceivedItem[] storage items,
- ReceivedItem[] memory newItems
- ) internal {
- clearMany(items);
- for (uint256 i = 0; i < newItems.length; i++) {
- items.push(newItems[i]);
- }
- }
-
- /**
- * @dev Makes a copy of an ReceivedItem in-memory.
- *
- * @param item the ReceivedItem to make a copy of in-memory
- *
- * @custom:return copiedReceivedItem the copied ReceivedItem
- */
- function copy(
- ReceivedItem memory item
- ) internal pure returns (ReceivedItem memory) {
- return
- ReceivedItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifier,
- amount: item.amount,
- recipient: item.recipient
- });
- }
-
- /**
- * @dev Makes a copy of an array of ReceivedItems in-memory.
- *
- * @param item the ReceivedItems array to make a copy of in-memory
- *
- * @custom:return copiedReceivedItems the copied ReceivedItems
- */
- function copy(
- ReceivedItem[] memory item
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory copies = new ReceivedItem[](item.length);
- for (uint256 i = 0; i < item.length; i++) {
- copies[i] = ReceivedItemLib.copy(item[i]);
- }
- return copies;
- }
-
- /**
- * @dev Gets the storage position of the default ReceivedItem map.
- *
- * @custom:return receivedItemMap the storage position of the default
- * ReceivedItem map
- */
- function _receivedItemMap()
- private
- pure
- returns (mapping(string => ReceivedItem) storage receivedItemMap)
- {
- bytes32 position = RECEIVED_ITEM_MAP_POSITION;
- assembly {
- receivedItemMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default ReceivedItem array map.
- *
- * @custom:return receivedItemsMap the storage position of the default
- * ReceivedItem array map
- */
- function _receivedItemsMap()
- private
- pure
- returns (mapping(string => ReceivedItem[]) storage receivedItemsMap)
- {
- bytes32 position = RECEIVED_ITEMS_MAP_POSITION;
- assembly {
- receivedItemsMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of a ReceivedItem's fields,
- // which modify the ReceivedItem struct in-place and return it.
-
- /**
- * @dev Sets the itemType field of an ReceivedItem.
- *
- * @param item the ReceivedItem to set the itemType field of
- * @param itemType the itemType to set the itemType field to
- *
- * @custom:return item the ReceivedItem with the itemType field set
- */
- function withItemType(
- ReceivedItem memory item,
- ItemType itemType
- ) internal pure returns (ReceivedItem memory) {
- item.itemType = itemType;
- return item;
- }
-
- /**
- * @dev Sets the token field of an ReceivedItem.
- *
- * @param item the ReceivedItem to set the token field of
- * @param token the token to set the token field to
- *
- * @custom:return item the ReceivedItem with the token field set
- */
- function withToken(
- ReceivedItem memory item,
- address token
- ) internal pure returns (ReceivedItem memory) {
- item.token = token;
- return item;
- }
-
- /**
- * @dev Sets the identifier field of an ReceivedItem.
- *
- * @param item the ReceivedItem to set the identifier field of
- * @param identifier the identifier to set the identifier field to
- *
- * @custom:return item the ReceivedItem with the identifier field set
- */
- function withIdentifier(
- ReceivedItem memory item,
- uint256 identifier
- ) internal pure returns (ReceivedItem memory) {
- item.identifier = identifier;
- return item;
- }
-
- /**
- * @dev Sets the amount field of an ReceivedItem.
- *
- * @param item the ReceivedItem to set the amount field of
- * @param amount the amount to set the amount field to
- *
- * @custom:return item the ReceivedItem with the amount field set
- */
- function withAmount(
- ReceivedItem memory item,
- uint256 amount
- ) internal pure returns (ReceivedItem memory) {
- item.amount = amount;
- return item;
- }
-
- /**
- * @dev Sets the recipient field of an ReceivedItem.
- *
- * @param item the ReceivedItem to set the recipient field of
- * @param recipient the recipient to set the recipient field to
- *
- * @custom:return item the ReceivedItem with the recipient field set
- */
- function withRecipient(
- ReceivedItem memory item,
- address recipient
- ) internal pure returns (ReceivedItem memory) {
- item.recipient = payable(recipient);
- return item;
- }
-
- /**
- * @dev Converts an ReceivedItem to a ConsiderationItem.
- *
- * @param item the ReceivedItem to convert to a ConsiderationItem
- *
- * @custom:return considerationItem the converted ConsiderationItem
- */
- function toConsiderationItem(
- ReceivedItem memory item
- ) internal pure returns (ConsiderationItem memory) {
- return
- ConsiderationItem({
- itemType: item.itemType,
- token: item.token,
- identifierOrCriteria: item.identifier,
- startAmount: item.amount,
- endAmount: item.amount,
- recipient: item.recipient
- });
- }
-}
diff --git a/contracts/helpers/sol/lib/SeaportArrays.sol b/contracts/helpers/sol/lib/SeaportArrays.sol
deleted file mode 100644
index 7372b2487..000000000
--- a/contracts/helpers/sol/lib/SeaportArrays.sol
+++ /dev/null
@@ -1,1390 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- AdditionalRecipient,
- AdvancedOrder,
- BasicOrderParameters,
- ConsiderationItem,
- CriteriaResolver,
- Fulfillment,
- FulfillmentComponent,
- OfferItem,
- Order,
- OrderComponents,
- OrderParameters,
- ReceivedItem,
- SpentItem
-} from "../../../lib/ConsiderationStructs.sol";
-
-library SeaportArrays {
- function Orders(Order memory a) internal pure returns (Order[] memory) {
- Order[] memory arr = new Order[](1);
- arr[0] = a;
- return arr;
- }
-
- function Orders(
- Order memory a,
- Order memory b
- ) internal pure returns (Order[] memory) {
- Order[] memory arr = new Order[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function Orders(
- Order memory a,
- Order memory b,
- Order memory c
- ) internal pure returns (Order[] memory) {
- Order[] memory arr = new Order[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function Orders(
- Order memory a,
- Order memory b,
- Order memory c,
- Order memory d
- ) internal pure returns (Order[] memory) {
- Order[] memory arr = new Order[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function Orders(
- Order memory a,
- Order memory b,
- Order memory c,
- Order memory d,
- Order memory e
- ) internal pure returns (Order[] memory) {
- Order[] memory arr = new Order[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function Orders(
- Order memory a,
- Order memory b,
- Order memory c,
- Order memory d,
- Order memory e,
- Order memory f
- ) internal pure returns (Order[] memory) {
- Order[] memory arr = new Order[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function Orders(
- Order memory a,
- Order memory b,
- Order memory c,
- Order memory d,
- Order memory e,
- Order memory f,
- Order memory g
- ) internal pure returns (Order[] memory) {
- Order[] memory arr = new Order[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function AdvancedOrders(
- AdvancedOrder memory a
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory arr = new AdvancedOrder[](1);
- arr[0] = a;
- return arr;
- }
-
- function AdvancedOrders(
- AdvancedOrder memory a,
- AdvancedOrder memory b
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory arr = new AdvancedOrder[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function AdvancedOrders(
- AdvancedOrder memory a,
- AdvancedOrder memory b,
- AdvancedOrder memory c
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory arr = new AdvancedOrder[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function AdvancedOrders(
- AdvancedOrder memory a,
- AdvancedOrder memory b,
- AdvancedOrder memory c,
- AdvancedOrder memory d
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory arr = new AdvancedOrder[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function AdvancedOrders(
- AdvancedOrder memory a,
- AdvancedOrder memory b,
- AdvancedOrder memory c,
- AdvancedOrder memory d,
- AdvancedOrder memory e
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory arr = new AdvancedOrder[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function AdvancedOrders(
- AdvancedOrder memory a,
- AdvancedOrder memory b,
- AdvancedOrder memory c,
- AdvancedOrder memory d,
- AdvancedOrder memory e,
- AdvancedOrder memory f
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory arr = new AdvancedOrder[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function AdvancedOrders(
- AdvancedOrder memory a,
- AdvancedOrder memory b,
- AdvancedOrder memory c,
- AdvancedOrder memory d,
- AdvancedOrder memory e,
- AdvancedOrder memory f,
- AdvancedOrder memory g
- ) internal pure returns (AdvancedOrder[] memory) {
- AdvancedOrder[] memory arr = new AdvancedOrder[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function OrderComponentsArray(
- OrderComponents memory a
- ) internal pure returns (OrderComponents[] memory) {
- OrderComponents[] memory arr = new OrderComponents[](1);
- arr[0] = a;
- return arr;
- }
-
- function OrderComponentsArray(
- OrderComponents memory a,
- OrderComponents memory b
- ) internal pure returns (OrderComponents[] memory) {
- OrderComponents[] memory arr = new OrderComponents[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function OrderComponentsArray(
- OrderComponents memory a,
- OrderComponents memory b,
- OrderComponents memory c
- ) internal pure returns (OrderComponents[] memory) {
- OrderComponents[] memory arr = new OrderComponents[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function OrderComponentsArray(
- OrderComponents memory a,
- OrderComponents memory b,
- OrderComponents memory c,
- OrderComponents memory d
- ) internal pure returns (OrderComponents[] memory) {
- OrderComponents[] memory arr = new OrderComponents[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function OrderComponentsArray(
- OrderComponents memory a,
- OrderComponents memory b,
- OrderComponents memory c,
- OrderComponents memory d,
- OrderComponents memory e
- ) internal pure returns (OrderComponents[] memory) {
- OrderComponents[] memory arr = new OrderComponents[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function OrderComponentsArray(
- OrderComponents memory a,
- OrderComponents memory b,
- OrderComponents memory c,
- OrderComponents memory d,
- OrderComponents memory e,
- OrderComponents memory f
- ) internal pure returns (OrderComponents[] memory) {
- OrderComponents[] memory arr = new OrderComponents[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function OrderComponentsArray(
- OrderComponents memory a,
- OrderComponents memory b,
- OrderComponents memory c,
- OrderComponents memory d,
- OrderComponents memory e,
- OrderComponents memory f,
- OrderComponents memory g
- ) internal pure returns (OrderComponents[] memory) {
- OrderComponents[] memory arr = new OrderComponents[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function OrderParametersArray(
- OrderParameters memory a
- ) internal pure returns (OrderParameters[] memory) {
- OrderParameters[] memory arr = new OrderParameters[](1);
- arr[0] = a;
- return arr;
- }
-
- function OrderParametersArray(
- OrderParameters memory a,
- OrderParameters memory b
- ) internal pure returns (OrderParameters[] memory) {
- OrderParameters[] memory arr = new OrderParameters[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function OrderParametersArray(
- OrderParameters memory a,
- OrderParameters memory b,
- OrderParameters memory c
- ) internal pure returns (OrderParameters[] memory) {
- OrderParameters[] memory arr = new OrderParameters[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function OrderParametersArray(
- OrderParameters memory a,
- OrderParameters memory b,
- OrderParameters memory c,
- OrderParameters memory d
- ) internal pure returns (OrderParameters[] memory) {
- OrderParameters[] memory arr = new OrderParameters[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function OrderParametersArray(
- OrderParameters memory a,
- OrderParameters memory b,
- OrderParameters memory c,
- OrderParameters memory d,
- OrderParameters memory e
- ) internal pure returns (OrderParameters[] memory) {
- OrderParameters[] memory arr = new OrderParameters[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function OrderParametersArray(
- OrderParameters memory a,
- OrderParameters memory b,
- OrderParameters memory c,
- OrderParameters memory d,
- OrderParameters memory e,
- OrderParameters memory f
- ) internal pure returns (OrderParameters[] memory) {
- OrderParameters[] memory arr = new OrderParameters[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function OrderParametersArray(
- OrderParameters memory a,
- OrderParameters memory b,
- OrderParameters memory c,
- OrderParameters memory d,
- OrderParameters memory e,
- OrderParameters memory f,
- OrderParameters memory g
- ) internal pure returns (OrderParameters[] memory) {
- OrderParameters[] memory arr = new OrderParameters[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function OfferItems(
- OfferItem memory a
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory arr = new OfferItem[](1);
- arr[0] = a;
- return arr;
- }
-
- function OfferItems(
- OfferItem memory a,
- OfferItem memory b
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory arr = new OfferItem[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function OfferItems(
- OfferItem memory a,
- OfferItem memory b,
- OfferItem memory c
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory arr = new OfferItem[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function OfferItems(
- OfferItem memory a,
- OfferItem memory b,
- OfferItem memory c,
- OfferItem memory d
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory arr = new OfferItem[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function OfferItems(
- OfferItem memory a,
- OfferItem memory b,
- OfferItem memory c,
- OfferItem memory d,
- OfferItem memory e
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory arr = new OfferItem[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function OfferItems(
- OfferItem memory a,
- OfferItem memory b,
- OfferItem memory c,
- OfferItem memory d,
- OfferItem memory e,
- OfferItem memory f
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory arr = new OfferItem[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function OfferItems(
- OfferItem memory a,
- OfferItem memory b,
- OfferItem memory c,
- OfferItem memory d,
- OfferItem memory e,
- OfferItem memory f,
- OfferItem memory g
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory arr = new OfferItem[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function ConsiderationItems(
- ConsiderationItem memory a
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory arr = new ConsiderationItem[](1);
- arr[0] = a;
- return arr;
- }
-
- function ConsiderationItems(
- ConsiderationItem memory a,
- ConsiderationItem memory b
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory arr = new ConsiderationItem[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function ConsiderationItems(
- ConsiderationItem memory a,
- ConsiderationItem memory b,
- ConsiderationItem memory c
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory arr = new ConsiderationItem[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function ConsiderationItems(
- ConsiderationItem memory a,
- ConsiderationItem memory b,
- ConsiderationItem memory c,
- ConsiderationItem memory d
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory arr = new ConsiderationItem[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function ConsiderationItems(
- ConsiderationItem memory a,
- ConsiderationItem memory b,
- ConsiderationItem memory c,
- ConsiderationItem memory d,
- ConsiderationItem memory e
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory arr = new ConsiderationItem[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function ConsiderationItems(
- ConsiderationItem memory a,
- ConsiderationItem memory b,
- ConsiderationItem memory c,
- ConsiderationItem memory d,
- ConsiderationItem memory e,
- ConsiderationItem memory f
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory arr = new ConsiderationItem[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function ConsiderationItems(
- ConsiderationItem memory a,
- ConsiderationItem memory b,
- ConsiderationItem memory c,
- ConsiderationItem memory d,
- ConsiderationItem memory e,
- ConsiderationItem memory f,
- ConsiderationItem memory g
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory arr = new ConsiderationItem[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function SpentItems(
- SpentItem memory a
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory arr = new SpentItem[](1);
- arr[0] = a;
- return arr;
- }
-
- function SpentItems(
- SpentItem memory a,
- SpentItem memory b
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory arr = new SpentItem[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function SpentItems(
- SpentItem memory a,
- SpentItem memory b,
- SpentItem memory c
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory arr = new SpentItem[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function SpentItems(
- SpentItem memory a,
- SpentItem memory b,
- SpentItem memory c,
- SpentItem memory d
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory arr = new SpentItem[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function SpentItems(
- SpentItem memory a,
- SpentItem memory b,
- SpentItem memory c,
- SpentItem memory d,
- SpentItem memory e
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory arr = new SpentItem[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function SpentItems(
- SpentItem memory a,
- SpentItem memory b,
- SpentItem memory c,
- SpentItem memory d,
- SpentItem memory e,
- SpentItem memory f
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory arr = new SpentItem[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function SpentItems(
- SpentItem memory a,
- SpentItem memory b,
- SpentItem memory c,
- SpentItem memory d,
- SpentItem memory e,
- SpentItem memory f,
- SpentItem memory g
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory arr = new SpentItem[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function ReceivedItems(
- ReceivedItem memory a
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory arr = new ReceivedItem[](1);
- arr[0] = a;
- return arr;
- }
-
- function ReceivedItems(
- ReceivedItem memory a,
- ReceivedItem memory b
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory arr = new ReceivedItem[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function ReceivedItems(
- ReceivedItem memory a,
- ReceivedItem memory b,
- ReceivedItem memory c
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory arr = new ReceivedItem[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function ReceivedItems(
- ReceivedItem memory a,
- ReceivedItem memory b,
- ReceivedItem memory c,
- ReceivedItem memory d
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory arr = new ReceivedItem[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function ReceivedItems(
- ReceivedItem memory a,
- ReceivedItem memory b,
- ReceivedItem memory c,
- ReceivedItem memory d,
- ReceivedItem memory e
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory arr = new ReceivedItem[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function ReceivedItems(
- ReceivedItem memory a,
- ReceivedItem memory b,
- ReceivedItem memory c,
- ReceivedItem memory d,
- ReceivedItem memory e,
- ReceivedItem memory f
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory arr = new ReceivedItem[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function ReceivedItems(
- ReceivedItem memory a,
- ReceivedItem memory b,
- ReceivedItem memory c,
- ReceivedItem memory d,
- ReceivedItem memory e,
- ReceivedItem memory f,
- ReceivedItem memory g
- ) internal pure returns (ReceivedItem[] memory) {
- ReceivedItem[] memory arr = new ReceivedItem[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](1);
- arr[0] = a;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e,
- FulfillmentComponent memory f
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function FulfillmentComponents(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b,
- FulfillmentComponent memory c,
- FulfillmentComponent memory d,
- FulfillmentComponent memory e,
- FulfillmentComponent memory f,
- FulfillmentComponent memory g
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[] memory arr = new FulfillmentComponent[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](1);
- arr[0] = a;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e,
- FulfillmentComponent[] memory f
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function FulfillmentComponentArrays(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b,
- FulfillmentComponent[] memory c,
- FulfillmentComponent[] memory d,
- FulfillmentComponent[] memory e,
- FulfillmentComponent[] memory f,
- FulfillmentComponent[] memory g
- ) internal pure returns (FulfillmentComponent[][] memory) {
- FulfillmentComponent[][] memory arr = new FulfillmentComponent[][](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function CriteriaResolvers(
- CriteriaResolver memory a
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory arr = new CriteriaResolver[](1);
- arr[0] = a;
- return arr;
- }
-
- function CriteriaResolvers(
- CriteriaResolver memory a,
- CriteriaResolver memory b
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory arr = new CriteriaResolver[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function CriteriaResolvers(
- CriteriaResolver memory a,
- CriteriaResolver memory b,
- CriteriaResolver memory c
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory arr = new CriteriaResolver[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function CriteriaResolvers(
- CriteriaResolver memory a,
- CriteriaResolver memory b,
- CriteriaResolver memory c,
- CriteriaResolver memory d
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory arr = new CriteriaResolver[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function CriteriaResolvers(
- CriteriaResolver memory a,
- CriteriaResolver memory b,
- CriteriaResolver memory c,
- CriteriaResolver memory d,
- CriteriaResolver memory e
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory arr = new CriteriaResolver[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function CriteriaResolvers(
- CriteriaResolver memory a,
- CriteriaResolver memory b,
- CriteriaResolver memory c,
- CriteriaResolver memory d,
- CriteriaResolver memory e,
- CriteriaResolver memory f
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory arr = new CriteriaResolver[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function CriteriaResolvers(
- CriteriaResolver memory a,
- CriteriaResolver memory b,
- CriteriaResolver memory c,
- CriteriaResolver memory d,
- CriteriaResolver memory e,
- CriteriaResolver memory f,
- CriteriaResolver memory g
- ) internal pure returns (CriteriaResolver[] memory) {
- CriteriaResolver[] memory arr = new CriteriaResolver[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function AdditionalRecipients(
- AdditionalRecipient memory a
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory arr = new AdditionalRecipient[](1);
- arr[0] = a;
- return arr;
- }
-
- function AdditionalRecipients(
- AdditionalRecipient memory a,
- AdditionalRecipient memory b
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory arr = new AdditionalRecipient[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function AdditionalRecipients(
- AdditionalRecipient memory a,
- AdditionalRecipient memory b,
- AdditionalRecipient memory c
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory arr = new AdditionalRecipient[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function AdditionalRecipients(
- AdditionalRecipient memory a,
- AdditionalRecipient memory b,
- AdditionalRecipient memory c,
- AdditionalRecipient memory d
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory arr = new AdditionalRecipient[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function AdditionalRecipients(
- AdditionalRecipient memory a,
- AdditionalRecipient memory b,
- AdditionalRecipient memory c,
- AdditionalRecipient memory d,
- AdditionalRecipient memory e
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory arr = new AdditionalRecipient[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function AdditionalRecipients(
- AdditionalRecipient memory a,
- AdditionalRecipient memory b,
- AdditionalRecipient memory c,
- AdditionalRecipient memory d,
- AdditionalRecipient memory e,
- AdditionalRecipient memory f
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory arr = new AdditionalRecipient[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function AdditionalRecipients(
- AdditionalRecipient memory a,
- AdditionalRecipient memory b,
- AdditionalRecipient memory c,
- AdditionalRecipient memory d,
- AdditionalRecipient memory e,
- AdditionalRecipient memory f,
- AdditionalRecipient memory g
- ) internal pure returns (AdditionalRecipient[] memory) {
- AdditionalRecipient[] memory arr = new AdditionalRecipient[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function BasicOrderParametersArray(
- BasicOrderParameters memory a
- ) internal pure returns (BasicOrderParameters[] memory) {
- BasicOrderParameters[] memory arr = new BasicOrderParameters[](1);
- arr[0] = a;
- return arr;
- }
-
- function BasicOrderParametersArray(
- BasicOrderParameters memory a,
- BasicOrderParameters memory b
- ) internal pure returns (BasicOrderParameters[] memory) {
- BasicOrderParameters[] memory arr = new BasicOrderParameters[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function BasicOrderParametersArray(
- BasicOrderParameters memory a,
- BasicOrderParameters memory b,
- BasicOrderParameters memory c
- ) internal pure returns (BasicOrderParameters[] memory) {
- BasicOrderParameters[] memory arr = new BasicOrderParameters[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function BasicOrderParametersArray(
- BasicOrderParameters memory a,
- BasicOrderParameters memory b,
- BasicOrderParameters memory c,
- BasicOrderParameters memory d
- ) internal pure returns (BasicOrderParameters[] memory) {
- BasicOrderParameters[] memory arr = new BasicOrderParameters[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function BasicOrderParametersArray(
- BasicOrderParameters memory a,
- BasicOrderParameters memory b,
- BasicOrderParameters memory c,
- BasicOrderParameters memory d,
- BasicOrderParameters memory e
- ) internal pure returns (BasicOrderParameters[] memory) {
- BasicOrderParameters[] memory arr = new BasicOrderParameters[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function BasicOrderParametersArray(
- BasicOrderParameters memory a,
- BasicOrderParameters memory b,
- BasicOrderParameters memory c,
- BasicOrderParameters memory d,
- BasicOrderParameters memory e,
- BasicOrderParameters memory f
- ) internal pure returns (BasicOrderParameters[] memory) {
- BasicOrderParameters[] memory arr = new BasicOrderParameters[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function BasicOrderParametersArray(
- BasicOrderParameters memory a,
- BasicOrderParameters memory b,
- BasicOrderParameters memory c,
- BasicOrderParameters memory d,
- BasicOrderParameters memory e,
- BasicOrderParameters memory f,
- BasicOrderParameters memory g
- ) internal pure returns (BasicOrderParameters[] memory) {
- BasicOrderParameters[] memory arr = new BasicOrderParameters[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](1);
- arr[0] = a;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](2);
- arr[0] = a;
- arr[1] = b;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](3);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](4);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](5);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e,
- Fulfillment memory f
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](6);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- return arr;
- }
-
- function Fulfillments(
- Fulfillment memory a,
- Fulfillment memory b,
- Fulfillment memory c,
- Fulfillment memory d,
- Fulfillment memory e,
- Fulfillment memory f,
- Fulfillment memory g
- ) internal pure returns (Fulfillment[] memory) {
- Fulfillment[] memory arr = new Fulfillment[](7);
- arr[0] = a;
- arr[1] = b;
- arr[2] = c;
- arr[3] = d;
- arr[4] = e;
- arr[5] = f;
- arr[6] = g;
- return arr;
- }
-}
diff --git a/contracts/helpers/sol/lib/SeaportEnumsLib.sol b/contracts/helpers/sol/lib/SeaportEnumsLib.sol
deleted file mode 100644
index d53216640..000000000
--- a/contracts/helpers/sol/lib/SeaportEnumsLib.sol
+++ /dev/null
@@ -1,61 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import {
- BasicOrderType,
- ItemType,
- OrderType
-} from "../../../lib/ConsiderationEnums.sol";
-
-library SeaportEnumsLib {
- /**
- * @dev Parses a BasicOrderType into its constituent parts.
- *
- * @param basicOrderType the BasicOrderType to parse
- *
- * @return orderType the OrderType
- * @return offerType the ItemType of the offer
- * @return considerationType the ItemType of the
- * consideration
- * @return additionalRecipientsType the ItemType of the
- * additional recipients
- * @return offerTypeIsAdditionalRecipientsType whether the offer type is the
- * additional recipients type
- */
- function parseBasicOrderType(
- BasicOrderType basicOrderType
- )
- internal
- pure
- returns (
- OrderType orderType,
- ItemType offerType,
- ItemType considerationType,
- ItemType additionalRecipientsType,
- bool offerTypeIsAdditionalRecipientsType
- )
- {
- assembly {
- // Mask all but 2 least-significant bits to derive the order type.
- orderType := and(basicOrderType, 3)
-
- // Divide basicOrderType by four to derive the route.
- let route := shr(2, basicOrderType)
- offerTypeIsAdditionalRecipientsType := gt(route, 3)
-
- // If route > 1 additionalRecipient items are ERC20 (1) else Eth (0)
- additionalRecipientsType := gt(route, 1)
-
- // If route > 2, receivedItemType is route - 2. If route is 2,
- // the receivedItemType is ERC20 (1). Otherwise, it is Eth (0).
- considerationType := add(
- mul(sub(route, 2), gt(route, 2)),
- eq(route, 2)
- )
-
- // If route > 3, offeredItemType is ERC20 (1). Route is 2 or 3,
- // offeredItemType = route. Route is 0 or 1, it is route + 2.
- offerType := add(route, mul(iszero(additionalRecipientsType), 2))
- }
- }
-}
diff --git a/contracts/helpers/sol/lib/SeaportStructLib.sol b/contracts/helpers/sol/lib/SeaportStructLib.sol
deleted file mode 100644
index 08cef330f..000000000
--- a/contracts/helpers/sol/lib/SeaportStructLib.sol
+++ /dev/null
@@ -1,21 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { AdditionalRecipientLib } from "./AdditionalRecipientLib.sol";
-import { AdvancedOrderLib } from "./AdvancedOrderLib.sol";
-import { ArrayLib } from "./ArrayLib.sol";
-import { BasicOrderParametersLib } from "./BasicOrderParametersLib.sol";
-import { ConsiderationItemLib } from "./ConsiderationItemLib.sol";
-import { CriteriaResolverLib } from "./CriteriaResolverLib.sol";
-import { ExecutionLib } from "./ExecutionLib.sol";
-import { FulfillmentComponentLib } from "./FulfillmentComponentLib.sol";
-import { FulfillmentLib } from "./FulfillmentLib.sol";
-import { OfferItemLib } from "./OfferItemLib.sol";
-import { OrderComponentsLib } from "./OrderComponentsLib.sol";
-import { OrderLib } from "./OrderLib.sol";
-import { OrderParametersLib } from "./OrderParametersLib.sol";
-import { ReceivedItemLib } from "./ReceivedItemLib.sol";
-import { SeaportArrays } from "./SeaportArrays.sol";
-import { SpentItemLib } from "./SpentItemLib.sol";
-import { StructCopier } from "./StructCopier.sol";
-import { ZoneParametersLib } from "./ZoneParametersLib.sol";
diff --git a/contracts/helpers/sol/lib/SpentItemLib.sol b/contracts/helpers/sol/lib/SpentItemLib.sol
deleted file mode 100644
index 417d996ad..000000000
--- a/contracts/helpers/sol/lib/SpentItemLib.sol
+++ /dev/null
@@ -1,332 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { OfferItem, SpentItem } from "../../../lib/ConsiderationStructs.sol";
-
-import { ItemType } from "../../../lib/ConsiderationEnums.sol";
-
-/**
- * @title SpentItemLib
- * @author James Wenzel (emo.eth)
- * @notice SpentItemLib is a library for managing SpentItem structs and arrays.
- * It allows chaining of functions to make struct creation more
- * readable.
- */
-library SpentItemLib {
- bytes32 private constant SPENT_ITEM_MAP_POSITION =
- keccak256("seaport.SpentItemDefaults");
- bytes32 private constant SPENT_ITEMS_MAP_POSITION =
- keccak256("seaport.SpentItemsDefaults");
- bytes32 private constant EMPTY_SPENT_ITEM =
- keccak256(
- abi.encode(
- SpentItem({
- itemType: ItemType(0),
- token: address(0),
- identifier: 0,
- amount: 0
- })
- )
- );
-
- /**
- * @dev Creates an empty SpentItem.
- *
- * @return the empty SpentItem
- */
- function empty() internal pure returns (SpentItem memory) {
- return SpentItem(ItemType(0), address(0), 0, 0);
- }
-
- /**
- * @dev Clears an SpentItem from storage.
- *
- * @param item the item to clear
- */
- function clear(SpentItem storage item) internal {
- // clear all fields
- item.itemType = ItemType(0);
- item.token = address(0);
- item.identifier = 0;
- item.amount = 0;
- }
-
- /**
- * @dev Clears an array of SpentItems from storage.
- *
- * @param items the items to clear
- */
- function clearMany(SpentItem[] storage items) internal {
- while (items.length > 0) {
- clear(items[items.length - 1]);
- items.pop();
- }
- }
-
- /**
- * @dev Clears a default SpentItem from storage.
- *
- * @param defaultName the name of the default to clear
- */
- function clear(string memory defaultName) internal {
- mapping(string => SpentItem) storage spentItemMap = _spentItemMap();
- SpentItem storage item = spentItemMap[defaultName];
- clear(item);
- }
-
- /**
- * @dev Clears an array of default SpentItems from storage.
- *
- * @param defaultsName the name of the default to clear
- */
- function clearMany(string memory defaultsName) internal {
- mapping(string => SpentItem[]) storage spentItemsMap = _spentItemsMap();
- SpentItem[] storage items = spentItemsMap[defaultsName];
- clearMany(items);
- }
-
- /**
- * @dev Gets a default SpentItem from storage.
- *
- * @param defaultName the name of the default for retrieval
- *
- * @return item the SpentItem
- */
- function fromDefault(
- string memory defaultName
- ) internal view returns (SpentItem memory item) {
- mapping(string => SpentItem) storage spentItemMap = _spentItemMap();
- item = spentItemMap[defaultName];
-
- if (keccak256(abi.encode(item)) == EMPTY_SPENT_ITEM) {
- revert("Empty SpentItem selected.");
- }
- }
-
- /**
- * @dev Gets an array of default SpentItems from storage.
- *
- * @param defaultsName the name of the default for retrieval
- *
- * @return items the SpentItems
- */
- function fromDefaultMany(
- string memory defaultsName
- ) internal view returns (SpentItem[] memory items) {
- mapping(string => SpentItem[]) storage spentItemsMap = _spentItemsMap();
- items = spentItemsMap[defaultsName];
-
- if (items.length == 0) {
- revert("Empty SpentItem array selected.");
- }
- }
-
- /**
- * @dev Saves an SpentItem as a named default.
- *
- * @param spentItem the SpentItem to save as a default
- * @param defaultName the name of the default for retrieval
- *
- * @return _spentItem the saved SpentItem
- */
- function saveDefault(
- SpentItem memory spentItem,
- string memory defaultName
- ) internal returns (SpentItem memory _spentItem) {
- mapping(string => SpentItem) storage spentItemMap = _spentItemMap();
- spentItemMap[defaultName] = spentItem;
- return spentItem;
- }
-
- /**
- * @dev Saves an array of SpentItems as a named default.
- *
- * @param spentItems the SpentItems to save as a default
- * @param defaultsName the name of the default for retrieval
- *
- * @return _spentItems the saved SpentItems
- */
- function saveDefaultMany(
- SpentItem[] memory spentItems,
- string memory defaultsName
- ) internal returns (SpentItem[] memory _spentItems) {
- mapping(string => SpentItem[]) storage spentItemsMap = _spentItemsMap();
- SpentItem[] storage items = spentItemsMap[defaultsName];
- setSpentItems(items, spentItems);
- return spentItems;
- }
-
- /**
- * @dev Sets an array of in-memory SpentItems to an array of SpentItems in
- * storage.
- *
- * @param items the SpentItem array in storage to push to
- * @param newItems the SpentItem array in memory to push onto the items
- * array
- */
- function setSpentItems(
- SpentItem[] storage items,
- SpentItem[] memory newItems
- ) internal {
- clearMany(items);
- for (uint256 i = 0; i < newItems.length; i++) {
- items.push(newItems[i]);
- }
- }
-
- /**
- * @dev Makes a copy of an SpentItem in-memory.
- *
- * @param item the SpentItem to make a copy of in-memory
- *
- * @custom:return copiedItem the copied SpentItem
- */
- function copy(
- SpentItem memory item
- ) internal pure returns (SpentItem memory) {
- return
- SpentItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifier,
- amount: item.amount
- });
- }
-
- /**
- * @dev Makes a copy of an array of SpentItems in-memory.
- *
- * @param items the SpentItems to make a copy of in-memory
- *
- * @custom:return copiedItems the copied SpentItems
- */
- function copy(
- SpentItem[] memory items
- ) internal pure returns (SpentItem[] memory) {
- SpentItem[] memory copiedItems = new SpentItem[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- copiedItems[i] = copy(items[i]);
- }
- return copiedItems;
- }
-
- /**
- * @dev Gets the storage position of the default SpentItem map.
- *
- * @custom:return position the storage position of the default SpentItem map
- */
- function _spentItemMap()
- private
- pure
- returns (mapping(string => SpentItem) storage spentItemMap)
- {
- bytes32 position = SPENT_ITEM_MAP_POSITION;
- assembly {
- spentItemMap.slot := position
- }
- }
-
- /**
- * @dev Gets the storage position of the default SpentItem array map.
- *
- * @custom:return position the storage position of the default SpentItem
- * array map
- */
- function _spentItemsMap()
- private
- pure
- returns (mapping(string => SpentItem[]) storage spentItemsMap)
- {
- bytes32 position = SPENT_ITEMS_MAP_POSITION;
- assembly {
- spentItemsMap.slot := position
- }
- }
-
- // Methods for configuring a single of each of a SpentItem's fields, which
- // modify the SpentItem struct in-place and return it.
-
- /**
- * @dev Sets the itemType field of a SpentItem.
- *
- * @param item the SpentItem to set the itemType field of
- * @param itemType the itemType to set the itemType field to
- *
- * @custom:return item the SpentItem with the itemType field set
- */
- function withItemType(
- SpentItem memory item,
- ItemType itemType
- ) internal pure returns (SpentItem memory) {
- item.itemType = itemType;
- return item;
- }
-
- /**
- * @dev Sets the token field of a SpentItem.
- *
- * @param item the SpentItem to set the token field of
- * @param token the token to set the token field to
- *
- * @custom:return item the SpentItem with the token field set
- */
- function withToken(
- SpentItem memory item,
- address token
- ) internal pure returns (SpentItem memory) {
- item.token = token;
- return item;
- }
-
- /**
- * @dev Sets the identifier field of a SpentItem.
- *
- * @param item the SpentItem to set the identifier field of
- * @param identifier the identifier to set the identifier field to
- *
- * @custom:return item the SpentItem with the identifier field set
- */
- function withIdentifier(
- SpentItem memory item,
- uint256 identifier
- ) internal pure returns (SpentItem memory) {
- item.identifier = identifier;
- return item;
- }
-
- /**
- * @dev Sets the amount field of a SpentItem.
- *
- * @param item the SpentItem to set the amount field of
- * @param amount the amount to set the amount field to
- *
- * @custom:return item the SpentItem with the amount field set
- */
- function withAmount(
- SpentItem memory item,
- uint256 amount
- ) internal pure returns (SpentItem memory) {
- item.amount = amount;
- return item;
- }
-
- /**
- * @dev Converts a SpentItem to an OfferItem.
- *
- * @param item the SpentItem to convert to an OfferItem
- *
- * @custom:return offerItem the converted OfferItem
- */
- function toOfferItem(
- SpentItem memory item
- ) internal pure returns (OfferItem memory) {
- return
- OfferItem({
- itemType: item.itemType,
- token: item.token,
- identifierOrCriteria: item.identifier,
- startAmount: item.amount,
- endAmount: item.amount
- });
- }
-}
diff --git a/contracts/helpers/sol/lib/StructCopier.sol b/contracts/helpers/sol/lib/StructCopier.sol
deleted file mode 100644
index 55bd466da..000000000
--- a/contracts/helpers/sol/lib/StructCopier.sol
+++ /dev/null
@@ -1,508 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- AdditionalRecipient,
- AdvancedOrder,
- BasicOrderParameters,
- ConsiderationItem,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- OfferItem,
- Order,
- OrderComponents,
- OrderParameters
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { ArrayLib } from "./ArrayLib.sol";
-
-library StructCopier {
- function _basicOrderParameters()
- private
- pure
- returns (BasicOrderParameters storage empty)
- {
- bytes32 position = keccak256("StructCopier.EmptyBasicOrderParameters");
- assembly {
- empty.slot := position
- }
- return empty;
- }
-
- function _criteriaResolver()
- private
- pure
- returns (CriteriaResolver storage empty)
- {
- bytes32 position = keccak256("StructCopier.EmptyCriteriaResolver");
- assembly {
- empty.slot := position
- }
- return empty;
- }
-
- function _fulfillment() private pure returns (Fulfillment storage empty) {
- bytes32 position = keccak256("StructCopier.EmptyFulfillment");
- assembly {
- empty.slot := position
- }
- return empty;
- }
-
- function _orderComponents()
- private
- pure
- returns (OrderComponents storage empty)
- {
- bytes32 position = keccak256("StructCopier.EmptyOrderComponents");
- assembly {
- empty.slot := position
- }
- return empty;
- }
-
- function _orderParameters()
- private
- pure
- returns (OrderParameters storage empty)
- {
- bytes32 position = keccak256("StructCopier.EmptyOrderParameters");
- assembly {
- empty.slot := position
- }
- return empty;
- }
-
- function _order() private pure returns (Order storage empty) {
- bytes32 position = keccak256("StructCopier.EmptyOrder");
- assembly {
- empty.slot := position
- }
- return empty;
- }
-
- function setBasicOrderParameters(
- BasicOrderParameters storage dest,
- BasicOrderParameters memory src
- ) internal {
- dest.considerationToken = src.considerationToken;
- dest.considerationIdentifier = src.considerationIdentifier;
- dest.considerationAmount = src.considerationAmount;
- dest.offerer = src.offerer;
- dest.zone = src.zone;
- dest.offerToken = src.offerToken;
- dest.offerIdentifier = src.offerIdentifier;
- dest.offerAmount = src.offerAmount;
- dest.basicOrderType = src.basicOrderType;
- dest.startTime = src.startTime;
- dest.endTime = src.endTime;
- dest.zoneHash = src.zoneHash;
- dest.salt = src.salt;
- dest.offererConduitKey = src.offererConduitKey;
- dest.fulfillerConduitKey = src.fulfillerConduitKey;
- dest.totalOriginalAdditionalRecipients = src
- .totalOriginalAdditionalRecipients;
- setAdditionalRecipients(
- dest.additionalRecipients,
- src.additionalRecipients
- );
- dest.signature = src.signature;
- }
-
- function setOrderComponents(
- OrderComponents storage dest,
- OrderComponents memory src
- ) internal {
- dest.offerer = src.offerer;
- dest.zone = src.zone;
- setOfferItems(dest.offer, src.offer);
- setConsiderationItems(dest.consideration, src.consideration);
- dest.orderType = src.orderType;
- dest.startTime = src.startTime;
- dest.endTime = src.endTime;
- dest.zoneHash = src.zoneHash;
- dest.salt = src.salt;
- dest.conduitKey = src.conduitKey;
- dest.counter = src.counter;
- }
-
- function setOrderComponents(
- OrderComponents[] storage dest,
- OrderComponents[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- OrderComponents storage empty = _orderComponents();
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(empty);
- setOrderComponents(dest[i], src[i]);
- }
- }
-
- function setBasicOrderParameters(
- BasicOrderParameters[] storage dest,
- BasicOrderParameters[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- BasicOrderParameters storage empty = _basicOrderParameters();
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(empty);
- setBasicOrderParameters(dest[i], src[i]);
- }
- }
-
- function setAdditionalRecipients(
- AdditionalRecipient[] storage dest,
- AdditionalRecipient[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(src[i]);
- }
- }
-
- function setCriteriaResolver(
- CriteriaResolver storage dest,
- CriteriaResolver memory src
- ) internal {
- dest.orderIndex = src.orderIndex;
- dest.side = src.side;
- dest.index = src.index;
- dest.identifier = src.identifier;
- ArrayLib.setBytes32s(dest.criteriaProof, src.criteriaProof);
- }
-
- function setCriteriaResolvers(
- CriteriaResolver[] storage dest,
- CriteriaResolver[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- CriteriaResolver storage empty = _criteriaResolver();
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(empty);
- setCriteriaResolver(dest[i], src[i]);
- }
- }
-
- function setOrder(Order storage dest, Order memory src) internal {
- setOrderParameters(dest.parameters, src.parameters);
- dest.signature = src.signature;
- }
-
- bytes32 constant TEMP_ORDER = keccak256("seaport-sol.temp.Order");
- bytes32 constant TEMP_COUNTER_SLOT = keccak256("seaport-sol.temp.Counter");
-
- /**
- * @notice Get a counter used to derive a temporary storage slot.
- * @dev Solidity does not allow copying dynamic types from memory to storage.
- * We need a "clean" (empty) temp pointer to make an exact copy of a struct with dynamic members, but
- * Solidity does not allow calling "delete" on a storage pointer either.
- * By hashing a struct's temp slot with a monotonically increasing counter, we can derive a new temp slot
- * that is basically "guaranteed" to have all successive storage slots empty.
- * TODO: We can revisit adding "clear" methods that definitively wipe all dynamic components of a struct,
- * but that will require an equal amount of SSTOREs; this is obviously more expensive gas-wise, but may not
- * make a difference performance-wise when running simiulations locally (though this needs to be tested)
- */
- function _getAndIncrementTempCounter() internal returns (uint256 counter) {
- // get counter slot
- bytes32 counterSlot = TEMP_COUNTER_SLOT;
- assembly {
- // load current value
- counter := sload(counterSlot)
- // store incremented value
- sstore(counterSlot, add(counter, 1))
- }
- // return original value
- return counter;
- }
-
- function _deriveTempSlotWithCounter(
- bytes32 libSlot
- ) internal returns (uint256 derivedSlot) {
- uint256 counter = _getAndIncrementTempCounter();
- assembly {
- // store lib slot in first mem position
- mstore(0x0, libSlot)
- // store temp counter in second position
- mstore(0x20, counter)
- // hash original slot with counter to get new temp slot, which has a low probability of being dirty
- // (~1/2**256)
- derivedSlot := keccak256(0x0, 0x40)
- }
- }
-
- function _getTempOrder() internal returns (Order storage _tempOrder) {
- uint256 position = _deriveTempSlotWithCounter(TEMP_ORDER);
- assembly {
- _tempOrder.slot := position
- }
- }
-
- function setOrders(Order[] storage dest, Order[] memory src) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- Order storage empty = _order();
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(empty);
- setOrder(dest[i], src[i]);
- }
- }
-
- function setAdvancedOrder(
- AdvancedOrder storage dest,
- AdvancedOrder memory src
- ) internal {
- setOrderParameters(dest.parameters, src.parameters);
- dest.numerator = src.numerator;
- dest.denominator = src.denominator;
- dest.signature = src.signature;
- dest.extraData = src.extraData;
- }
-
- bytes32 constant TEMP_ADVANCED_ORDER =
- keccak256("seaport-sol.temp.AdvancedOrder");
-
- function _getTempAdvancedOrder()
- internal
- returns (AdvancedOrder storage _tempAdvancedOrder)
- {
- uint256 position = _deriveTempSlotWithCounter(TEMP_ADVANCED_ORDER);
- assembly {
- _tempAdvancedOrder.slot := position
- }
- }
-
- function setAdvancedOrders(
- AdvancedOrder[] storage dest,
- AdvancedOrder[] memory src
- ) internal {
- AdvancedOrder storage _tempAdvancedOrder = _getTempAdvancedOrder();
-
- while (dest.length != 0) {
- dest.pop();
- }
- for (uint256 i = 0; i < src.length; ++i) {
- setAdvancedOrder(_tempAdvancedOrder, src[i]);
- dest.push(_tempAdvancedOrder);
- }
- }
-
- function setOrderParameters(
- OrderParameters storage dest,
- OrderParameters memory src
- ) internal {
- dest.offerer = src.offerer;
- dest.zone = src.zone;
- setOfferItems(dest.offer, src.offer);
- setConsiderationItems(dest.consideration, src.consideration);
- dest.orderType = src.orderType;
- dest.startTime = src.startTime;
- dest.endTime = src.endTime;
- dest.zoneHash = src.zoneHash;
- dest.salt = src.salt;
- dest.conduitKey = src.conduitKey;
- dest.totalOriginalConsiderationItems = src
- .totalOriginalConsiderationItems;
- }
-
- function setOfferItems(
- OfferItem[] storage dest,
- OfferItem[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(src[i]);
- }
- }
-
- function setConsiderationItems(
- ConsiderationItem[] storage dest,
- ConsiderationItem[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(src[i]);
- }
- }
-
- function setFulfillment(
- Fulfillment storage dest,
- Fulfillment memory src
- ) internal {
- setFulfillmentComponents(dest.offerComponents, src.offerComponents);
- setFulfillmentComponents(
- dest.considerationComponents,
- src.considerationComponents
- );
- }
-
- function setFulfillments(
- Fulfillment[] storage dest,
- Fulfillment[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- Fulfillment storage empty = _fulfillment();
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(empty);
- setFulfillment(dest[i], src[i]);
- }
- }
-
- function setFulfillmentComponents(
- FulfillmentComponent[] storage dest,
- FulfillmentComponent[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(src[i]);
- }
- }
-
- bytes32 constant TEMP_FULFILLMENT_COMPONENTS =
- keccak256("seaport-sol.temp.FulfillmentComponents");
-
- function _getTempFulfillmentComponents()
- internal
- pure
- returns (FulfillmentComponent[] storage _tempFulfillmentComponents)
- {
- bytes32 position = TEMP_FULFILLMENT_COMPONENTS;
- assembly {
- _tempFulfillmentComponents.slot := position
- }
- }
-
- function pushFulFillmentComponents(
- FulfillmentComponent[][] storage dest,
- FulfillmentComponent[] memory src
- ) internal {
- FulfillmentComponent[]
- storage _tempFulfillmentComponents = _getTempFulfillmentComponents();
- setFulfillmentComponents(_tempFulfillmentComponents, src);
- dest.push(_tempFulfillmentComponents);
- }
-
- function setFulfillmentComponentsArray(
- FulfillmentComponent[][] storage dest,
- FulfillmentComponent[][] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- for (uint256 i = 0; i < src.length; ++i) {
- pushFulFillmentComponents(dest, src[i]);
- }
- }
-
- function toConsiderationItems(
- OfferItem[] memory _offerItems,
- address payable receiver
- ) internal pure returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory considerationItems = new ConsiderationItem[](
- _offerItems.length
- );
- for (uint256 i = 0; i < _offerItems.length; ++i) {
- considerationItems[i] = ConsiderationItem(
- _offerItems[i].itemType,
- _offerItems[i].token,
- _offerItems[i].identifierOrCriteria,
- _offerItems[i].startAmount,
- _offerItems[i].endAmount,
- receiver
- );
- }
- return considerationItems;
- }
-
- function toOfferItems(
- ConsiderationItem[] memory _considerationItems
- ) internal pure returns (OfferItem[] memory) {
- OfferItem[] memory _offerItems = new OfferItem[](
- _considerationItems.length
- );
- for (uint256 i = 0; i < _offerItems.length; i++) {
- _offerItems[i] = OfferItem(
- _considerationItems[i].itemType,
- _considerationItems[i].token,
- _considerationItems[i].identifierOrCriteria,
- _considerationItems[i].startAmount,
- _considerationItems[i].endAmount
- );
- }
- return _offerItems;
- }
-
- function createMirrorOrderParameters(
- OrderParameters memory orderParameters,
- address payable offerer,
- address zone,
- bytes32 conduitKey
- ) public pure returns (OrderParameters memory) {
- OfferItem[] memory _offerItems = toOfferItems(
- orderParameters.consideration
- );
- ConsiderationItem[] memory _considerationItems = toConsiderationItems(
- orderParameters.offer,
- offerer
- );
-
- OrderParameters memory _mirrorOrderParameters = OrderParameters(
- offerer,
- zone,
- _offerItems,
- _considerationItems,
- orderParameters.orderType,
- orderParameters.startTime,
- orderParameters.endTime,
- orderParameters.zoneHash,
- orderParameters.salt,
- conduitKey,
- _considerationItems.length
- );
- return _mirrorOrderParameters;
- }
-
- function setExecutions(
- Execution[] storage dest,
- Execution[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(src[i]);
- }
- }
-
- function setOrderParameters(
- OrderParameters[] storage dest,
- OrderParameters[] memory src
- ) internal {
- while (dest.length != 0) {
- dest.pop();
- }
- OrderParameters storage empty = _orderParameters();
- for (uint256 i = 0; i < src.length; ++i) {
- dest.push(empty);
- setOrderParameters(dest[i], src[i]);
- }
- }
-}
diff --git a/contracts/helpers/sol/lib/ZoneParametersLib.sol b/contracts/helpers/sol/lib/ZoneParametersLib.sol
deleted file mode 100644
index 09e88fb08..000000000
--- a/contracts/helpers/sol/lib/ZoneParametersLib.sol
+++ /dev/null
@@ -1,312 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { ItemType, Side, OrderType } from "../../../lib/ConsiderationEnums.sol";
-
-import {
- AdvancedOrder,
- ConsiderationItem,
- CriteriaResolver,
- OfferItem,
- Order,
- OrderComponents,
- OrderParameters,
- SpentItem,
- ReceivedItem,
- ZoneParameters,
- CriteriaResolver
-} from "../../../lib/ConsiderationStructs.sol";
-
-import { SeaportInterface } from "../SeaportInterface.sol";
-
-import { GettersAndDerivers } from "../../../lib/GettersAndDerivers.sol";
-
-import { UnavailableReason } from "../SpaceEnums.sol";
-
-import { AdvancedOrderLib } from "./AdvancedOrderLib.sol";
-
-import { ConsiderationItemLib } from "./ConsiderationItemLib.sol";
-
-import { OfferItemLib } from "./OfferItemLib.sol";
-
-import { ReceivedItemLib } from "./ReceivedItemLib.sol";
-
-import { OrderParametersLib } from "./OrderParametersLib.sol";
-
-import { StructCopier } from "./StructCopier.sol";
-
-import { AmountDeriverHelper } from "./fulfillment/AmountDeriverHelper.sol";
-
-import { OrderDetails } from "../fulfillments/lib/Structs.sol";
-
-interface FailingContractOfferer {
- function failureReasons(bytes32) external view returns (uint256);
-}
-
-library ZoneParametersLib {
- using AdvancedOrderLib for AdvancedOrder;
- using AdvancedOrderLib for AdvancedOrder[];
- using OfferItemLib for OfferItem;
- using OfferItemLib for OfferItem[];
- using ConsiderationItemLib for ConsiderationItem;
- using ConsiderationItemLib for ConsiderationItem[];
- using OrderParametersLib for OrderParameters;
-
- struct ZoneParametersStruct {
- AdvancedOrder[] advancedOrders;
- address fulfiller;
- uint256 maximumFulfilled;
- address seaport;
- CriteriaResolver[] criteriaResolvers;
- }
-
- struct ZoneDetails {
- AdvancedOrder[] advancedOrders;
- address fulfiller;
- uint256 maximumFulfilled;
- OrderDetails[] orderDetails;
- bytes32[] orderHashes;
- }
-
- function getZoneParameters(
- AdvancedOrder memory advancedOrder,
- address fulfiller,
- uint256 counter,
- address seaport,
- CriteriaResolver[] memory criteriaResolvers
- ) internal view returns (ZoneParameters memory zoneParameters) {
- SeaportInterface seaportInterface = SeaportInterface(seaport);
- // Get orderParameters from advancedOrder
- OrderParameters memory orderParameters = advancedOrder.parameters;
-
- // Get orderHash
- bytes32 orderHash = advancedOrder.getTipNeutralizedOrderHash(
- seaportInterface,
- counter
- );
-
- (
- SpentItem[] memory spentItems,
- ReceivedItem[] memory receivedItems
- ) = orderParameters.getSpentAndReceivedItems(
- advancedOrder.numerator,
- advancedOrder.denominator,
- 0,
- criteriaResolvers
- );
-
- // Store orderHash in orderHashes array to pass into zoneParameters
- bytes32[] memory orderHashes = new bytes32[](1);
- orderHashes[0] = orderHash;
-
- // Create ZoneParameters and add to zoneParameters array
- zoneParameters = ZoneParameters({
- orderHash: orderHash,
- fulfiller: fulfiller,
- offerer: orderParameters.offerer,
- offer: spentItems,
- consideration: receivedItems,
- extraData: advancedOrder.extraData,
- orderHashes: orderHashes,
- startTime: orderParameters.startTime,
- endTime: orderParameters.endTime,
- zoneHash: orderParameters.zoneHash
- });
- }
-
- function getZoneParameters(
- AdvancedOrder[] memory advancedOrders,
- address fulfiller,
- uint256 maximumFulfilled,
- address seaport,
- CriteriaResolver[] memory criteriaResolvers,
- UnavailableReason[] memory unavailableReasons
- ) internal view returns (ZoneParameters[] memory) {
- return
- _getZoneParametersFromStruct(
- _getZoneParametersStruct(
- advancedOrders,
- fulfiller,
- maximumFulfilled,
- seaport,
- criteriaResolvers
- ), unavailableReasons
- );
- }
-
- function _getZoneParametersStruct(
- AdvancedOrder[] memory advancedOrders,
- address fulfiller,
- uint256 maximumFulfilled,
- address seaport,
- CriteriaResolver[] memory criteriaResolvers
- ) internal pure returns (ZoneParametersStruct memory) {
- return
- ZoneParametersStruct(
- advancedOrders,
- fulfiller,
- maximumFulfilled,
- seaport,
- criteriaResolvers
- );
- }
-
- function _getZoneParametersFromStruct(
- ZoneParametersStruct memory zoneParametersStruct,
- UnavailableReason[] memory unavailableReasons
- ) internal view returns (ZoneParameters[] memory) {
- // TODO: use testHelpers pattern to use single amount deriver helper
- ZoneDetails memory details = _getZoneDetails(zoneParametersStruct);
-
- // Convert offer + consideration to spent + received
- _applyOrderDetails(details, zoneParametersStruct, unavailableReasons);
-
- // Iterate over advanced orders to calculate orderHashes
- _applyOrderHashes(details, zoneParametersStruct.seaport);
-
- return _finalizeZoneParameters(details);
- }
-
- function _getZoneDetails(
- ZoneParametersStruct memory zoneParametersStruct
- ) internal pure returns (ZoneDetails memory) {
- return
- ZoneDetails({
- advancedOrders: zoneParametersStruct.advancedOrders,
- fulfiller: zoneParametersStruct.fulfiller,
- maximumFulfilled: zoneParametersStruct.maximumFulfilled,
- orderDetails: new OrderDetails[](
- zoneParametersStruct.advancedOrders.length
- ),
- orderHashes: new bytes32[](
- zoneParametersStruct.advancedOrders.length
- )
- });
- }
-
- function _applyOrderDetails(
- ZoneDetails memory details,
- ZoneParametersStruct memory zoneParametersStruct,
- UnavailableReason[] memory unavailableReasons
- ) internal view {
- bytes32[] memory orderHashes = details.advancedOrders.getOrderHashes(
- zoneParametersStruct.seaport
- );
-
- details.orderDetails = zoneParametersStruct
- .advancedOrders
- .getOrderDetails(
- zoneParametersStruct.criteriaResolvers,
- orderHashes,
- unavailableReasons
- );
- }
-
- function _applyOrderHashes(
- ZoneDetails memory details,
- address seaport
- ) internal view {
- bytes32[] memory orderHashes = details.advancedOrders.getOrderHashes(
- seaport
- );
-
- uint256 totalFulfilled = 0;
- // Iterate over advanced orders to calculate orderHashes
- for (uint256 i = 0; i < details.advancedOrders.length; i++) {
- bytes32 orderHash = orderHashes[i];
-
- if (
- totalFulfilled >= details.maximumFulfilled ||
- _isUnavailable(
- details.advancedOrders[i].parameters,
- orderHash,
- SeaportInterface(seaport)
- )
- ) {
- // Set orderHash to 0 if order index exceeds maximumFulfilled
- details.orderHashes[i] = bytes32(0);
- } else {
- // Add orderHash to orderHashes and increment totalFulfilled/
- details.orderHashes[i] = orderHash;
- ++totalFulfilled;
- }
- }
- }
-
- function _isUnavailable(
- OrderParameters memory order,
- bytes32 orderHash,
- SeaportInterface seaport
- ) internal view returns (bool) {
- (, bool isCancelled, uint256 totalFilled, uint256 totalSize) = seaport
- .getOrderStatus(orderHash);
-
- bool isRevertingContractOrder = false;
- if (order.orderType == OrderType.CONTRACT) {
- isRevertingContractOrder =
- FailingContractOfferer(order.offerer).failureReasons(
- orderHash
- ) !=
- 0;
- }
-
- return (block.timestamp >= order.endTime ||
- block.timestamp < order.startTime ||
- isCancelled ||
- isRevertingContractOrder ||
- (totalFilled >= totalSize && totalSize > 0));
- }
-
- function _finalizeZoneParameters(
- ZoneDetails memory zoneDetails
- ) internal pure returns (ZoneParameters[] memory zoneParameters) {
- zoneParameters = new ZoneParameters[](
- zoneDetails.advancedOrders.length
- );
-
- // Iterate through advanced orders to create zoneParameters
- uint256 totalFulfilled = 0;
-
- for (uint i = 0; i < zoneDetails.advancedOrders.length; i++) {
- if (totalFulfilled >= zoneDetails.maximumFulfilled) {
- break;
- }
-
- if (zoneDetails.orderHashes[i] != bytes32(0)) {
- // Create ZoneParameters and add to zoneParameters array
- zoneParameters[i] = _createZoneParameters(
- zoneDetails.orderHashes[i],
- zoneDetails.orderDetails[i],
- zoneDetails.advancedOrders[i],
- zoneDetails.fulfiller,
- zoneDetails.orderHashes
- );
- ++totalFulfilled;
- }
- }
-
- return zoneParameters;
- }
-
- function _createZoneParameters(
- bytes32 orderHash,
- OrderDetails memory orderDetails,
- AdvancedOrder memory advancedOrder,
- address fulfiller,
- bytes32[] memory orderHashes
- ) internal pure returns (ZoneParameters memory) {
- return
- ZoneParameters({
- orderHash: orderHash,
- fulfiller: fulfiller,
- offerer: advancedOrder.parameters.offerer,
- offer: orderDetails.offer,
- consideration: orderDetails.consideration,
- extraData: advancedOrder.extraData,
- orderHashes: orderHashes,
- startTime: advancedOrder.parameters.startTime,
- endTime: advancedOrder.parameters.endTime,
- zoneHash: advancedOrder.parameters.zoneHash
- });
- }
-}
diff --git a/contracts/helpers/sol/lib/fulfillment/AmountDeriverHelper.sol b/contracts/helpers/sol/lib/fulfillment/AmountDeriverHelper.sol
deleted file mode 100644
index 9c0287b2e..000000000
--- a/contracts/helpers/sol/lib/fulfillment/AmountDeriverHelper.sol
+++ /dev/null
@@ -1,560 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { SeaportInterface } from "../../../../interfaces/SeaportInterface.sol";
-import { AmountDeriver } from "../../../../lib/AmountDeriver.sol";
-import {
- AdvancedOrder,
- ConsiderationItem,
- CriteriaResolver,
- OfferItem,
- Order,
- OrderComponents,
- OrderParameters,
- OrderType,
- ReceivedItem,
- SpentItem
-} from "../../../../lib/ConsiderationStructs.sol";
-import { Side, ItemType } from "../../../../lib/ConsiderationEnums.sol";
-import { OfferItemLib } from "../OfferItemLib.sol";
-import { ConsiderationItemLib } from "../ConsiderationItemLib.sol";
-import { OrderParametersLib } from "../OrderParametersLib.sol";
-import { OrderDetails } from "../../fulfillments/lib/Structs.sol";
-import { UnavailableReason } from "../../SpaceEnums.sol";
-
-/**
- * @notice Note that this contract relies on current block.timestamp to determine amounts.
- */
-contract AmountDeriverHelper is AmountDeriver {
- using OfferItemLib for OfferItem[];
- using ConsiderationItemLib for ConsiderationItem[];
- using OrderParametersLib for OrderParameters;
-
- struct ContractNonceDetails {
- bool set;
- address offerer;
- uint256 currentNonce;
- }
-
- function getSpentAndReceivedItems(
- Order calldata order
- )
- external
- view
- returns (SpentItem[] memory spent, ReceivedItem[] memory received)
- {
- return getSpentAndReceivedItems(order.parameters);
- }
-
- function getSpentAndReceivedItems(
- AdvancedOrder calldata order
- )
- external
- view
- returns (SpentItem[] memory spent, ReceivedItem[] memory received)
- {
- CriteriaResolver[] memory resolvers;
- return
- getSpentAndReceivedItems(
- order.parameters,
- order.numerator,
- order.denominator,
- 0,
- resolvers
- );
- }
-
- function getSpentAndReceivedItems(
- AdvancedOrder calldata order,
- uint256 orderIndex,
- CriteriaResolver[] calldata criteriaResolvers
- )
- external
- view
- returns (SpentItem[] memory spent, ReceivedItem[] memory received)
- {
- return
- getSpentAndReceivedItems(
- order.parameters,
- order.numerator,
- order.denominator,
- orderIndex,
- criteriaResolvers
- );
- }
-
- function getSpentAndReceivedItems(
- OrderParameters calldata parameters
- )
- public
- view
- returns (SpentItem[] memory spent, ReceivedItem[] memory received)
- {
- if (parameters.isAvailable()) {
- spent = getSpentItems(parameters);
- received = getReceivedItems(parameters);
- }
- }
-
- function toOrderDetails(
- OrderParameters memory order,
- bytes32 orderHash,
- UnavailableReason unavailableReason
- ) internal view returns (OrderDetails memory) {
- (SpentItem[] memory offer, ReceivedItem[] memory consideration) = this
- .getSpentAndReceivedItems(order);
- return
- OrderDetails({
- offerer: order.offerer,
- conduitKey: order.conduitKey,
- offer: offer,
- consideration: consideration,
- isContract: order.orderType == OrderType.CONTRACT,
- orderHash: orderHash,
- unavailableReason: unavailableReason
- });
- }
-
- function toOrderDetails(
- Order[] memory order,
- bytes32[] memory orderHashes,
- UnavailableReason[] memory unavailableReasons
- ) public view returns (OrderDetails[] memory) {
- OrderDetails[] memory orderDetails = new OrderDetails[](order.length);
- for (uint256 i = 0; i < order.length; i++) {
- orderDetails[i] = toOrderDetails(
- order[i].parameters,
- orderHashes[i],
- unavailableReasons[i]
- );
- }
- return orderDetails;
- }
-
- function toOrderDetails(
- AdvancedOrder[] memory orders,
- CriteriaResolver[] memory resolvers,
- bytes32[] memory orderHashes,
- UnavailableReason[] memory unavailableReasons
- ) public view returns (OrderDetails[] memory) {
- OrderDetails[] memory orderDetails = new OrderDetails[](orders.length);
- for (uint256 i = 0; i < orders.length; i++) {
- orderDetails[i] = toOrderDetails(
- orders[i],
- i,
- resolvers,
- orderHashes[i],
- unavailableReasons[i]
- );
- }
- return orderDetails;
- }
-
- function toOrderDetails(
- AdvancedOrder memory order,
- uint256 orderIndex,
- CriteriaResolver[] memory resolvers,
- bytes32 orderHash,
- UnavailableReason unavailableReason
- ) internal view returns (OrderDetails memory) {
- (SpentItem[] memory offer, ReceivedItem[] memory consideration) = this
- .getSpentAndReceivedItems(order, orderIndex, resolvers);
-
- return
- OrderDetails({
- offerer: order.parameters.offerer,
- conduitKey: order.parameters.conduitKey,
- offer: offer,
- consideration: consideration,
- isContract: order.parameters.orderType == OrderType.CONTRACT,
- orderHash: orderHash,
- unavailableReason: unavailableReason
- });
- }
-
- function getSpentAndReceivedItems(
- OrderParameters memory parameters,
- uint256 numerator,
- uint256 denominator,
- uint256 orderIndex,
- CriteriaResolver[] memory criteriaResolvers
- )
- private
- view
- returns (SpentItem[] memory spent, ReceivedItem[] memory received)
- {
- if (parameters.isAvailable()) {
- spent = getSpentItems(parameters, numerator, denominator);
- received = getReceivedItems(parameters, numerator, denominator);
-
- applyCriteriaResolvers(
- spent,
- received,
- orderIndex,
- criteriaResolvers
- );
- }
- }
-
- function applyCriteriaResolvers(
- SpentItem[] memory spentItems,
- ReceivedItem[] memory receivedItems,
- uint256 orderIndex,
- CriteriaResolver[] memory criteriaResolvers
- ) private pure {
- for (uint256 i = 0; i < criteriaResolvers.length; i++) {
- CriteriaResolver memory resolver = criteriaResolvers[i];
- if (resolver.orderIndex != orderIndex) {
- continue;
- }
- if (resolver.side == Side.OFFER) {
- SpentItem memory item = spentItems[resolver.index];
- item.itemType = convertCriteriaItemType(item.itemType);
- item.identifier = resolver.identifier;
- } else {
- ReceivedItem memory item = receivedItems[resolver.index];
- item.itemType = convertCriteriaItemType(item.itemType);
- item.identifier = resolver.identifier;
- }
- }
- }
-
- function convertCriteriaItemType(
- ItemType itemType
- ) internal pure returns (ItemType) {
- if (itemType == ItemType.ERC721_WITH_CRITERIA) {
- return ItemType.ERC721;
- } else if (itemType == ItemType.ERC1155_WITH_CRITERIA) {
- return ItemType.ERC1155;
- } else {
- revert("amount deriver helper resolving non criteria item type");
- }
- }
-
- function getSpentItems(
- OrderParameters memory parameters,
- uint256 numerator,
- uint256 denominator
- ) private view returns (SpentItem[] memory) {
- return
- getSpentItems(
- parameters.offer,
- parameters.startTime,
- parameters.endTime,
- numerator,
- denominator
- );
- }
-
- function getSpentItems(
- OrderParameters memory parameters
- ) private view returns (SpentItem[] memory) {
- return
- getSpentItems(
- parameters.offer,
- parameters.startTime,
- parameters.endTime
- );
- }
-
- function getSpentItems(
- OfferItem[] memory offerItems,
- uint256 startTime,
- uint256 endTime
- ) private view returns (SpentItem[] memory) {
- SpentItem[] memory spentItems = new SpentItem[](offerItems.length);
- for (uint256 i = 0; i < offerItems.length; i++) {
- spentItems[i] = getSpentItem(offerItems[i], startTime, endTime);
- }
- return spentItems;
- }
-
- function getSpentItems(
- OfferItem[] memory items,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) private view returns (SpentItem[] memory) {
- SpentItem[] memory spentItems = new SpentItem[](items.length);
- for (uint256 i = 0; i < items.length; i++) {
- spentItems[i] = getSpentItem(
- items[i],
- startTime,
- endTime,
- numerator,
- denominator
- );
- }
- return spentItems;
- }
-
- function getSpentItem(
- OfferItem memory offerItem,
- uint256 startTime,
- uint256 endTime
- ) private view returns (SpentItem memory spent) {
- spent = SpentItem({
- itemType: offerItem.itemType,
- token: offerItem.token,
- identifier: offerItem.identifierOrCriteria,
- amount: _locateCurrentAmount({
- item: offerItem,
- startTime: startTime,
- endTime: endTime
- })
- });
- }
-
- function getSpentItem(
- OfferItem memory item,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) private view returns (SpentItem memory spent) {
- // Detect if the order has an invalid time;
- // if so, set amount to zero
- spent = SpentItem({
- itemType: item.itemType,
- token: item.token,
- identifier: item.identifierOrCriteria,
- amount: (block.timestamp < startTime || block.timestamp >= endTime)
- ? 0
- : _applyFraction({
- numerator: numerator,
- denominator: denominator,
- item: item,
- startTime: startTime,
- endTime: endTime
- })
- });
- }
-
- function getReceivedItems(
- OrderParameters memory parameters
- ) private view returns (ReceivedItem[] memory) {
- return
- getReceivedItems(
- parameters.consideration,
- parameters.startTime,
- parameters.endTime
- );
- }
-
- function getReceivedItems(
- OrderParameters memory parameters,
- uint256 numerator,
- uint256 denominator
- ) private view returns (ReceivedItem[] memory) {
- return
- getReceivedItems(
- parameters.consideration,
- parameters.startTime,
- parameters.endTime,
- numerator,
- denominator
- );
- }
-
- function getReceivedItems(
- ConsiderationItem[] memory considerationItems,
- uint256 startTime,
- uint256 endTime
- ) private view returns (ReceivedItem[] memory) {
- ReceivedItem[] memory receivedItems = new ReceivedItem[](
- considerationItems.length
- );
- for (uint256 i = 0; i < considerationItems.length; i++) {
- receivedItems[i] = getReceivedItem(
- considerationItems[i],
- startTime,
- endTime
- );
- }
- return receivedItems;
- }
-
- function getReceivedItems(
- ConsiderationItem[] memory considerationItems,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) private view returns (ReceivedItem[] memory) {
- ReceivedItem[] memory receivedItems = new ReceivedItem[](
- considerationItems.length
- );
- for (uint256 i = 0; i < considerationItems.length; i++) {
- receivedItems[i] = getReceivedItem(
- considerationItems[i],
- startTime,
- endTime,
- numerator,
- denominator
- );
- }
- return receivedItems;
- }
-
- function getReceivedItem(
- ConsiderationItem memory considerationItem,
- uint256 startTime,
- uint256 endTime
- ) private view returns (ReceivedItem memory received) {
- received = ReceivedItem({
- itemType: considerationItem.itemType,
- token: considerationItem.token,
- identifier: considerationItem.identifierOrCriteria,
- amount: _locateCurrentAmount({
- item: considerationItem,
- startTime: startTime,
- endTime: endTime
- }),
- recipient: considerationItem.recipient
- });
- }
-
- function getReceivedItem(
- ConsiderationItem memory considerationItem,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) private view returns (ReceivedItem memory received) {
- // Detect if the order has an invalid time;
- // if so, set amount to zero
- received = ReceivedItem({
- itemType: considerationItem.itemType,
- token: considerationItem.token,
- identifier: considerationItem.identifierOrCriteria,
- amount: (block.timestamp < startTime || block.timestamp >= endTime)
- ? 0
- : _applyFraction({
- numerator: numerator,
- denominator: denominator,
- item: considerationItem,
- startTime: startTime,
- endTime: endTime
- }),
- recipient: considerationItem.recipient
- });
- }
-
- function _locateCurrentAmount(
- OfferItem memory item,
- uint256 startTime,
- uint256 endTime
- ) private view returns (uint256) {
- return
- _locateCurrentAmount({
- startAmount: item.startAmount,
- endAmount: item.endAmount,
- startTime: startTime,
- endTime: endTime,
- roundUp: false
- });
- }
-
- function deriveFractionCompatibleAmounts(
- uint256 originalStartAmount,
- uint256 originalEndAmount,
- uint256 startTime,
- uint256 endTime,
- uint256 numerator,
- uint256 denominator
- ) public pure returns (uint256 newStartAmount, uint256 newEndAmount) {
- if (
- startTime >= endTime ||
- numerator > denominator ||
- numerator == 0 ||
- denominator == 0 ||
- (originalStartAmount == 0 && originalEndAmount == 0)
- ) {
- revert(
- "AmountDeriverHelper: bad inputs to deriveFractionCompatibleAmounts"
- );
- }
-
- uint256 duration = endTime - startTime;
-
- // determine if duration or numerator is more likely to overflow when multiplied by value
- uint256 overflowBottleneck = (numerator > duration)
- ? numerator
- : duration;
-
- uint256 absoluteMax = type(uint256).max / overflowBottleneck;
- uint256 fractionCompatibleMax = (absoluteMax / denominator) *
- denominator;
-
- newStartAmount = originalStartAmount % fractionCompatibleMax;
- newStartAmount = (newStartAmount / denominator) * denominator;
- newStartAmount = (newStartAmount == 0) ? denominator : newStartAmount;
-
- newEndAmount = originalEndAmount % fractionCompatibleMax;
- newEndAmount = (newEndAmount / denominator) * denominator;
- newEndAmount = (newEndAmount == 0) ? denominator : newEndAmount;
-
- if (newStartAmount == 0 && newEndAmount == 0) {
- revert("AmountDeriverHelper: derived amount will always be zero");
- }
- }
-
- function _locateCurrentAmount(
- ConsiderationItem memory item,
- uint256 startTime,
- uint256 endTime
- ) private view returns (uint256) {
- return
- _locateCurrentAmount({
- startAmount: item.startAmount,
- endAmount: item.endAmount,
- startTime: startTime,
- endTime: endTime,
- roundUp: true
- });
- }
-
- function _applyFraction(
- uint256 numerator,
- uint256 denominator,
- uint256 startTime,
- uint256 endTime,
- OfferItem memory item
- ) internal view returns (uint256) {
- uint256 startAmount = item.startAmount;
- uint256 endAmount = item.endAmount;
- return
- _applyFraction({
- numerator: numerator,
- denominator: denominator,
- startAmount: startAmount,
- endAmount: endAmount,
- startTime: startTime,
- endTime: endTime,
- roundUp: false // don't round up offers
- });
- }
-
- function _applyFraction(
- uint256 numerator,
- uint256 denominator,
- uint256 startTime,
- uint256 endTime,
- ConsiderationItem memory item
- ) internal view returns (uint256) {
- uint256 startAmount = item.startAmount;
- uint256 endAmount = item.endAmount;
-
- return
- _applyFraction({
- numerator: numerator,
- denominator: denominator,
- startAmount: startAmount,
- endAmount: endAmount,
- startTime: startTime,
- endTime: endTime,
- roundUp: true // round up considerations
- });
- }
-}
diff --git a/contracts/helpers/sol/lib/types/MatchComponentType.sol b/contracts/helpers/sol/lib/types/MatchComponentType.sol
deleted file mode 100644
index cb8ebe2ed..000000000
--- a/contracts/helpers/sol/lib/types/MatchComponentType.sol
+++ /dev/null
@@ -1,182 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { FulfillmentComponent } from "../../SeaportStructs.sol";
-
-struct MatchComponent {
- uint256 amount;
- uint8 orderIndex;
- uint8 itemIndex;
-}
-
-library MatchComponentType {
- using MatchComponentType for MatchComponent;
-
- uint256 private constant AMOUNT_SHL_OFFSET = 16;
- uint256 private constant ORDER_INDEX_SHL_OFFSET = 8;
- uint256 private constant BYTE_MASK = 0xFF;
- uint256 private constant AMOUNT_MASK =
- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0000;
- uint256 private constant ORDER_INDEX_MASK = 0xFF00;
- uint256 private constant ITEM_INDEX_MASK = 0xFF;
- uint256 private constant NOT_AMOUNT_MASK = 0xFFFF;
- uint256 private constant NOT_ORDER_INDEX_MASK =
- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00FF;
- uint256 private constant NOT_ITEM_INDEX_MASK =
- 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00;
-
- function createMatchComponent(
- uint256 amount,
- uint8 orderIndex,
- uint8 itemIndex
- ) internal pure returns (MatchComponent memory component) {
- component.amount = amount;
- component.orderIndex = orderIndex;
- component.itemIndex = itemIndex;
- // assembly {
- // component := or(
- // shl(AMOUNT_SHL_OFFSET, amount),
- // or(shl(ORDER_INDEX_SHL_OFFSET, orderIndex), itemIndex)
- // )
- // }
- }
-
- function getAmount(
- MatchComponent memory component
- ) internal pure returns (uint256 amount) {
- return component.amount;
- }
-
- function copy(
- MatchComponent memory component
- ) internal pure returns (MatchComponent memory copy_) {
- copy_.amount = component.amount;
- copy_.orderIndex = component.orderIndex;
- copy_.itemIndex = component.itemIndex;
- }
-
- function setAmount(
- MatchComponent memory component,
- uint256 amount
- ) internal pure returns (MatchComponent memory newComponent) {
- newComponent = component.copy();
- newComponent.amount = amount;
- }
-
- function getOrderIndex(
- MatchComponent memory component
- ) internal pure returns (uint8 orderIndex) {
- return component.orderIndex;
- }
-
- function setOrderIndex(
- MatchComponent memory component,
- uint8 orderIndex
- ) internal pure returns (MatchComponent memory newComponent) {
- newComponent = component.copy();
- newComponent.orderIndex = orderIndex;
- }
-
- function getItemIndex(
- MatchComponent memory component
- ) internal pure returns (uint8 itemIndex) {
- return component.itemIndex;
- }
-
- function setItemIndex(
- MatchComponent memory component,
- uint8 itemIndex
- ) internal pure returns (MatchComponent memory newComponent) {
- newComponent = component.copy();
- newComponent.itemIndex = itemIndex;
- }
-
- function unpack(
- MatchComponent memory component
- )
- internal
- pure
- returns (uint256 amount, uint8 orderIndex, uint8 itemIndex)
- {
- return (component.amount, component.orderIndex, component.itemIndex);
- }
-
- function subtractAmount(
- MatchComponent memory minuend,
- MatchComponent memory subtrahend
- ) internal pure returns (MatchComponent memory newComponent) {
- uint256 minuendAmount = minuend.getAmount();
- uint256 subtrahendAmount = subtrahend.getAmount();
- uint256 newAmount = uint256(minuendAmount - subtrahendAmount);
- return minuend.setAmount(newAmount);
- }
-
- function addAmount(
- MatchComponent memory target,
- MatchComponent memory ref
- ) internal pure returns (MatchComponent memory) {
- uint256 targetAmount = target.getAmount();
- uint256 refAmount = ref.getAmount();
- uint256 newAmount = uint256(targetAmount + refAmount);
- return target.setAmount(newAmount);
- }
-
- function toFulfillmentComponent(
- MatchComponent memory component
- ) internal pure returns (FulfillmentComponent memory) {
- (, uint8 orderIndex, uint8 itemIndex) = component.unpack();
- return
- FulfillmentComponent({
- orderIndex: orderIndex,
- itemIndex: itemIndex
- });
- }
-
- function toFulfillmentComponents(
- MatchComponent[] memory components
- ) internal pure returns (FulfillmentComponent[] memory) {
- FulfillmentComponent[]
- memory fulfillmentComponents = new FulfillmentComponent[](
- components.length
- );
- for (uint256 i = 0; i < components.length; i++) {
- fulfillmentComponents[i] = components[i].toFulfillmentComponent();
- }
- return fulfillmentComponents;
- }
-
- function toStruct(
- MatchComponent memory component
- ) internal pure returns (MatchComponent memory) {
- (uint256 amount, uint8 orderIndex, uint8 itemIndex) = component
- .unpack();
- return
- MatchComponent({
- amount: amount,
- orderIndex: orderIndex,
- itemIndex: itemIndex
- });
- }
-
- function toStructs(
- MatchComponent[] memory components
- ) internal pure returns (MatchComponent[] memory) {
- MatchComponent[] memory structs = new MatchComponent[](
- components.length
- );
- for (uint256 i = 0; i < components.length; i++) {
- structs[i] = components[i].toStruct();
- }
- return structs;
- }
-
- function equals(
- MatchComponent memory left,
- MatchComponent memory right
- ) internal pure returns (bool) {
- return
- left.amount == right.amount &&
- left.orderIndex == right.orderIndex &&
- left.itemIndex == right.itemIndex;
- }
-}
diff --git a/contracts/interfaces/AbridgedTokenInterfaces.sol b/contracts/interfaces/AbridgedTokenInterfaces.sol
deleted file mode 100644
index 9cadced25..000000000
--- a/contracts/interfaces/AbridgedTokenInterfaces.sol
+++ /dev/null
@@ -1,195 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title ERC20Interface
- * @notice Contains the minimum interfaces needed to interact with ERC20s.
- */
-interface ERC20Interface {
- /**
- * @dev Allows an operator to transfer tokens on behalf of an owner.
- *
- * @param from The address of the owner.
- * @param to The address of the recipient.
- * @param value The amount of tokens to transfer.
- *
- * @return success True if the transfer was successful.
- */
- function transferFrom(
- address from,
- address to,
- uint256 value
- ) external returns (bool success);
-
- /**
- * @dev Allows an operator to approve a spender to transfer tokens on behalf
- * of a user.
- *
- * @param spender The address of the spender.
- * @param value The amount of tokens to approve.
- *
- * @return success True if the approval was successful.
- */
- function approve(
- address spender,
- uint256 value
- ) external returns (bool success);
-
- /**
- * @dev Returns the balance of a user.
- *
- * @param account The address of the user.
- *
- * @return balance The balance of the user.
- */
- function balanceOf(address account) external view returns (uint256);
-
- /**
- * @dev Returns the amount which spender is still allowed to withdraw
- * from owner.
- *
- * @param owner The address of the owner.
- * @param spender The address of the spender.
- *
- * @return remaining The amount of tokens that the spender is allowed to
- * transfer on behalf of the owner.
- */
- function allowance(
- address owner,
- address spender
- ) external view returns (uint256 remaining);
-}
-
-/**
- * @title ERC721Interface
- * @notice Contains the minimum interfaces needed to interact with ERC721s.
- */
-interface ERC721Interface {
- /**
- * @dev Allows an operator to transfer tokens on behalf of an owner.
- *
- * @param from The address of the owner.
- * @param to The address of the recipient.
- * @param tokenId The ID of the token to transfer.
- */
- function transferFrom(address from, address to, uint256 tokenId) external;
-
- /**
- * @dev Allows an owner to approve an operator to transfer all tokens on a
- * contract on behalf of the owner.
- *
- * @param to The address of the operator.
- * @param approved Whether the operator is approved.
- */
- function setApprovalForAll(address to, bool approved) external;
-
- /**
- * @dev Returns the account approved for tokenId token
- *
- * @param tokenId The tokenId to query the approval of.
- *
- * @return operator The approved account of the tokenId.
- */
- function getApproved(
- uint256 tokenId
- ) external view returns (address operator);
-
- /**
- * @dev Returns whether an operator is allowed to manage all of
- * the assets of owner.
- *
- * @param owner The address of the owner.
- * @param operator The address of the operator.
- *
- * @return approved True if the operator is approved by the owner.
- */
- function isApprovedForAll(
- address owner,
- address operator
- ) external view returns (bool);
-
- /**
- * @dev Returns the owner of a given token ID.
- *
- * @param tokenId The token ID.
- *
- * @return owner The owner of the token.
- */
- function ownerOf(uint256 tokenId) external view returns (address owner);
-}
-
-/**
- * @title ERC1155Interface
- * @notice Contains the minimum interfaces needed to interact with ERC1155s.
- */
-interface ERC1155Interface {
- /**
- * @dev Allows an operator to transfer tokens on behalf of an owner.
- *
- * @param from The address of the owner.
- * @param to The address of the recipient.
- * @param id The ID of the token(s) to transfer.
- * @param amount The amount of tokens to transfer.
- * @param data Additional data.
- */
- function safeTransferFrom(
- address from,
- address to,
- uint256 id,
- uint256 amount,
- bytes calldata data
- ) external;
-
- /**
- * @dev Allows an operator to transfer tokens on behalf of an owner.
- *
- * @param from The address of the owner.
- * @param to The address of the recipient.
- * @param ids The IDs of the token(s) to transfer.
- * @param amounts The amounts of tokens to transfer.
- * @param data Additional data.
- */
- function safeBatchTransferFrom(
- address from,
- address to,
- uint256[] calldata ids,
- uint256[] calldata amounts,
- bytes calldata data
- ) external;
-
- /**
- * @dev Allows an owner to approve an operator to transfer all tokens on a
- * contract on behalf of the owner.
- *
- * @param to The address of the operator.
- * @param approved Whether the operator is approved.
- */
- function setApprovalForAll(address to, bool approved) external;
-
- /**
- * @dev Returns the amount of token type id owned by account.
- *
- * @param account The address of the account.
- * @param id The id of the token.
- *
- * @return balance The amount of tokens of type id owned by account.
- */
- function balanceOf(
- address account,
- uint256 id
- ) external view returns (uint256);
-
- /**
- * @dev Returns true if operator is approved to transfer account's tokens.
- *
- * @param account The address of the account.
- * @param operator The address of the operator.
- *
- * @return approved True if the operator is approved to transfer account's
- * tokens.
- */
- function isApprovedForAll(
- address account,
- address operator
- ) external view returns (bool);
-}
diff --git a/contracts/interfaces/AmountDerivationErrors.sol b/contracts/interfaces/AmountDerivationErrors.sol
deleted file mode 100644
index 31b62e5b8..000000000
--- a/contracts/interfaces/AmountDerivationErrors.sol
+++ /dev/null
@@ -1,15 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title AmountDerivationErrors
- * @author 0age
- * @notice AmountDerivationErrors contains errors related to amount derivation.
- */
-interface AmountDerivationErrors {
- /**
- * @dev Revert with an error when attempting to apply a fraction as part of
- * a partial fill that does not divide the target amount cleanly.
- */
- error InexactFraction();
-}
diff --git a/contracts/interfaces/ConduitControllerInterface.sol b/contracts/interfaces/ConduitControllerInterface.sol
deleted file mode 100644
index 6de8f8885..000000000
--- a/contracts/interfaces/ConduitControllerInterface.sol
+++ /dev/null
@@ -1,296 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title ConduitControllerInterface
- * @author 0age
- * @notice ConduitControllerInterface contains all external function interfaces,
- * structs, events, and errors for the conduit controller.
- */
-interface ConduitControllerInterface {
- /**
- * @dev Track the conduit key, current owner, new potential owner, and open
- * channels for each deployed conduit.
- */
- struct ConduitProperties {
- bytes32 key;
- address owner;
- address potentialOwner;
- address[] channels;
- mapping(address => uint256) channelIndexesPlusOne;
- }
-
- /**
- * @dev Emit an event whenever a new conduit is created.
- *
- * @param conduit The newly created conduit.
- * @param conduitKey The conduit key used to create the new conduit.
- */
- event NewConduit(address conduit, bytes32 conduitKey);
-
- /**
- * @dev Emit an event whenever conduit ownership is transferred.
- *
- * @param conduit The conduit for which ownership has been
- * transferred.
- * @param previousOwner The previous owner of the conduit.
- * @param newOwner The new owner of the conduit.
- */
- event OwnershipTransferred(
- address indexed conduit,
- address indexed previousOwner,
- address indexed newOwner
- );
-
- /**
- * @dev Emit an event whenever a conduit owner registers a new potential
- * owner for that conduit.
- *
- * @param newPotentialOwner The new potential owner of the conduit.
- */
- event PotentialOwnerUpdated(address indexed newPotentialOwner);
-
- /**
- * @dev Revert with an error when attempting to create a new conduit using a
- * conduit key where the first twenty bytes of the key do not match the
- * address of the caller.
- */
- error InvalidCreator();
-
- /**
- * @dev Revert with an error when attempting to create a new conduit when no
- * initial owner address is supplied.
- */
- error InvalidInitialOwner();
-
- /**
- * @dev Revert with an error when attempting to set a new potential owner
- * that is already set.
- */
- error NewPotentialOwnerAlreadySet(
- address conduit,
- address newPotentialOwner
- );
-
- /**
- * @dev Revert with an error when attempting to cancel ownership transfer
- * when no new potential owner is currently set.
- */
- error NoPotentialOwnerCurrentlySet(address conduit);
-
- /**
- * @dev Revert with an error when attempting to interact with a conduit that
- * does not yet exist.
- */
- error NoConduit();
-
- /**
- * @dev Revert with an error when attempting to create a conduit that
- * already exists.
- */
- error ConduitAlreadyExists(address conduit);
-
- /**
- * @dev Revert with an error when attempting to update channels or transfer
- * ownership of a conduit when the caller is not the owner of the
- * conduit in question.
- */
- error CallerIsNotOwner(address conduit);
-
- /**
- * @dev Revert with an error when attempting to register a new potential
- * owner and supplying the null address.
- */
- error NewPotentialOwnerIsZeroAddress(address conduit);
-
- /**
- * @dev Revert with an error when attempting to claim ownership of a conduit
- * with a caller that is not the current potential owner for the
- * conduit in question.
- */
- error CallerIsNotNewPotentialOwner(address conduit);
-
- /**
- * @dev Revert with an error when attempting to retrieve a channel using an
- * index that is out of range.
- */
- error ChannelOutOfRange(address conduit);
-
- /**
- * @notice Deploy a new conduit using a supplied conduit key and assigning
- * an initial owner for the deployed conduit. Note that the first
- * twenty bytes of the supplied conduit key must match the caller
- * and that a new conduit cannot be created if one has already been
- * deployed using the same conduit key.
- *
- * @param conduitKey The conduit key used to deploy the conduit. Note that
- * the first twenty bytes of the conduit key must match
- * the caller of this contract.
- * @param initialOwner The initial owner to set for the new conduit.
- *
- * @return conduit The address of the newly deployed conduit.
- */
- function createConduit(
- bytes32 conduitKey,
- address initialOwner
- ) external returns (address conduit);
-
- /**
- * @notice Open or close a channel on a given conduit, thereby allowing the
- * specified account to execute transfers against that conduit.
- * Extreme care must be taken when updating channels, as malicious
- * or vulnerable channels can transfer any ERC20, ERC721 and ERC1155
- * tokens where the token holder has granted the conduit approval.
- * Only the owner of the conduit in question may call this function.
- *
- * @param conduit The conduit for which to open or close the channel.
- * @param channel The channel to open or close on the conduit.
- * @param isOpen A boolean indicating whether to open or close the channel.
- */
- function updateChannel(
- address conduit,
- address channel,
- bool isOpen
- ) external;
-
- /**
- * @notice Initiate conduit ownership transfer by assigning a new potential
- * owner for the given conduit. Once set, the new potential owner
- * may call `acceptOwnership` to claim ownership of the conduit.
- * Only the owner of the conduit in question may call this function.
- *
- * @param conduit The conduit for which to initiate ownership transfer.
- * @param newPotentialOwner The new potential owner of the conduit.
- */
- function transferOwnership(
- address conduit,
- address newPotentialOwner
- ) external;
-
- /**
- * @notice Clear the currently set potential owner, if any, from a conduit.
- * Only the owner of the conduit in question may call this function.
- *
- * @param conduit The conduit for which to cancel ownership transfer.
- */
- function cancelOwnershipTransfer(address conduit) external;
-
- /**
- * @notice Accept ownership of a supplied conduit. Only accounts that the
- * current owner has set as the new potential owner may call this
- * function.
- *
- * @param conduit The conduit for which to accept ownership.
- */
- function acceptOwnership(address conduit) external;
-
- /**
- * @notice Retrieve the current owner of a deployed conduit.
- *
- * @param conduit The conduit for which to retrieve the associated owner.
- *
- * @return owner The owner of the supplied conduit.
- */
- function ownerOf(address conduit) external view returns (address owner);
-
- /**
- * @notice Retrieve the conduit key for a deployed conduit via reverse
- * lookup.
- *
- * @param conduit The conduit for which to retrieve the associated conduit
- * key.
- *
- * @return conduitKey The conduit key used to deploy the supplied conduit.
- */
- function getKey(address conduit) external view returns (bytes32 conduitKey);
-
- /**
- * @notice Derive the conduit associated with a given conduit key and
- * determine whether that conduit exists (i.e. whether it has been
- * deployed).
- *
- * @param conduitKey The conduit key used to derive the conduit.
- *
- * @return conduit The derived address of the conduit.
- * @return exists A boolean indicating whether the derived conduit has been
- * deployed or not.
- */
- function getConduit(
- bytes32 conduitKey
- ) external view returns (address conduit, bool exists);
-
- /**
- * @notice Retrieve the potential owner, if any, for a given conduit. The
- * current owner may set a new potential owner via
- * `transferOwnership` and that owner may then accept ownership of
- * the conduit in question via `acceptOwnership`.
- *
- * @param conduit The conduit for which to retrieve the potential owner.
- *
- * @return potentialOwner The potential owner, if any, for the conduit.
- */
- function getPotentialOwner(
- address conduit
- ) external view returns (address potentialOwner);
-
- /**
- * @notice Retrieve the status (either open or closed) of a given channel on
- * a conduit.
- *
- * @param conduit The conduit for which to retrieve the channel status.
- * @param channel The channel for which to retrieve the status.
- *
- * @return isOpen The status of the channel on the given conduit.
- */
- function getChannelStatus(
- address conduit,
- address channel
- ) external view returns (bool isOpen);
-
- /**
- * @notice Retrieve the total number of open channels for a given conduit.
- *
- * @param conduit The conduit for which to retrieve the total channel count.
- *
- * @return totalChannels The total number of open channels for the conduit.
- */
- function getTotalChannels(
- address conduit
- ) external view returns (uint256 totalChannels);
-
- /**
- * @notice Retrieve an open channel at a specific index for a given conduit.
- * Note that the index of a channel can change as a result of other
- * channels being closed on the conduit.
- *
- * @param conduit The conduit for which to retrieve the open channel.
- * @param channelIndex The index of the channel in question.
- *
- * @return channel The open channel, if any, at the specified channel index.
- */
- function getChannel(
- address conduit,
- uint256 channelIndex
- ) external view returns (address channel);
-
- /**
- * @notice Retrieve all open channels for a given conduit. Note that calling
- * this function for a conduit with many channels will revert with
- * an out-of-gas error.
- *
- * @param conduit The conduit for which to retrieve open channels.
- *
- * @return channels An array of open channels on the given conduit.
- */
- function getChannels(
- address conduit
- ) external view returns (address[] memory channels);
-
- /**
- * @dev Retrieve the conduit creation code and runtime code hashes.
- */
- function getConduitCodeHashes()
- external
- view
- returns (bytes32 creationCodeHash, bytes32 runtimeCodeHash);
-}
diff --git a/contracts/interfaces/ConduitInterface.sol b/contracts/interfaces/ConduitInterface.sol
deleted file mode 100644
index 113b464ba..000000000
--- a/contracts/interfaces/ConduitInterface.sol
+++ /dev/null
@@ -1,96 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- ConduitBatch1155Transfer,
- ConduitTransfer
-} from "../conduit/lib/ConduitStructs.sol";
-
-/**
- * @title ConduitInterface
- * @author 0age
- * @notice ConduitInterface contains all external function interfaces, events,
- * and errors for conduit contracts.
- */
-interface ConduitInterface {
- /**
- * @dev Revert with an error when attempting to execute transfers using a
- * caller that does not have an open channel.
- */
- error ChannelClosed(address channel);
-
- /**
- * @dev Revert with an error when attempting to update a channel to the
- * current status of that channel.
- */
- error ChannelStatusAlreadySet(address channel, bool isOpen);
-
- /**
- * @dev Revert with an error when attempting to execute a transfer for an
- * item that does not have an ERC20/721/1155 item type.
- */
- error InvalidItemType();
-
- /**
- * @dev Revert with an error when attempting to update the status of a
- * channel from a caller that is not the conduit controller.
- */
- error InvalidController();
-
- /**
- * @dev Emit an event whenever a channel is opened or closed.
- *
- * @param channel The channel that has been updated.
- * @param open A boolean indicating whether the conduit is open or not.
- */
- event ChannelUpdated(address indexed channel, bool open);
-
- /**
- * @notice Execute a sequence of ERC20/721/1155 transfers. Only a caller
- * with an open channel can call this function.
- *
- * @param transfers The ERC20/721/1155 transfers to perform.
- *
- * @return magicValue A magic value indicating that the transfers were
- * performed successfully.
- */
- function execute(
- ConduitTransfer[] calldata transfers
- ) external returns (bytes4 magicValue);
-
- /**
- * @notice Execute a sequence of batch 1155 transfers. Only a caller with an
- * open channel can call this function.
- *
- * @param batch1155Transfers The 1155 batch transfers to perform.
- *
- * @return magicValue A magic value indicating that the transfers were
- * performed successfully.
- */
- function executeBatch1155(
- ConduitBatch1155Transfer[] calldata batch1155Transfers
- ) external returns (bytes4 magicValue);
-
- /**
- * @notice Execute a sequence of transfers, both single and batch 1155. Only
- * a caller with an open channel can call this function.
- *
- * @param standardTransfers The ERC20/721/1155 transfers to perform.
- * @param batch1155Transfers The 1155 batch transfers to perform.
- *
- * @return magicValue A magic value indicating that the transfers were
- * performed successfully.
- */
- function executeWithBatch1155(
- ConduitTransfer[] calldata standardTransfers,
- ConduitBatch1155Transfer[] calldata batch1155Transfers
- ) external returns (bytes4 magicValue);
-
- /**
- * @notice Open or close a given channel. Only callable by the controller.
- *
- * @param channel The channel to open or close.
- * @param isOpen The status of the channel (either open or closed).
- */
- function updateChannel(address channel, bool isOpen) external;
-}
diff --git a/contracts/interfaces/ConsiderationEventsAndErrors.sol b/contracts/interfaces/ConsiderationEventsAndErrors.sol
deleted file mode 100644
index b13abf590..000000000
--- a/contracts/interfaces/ConsiderationEventsAndErrors.sol
+++ /dev/null
@@ -1,210 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- OrderParameters,
- ReceivedItem,
- SpentItem
-} from "../lib/ConsiderationStructs.sol";
-
-/**
- * @title ConsiderationEventsAndErrors
- * @author 0age
- * @notice ConsiderationEventsAndErrors contains all events and errors.
- */
-interface ConsiderationEventsAndErrors {
- /**
- * @dev Emit an event whenever an order is successfully fulfilled.
- *
- * @param orderHash The hash of the fulfilled order.
- * @param offerer The offerer of the fulfilled order.
- * @param zone The zone of the fulfilled order.
- * @param recipient The recipient of each spent item on the fulfilled
- * order, or the null address if there is no specific
- * fulfiller (i.e. the order is part of a group of
- * orders). Defaults to the caller unless explicitly
- * specified otherwise by the fulfiller.
- * @param offer The offer items spent as part of the order.
- * @param consideration The consideration items received as part of the
- * order along with the recipients of each item.
- */
- event OrderFulfilled(
- bytes32 orderHash,
- address indexed offerer,
- address indexed zone,
- address recipient,
- SpentItem[] offer,
- ReceivedItem[] consideration
- );
-
- /**
- * @dev Emit an event whenever an order is successfully cancelled.
- *
- * @param orderHash The hash of the cancelled order.
- * @param offerer The offerer of the cancelled order.
- * @param zone The zone of the cancelled order.
- */
- event OrderCancelled(
- bytes32 orderHash,
- address indexed offerer,
- address indexed zone
- );
-
- /**
- * @dev Emit an event whenever an order is explicitly validated. Note that
- * this event will not be emitted on partial fills even though they do
- * validate the order as part of partial fulfillment.
- *
- * @param orderHash The hash of the validated order.
- * @param orderParameters The parameters of the validated order.
- */
- event OrderValidated(bytes32 orderHash, OrderParameters orderParameters);
-
- /**
- * @dev Emit an event whenever one or more orders are matched using either
- * matchOrders or matchAdvancedOrders.
- *
- * @param orderHashes The order hashes of the matched orders.
- */
- event OrdersMatched(bytes32[] orderHashes);
-
- /**
- * @dev Emit an event whenever a counter for a given offerer is incremented.
- *
- * @param newCounter The new counter for the offerer.
- * @param offerer The offerer in question.
- */
- event CounterIncremented(uint256 newCounter, address indexed offerer);
-
- /**
- * @dev Revert with an error when attempting to fill an order that has
- * already been fully filled.
- *
- * @param orderHash The order hash on which a fill was attempted.
- */
- error OrderAlreadyFilled(bytes32 orderHash);
-
- /**
- * @dev Revert with an error when attempting to fill an order outside the
- * specified start time and end time.
- *
- * @param startTime The time at which the order becomes active.
- * @param endTime The time at which the order becomes inactive.
- */
- error InvalidTime(uint256 startTime, uint256 endTime);
-
- /**
- * @dev Revert with an error when attempting to fill an order referencing an
- * invalid conduit (i.e. one that has not been deployed).
- */
- error InvalidConduit(bytes32 conduitKey, address conduit);
-
- /**
- * @dev Revert with an error when an order is supplied for fulfillment with
- * a consideration array that is shorter than the original array.
- */
- error MissingOriginalConsiderationItems();
-
- /**
- * @dev Revert with an error when an order is validated and the length of
- * the consideration array is not equal to the supplied total original
- * consideration items value. This error is also thrown when contract
- * orders supply a total original consideration items value that does
- * not match the supplied consideration array length.
- */
- error ConsiderationLengthNotEqualToTotalOriginal();
-
- /**
- * @dev Revert with an error when a call to a conduit fails with revert data
- * that is too expensive to return.
- */
- error InvalidCallToConduit(address conduit);
-
- /**
- * @dev Revert with an error if a consideration amount has not been fully
- * zeroed out after applying all fulfillments.
- *
- * @param orderIndex The index of the order with the consideration
- * item with a shortfall.
- * @param considerationIndex The index of the consideration item on the
- * order.
- * @param shortfallAmount The unfulfilled consideration amount.
- */
- error ConsiderationNotMet(
- uint256 orderIndex,
- uint256 considerationIndex,
- uint256 shortfallAmount
- );
-
- /**
- * @dev Revert with an error when insufficient native tokens are supplied as
- * part of msg.value when fulfilling orders.
- */
- error InsufficientNativeTokensSupplied();
-
- /**
- * @dev Revert with an error when a native token transfer reverts.
- */
- error NativeTokenTransferGenericFailure(address account, uint256 amount);
-
- /**
- * @dev Revert with an error when a partial fill is attempted on an order
- * that does not specify partial fill support in its order type.
- */
- error PartialFillsNotEnabledForOrder();
-
- /**
- * @dev Revert with an error when attempting to fill an order that has been
- * cancelled.
- *
- * @param orderHash The hash of the cancelled order.
- */
- error OrderIsCancelled(bytes32 orderHash);
-
- /**
- * @dev Revert with an error when attempting to fill a basic order that has
- * been partially filled.
- *
- * @param orderHash The hash of the partially used order.
- */
- error OrderPartiallyFilled(bytes32 orderHash);
-
- /**
- * @dev Revert with an error when attempting to cancel an order as a caller
- * other than the indicated offerer or zone or when attempting to
- * cancel a contract order.
- */
- error CannotCancelOrder();
-
- /**
- * @dev Revert with an error when supplying a fraction with a value of zero
- * for the numerator or denominator, or one where the numerator exceeds
- * the denominator.
- */
- error BadFraction();
-
- /**
- * @dev Revert with an error when a caller attempts to supply callvalue to a
- * non-payable basic order route or does not supply any callvalue to a
- * payable basic order route.
- */
- error InvalidMsgValue(uint256 value);
-
- /**
- * @dev Revert with an error when attempting to fill a basic order using
- * calldata not produced by default ABI encoding.
- */
- error InvalidBasicOrderParameterEncoding();
-
- /**
- * @dev Revert with an error when attempting to fulfill any number of
- * available orders when none are fulfillable.
- */
- error NoSpecifiedOrdersAvailable();
-
- /**
- * @dev Revert with an error when attempting to fulfill an order with an
- * offer for a native token outside of matching orders.
- */
- error InvalidNativeOfferItem();
-}
diff --git a/contracts/interfaces/ConsiderationInterface.sol b/contracts/interfaces/ConsiderationInterface.sol
deleted file mode 100644
index 3a3d07d72..000000000
--- a/contracts/interfaces/ConsiderationInterface.sol
+++ /dev/null
@@ -1,480 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- AdvancedOrder,
- BasicOrderParameters,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- Order,
- OrderComponents
-} from "../lib/ConsiderationStructs.sol";
-
-/**
- * @title ConsiderationInterface
- * @author 0age
- * @custom:version 1.5
- * @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155
- * marketplace. It minimizes external calls to the greatest extent
- * possible and provides lightweight methods for common routes as well
- * as more flexible methods for composing advanced orders.
- *
- * @dev ConsiderationInterface contains all external function interfaces for
- * Consideration.
- */
-interface ConsiderationInterface {
- /**
- * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
- * the native token for the given chain) as consideration for the
- * order. An arbitrary number of "additional recipients" may also be
- * supplied which will each receive native tokens from the fulfiller
- * as consideration.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer must first approve this contract (or
- * their preferred conduit if indicated by the order) for
- * their offered ERC721 token to be transferred.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillBasicOrder(
- BasicOrderParameters calldata parameters
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Fulfill an order with an arbitrary number of items for offer and
- * consideration. Note that this function does not support
- * criteria-based orders or partial filling of orders (though
- * filling the remainder of a partially-filled order is supported).
- *
- * @param order The order to fulfill. Note that both the
- * offerer and the fulfiller must first approve
- * this contract (or the corresponding conduit if
- * indicated) to transfer any relevant tokens on
- * their behalf and that contracts must implement
- * `onERC1155Received` to receive ERC1155 tokens
- * as consideration.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Consideration.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillOrder(
- Order calldata order,
- bytes32 fulfillerConduitKey
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Fill an order, fully or partially, with an arbitrary number of
- * items for offer and consideration alongside criteria resolvers
- * containing specific token identifiers and associated proofs.
- *
- * @param advancedOrder The order to fulfill along with the fraction
- * of the order to attempt to fill. Note that
- * both the offerer and the fulfiller must first
- * approve this contract (or their preferred
- * conduit if indicated by the order) to transfer
- * any relevant tokens on their behalf and that
- * contracts must implement `onERC1155Received`
- * to receive ERC1155 tokens as consideration.
- * Also note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount with
- * the supplied fraction for the partial fill to
- * be considered valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a proof
- * that the supplied token identifier is
- * contained in the merkle root held by the item
- * in question's criteria element. Note that an
- * empty criteria indicates that any
- * (transferable) token identifier on the token
- * in question is valid and that no associated
- * proof needs to be supplied.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Consideration.
- * @param recipient The intended recipient for all received items,
- * with `address(0)` indicating that the caller
- * should receive the items.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillAdvancedOrder(
- AdvancedOrder calldata advancedOrder,
- CriteriaResolver[] calldata criteriaResolvers,
- bytes32 fulfillerConduitKey,
- address recipient
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Attempt to fill a group of orders, each with an arbitrary number
- * of items for offer and consideration. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- * Note that this function does not support criteria-based orders or
- * partial filling of orders (though filling the remainder of a
- * partially-filled order is supported).
- *
- * @param orders The orders to fulfill. Note that both
- * the offerer and the fulfiller must first
- * approve this contract (or the
- * corresponding conduit if indicated) to
- * transfer any relevant tokens on their
- * behalf and that contracts must implement
- * `onERC1155Received` to receive ERC1155
- * tokens as consideration.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used, with
- * direct approvals set on this contract.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or
- * native tokens will not be reflected as part of
- * this array.
- */
- function fulfillAvailableOrders(
- Order[] calldata orders,
- FulfillmentComponent[][] calldata offerFulfillments,
- FulfillmentComponent[][] calldata considerationFulfillments,
- bytes32 fulfillerConduitKey,
- uint256 maximumFulfilled
- )
- external
- payable
- returns (bool[] memory availableOrders, Execution[] memory executions);
-
- /**
- * @notice Attempt to fill a group of orders, fully or partially, with an
- * arbitrary number of items for offer and consideration per order
- * alongside criteria resolvers containing specific token
- * identifiers and associated proofs. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- *
- * @param advancedOrders The orders to fulfill along with the
- * fraction of those orders to attempt to
- * fill. Note that both the offerer and the
- * fulfiller must first approve this
- * contract (or their preferred conduit if
- * indicated by the order) to transfer any
- * relevant tokens on their behalf and that
- * contracts must implement
- * `onERC1155Received` to enable receipt of
- * ERC1155 tokens as consideration. Also
- * note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount
- * with the supplied fraction for an
- * order's partial fill amount to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a
- * proof that the supplied token identifier
- * is contained in the merkle root held by
- * the item in question's criteria element.
- * Note that an empty criteria indicates
- * that any (transferable) token
- * identifier on the token in question is
- * valid and that no associated proof needs
- * to be supplied.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used, with
- * direct approvals set on this contract.
- * @param recipient The intended recipient for all received
- * items, with `address(0)` indicating that
- * the caller should receive the items.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or
- * native tokens will not be reflected as part of
- * this array.
- */
- function fulfillAvailableAdvancedOrders(
- AdvancedOrder[] calldata advancedOrders,
- CriteriaResolver[] calldata criteriaResolvers,
- FulfillmentComponent[][] calldata offerFulfillments,
- FulfillmentComponent[][] calldata considerationFulfillments,
- bytes32 fulfillerConduitKey,
- address recipient,
- uint256 maximumFulfilled
- )
- external
- payable
- returns (bool[] memory availableOrders, Execution[] memory executions);
-
- /**
- * @notice Match an arbitrary number of orders, each with an arbitrary
- * number of items for offer and consideration along with a set of
- * fulfillments allocating offer components to consideration
- * components. Note that this function does not support
- * criteria-based or partial filling of orders (though filling the
- * remainder of a partially-filled order is supported). Any unspent
- * offer item amounts or native tokens will be transferred to the
- * caller.
- *
- * @param orders The orders to match. Note that both the offerer and
- * fulfiller on each order must first approve this
- * contract (or their conduit if indicated by the order)
- * to transfer any relevant tokens on their behalf and
- * each consideration recipient must implement
- * `onERC1155Received` to enable ERC1155 token receipt.
- * @param fulfillments An array of elements allocating offer components to
- * consideration components. Note that each
- * consideration component must be fully met for the
- * match operation to be valid.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or
- * native tokens will not be reflected as part of this
- * array.
- */
- function matchOrders(
- Order[] calldata orders,
- Fulfillment[] calldata fulfillments
- ) external payable returns (Execution[] memory executions);
-
- /**
- * @notice Match an arbitrary number of full or partial orders, each with an
- * arbitrary number of items for offer and consideration, supplying
- * criteria resolvers containing specific token identifiers and
- * associated proofs as well as fulfillments allocating offer
- * components to consideration components. Any unspent offer item
- * amounts will be transferred to the designated recipient (with the
- * null address signifying to use the caller) and any unspent native
- * tokens will be returned to the caller.
- *
- * @param orders The advanced orders to match. Note that both the
- * offerer and fulfiller on each order must first
- * approve this contract (or a preferred conduit if
- * indicated by the order) to transfer any relevant
- * tokens on their behalf and each consideration
- * recipient must implement `onERC1155Received` in
- * order to receive ERC1155 tokens. Also note that
- * the offer and consideration components for each
- * order must have no remainder after multiplying
- * the respective amount with the supplied fraction
- * in order for the group of partial fills to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a reference
- * to a specific order as well as that order's
- * offer or consideration, a token identifier, and
- * a proof that the supplied token identifier is
- * contained in the order's merkle root. Note that
- * an empty root indicates that any (transferable)
- * token identifier is valid and that no associated
- * proof needs to be supplied.
- * @param fulfillments An array of elements allocating offer components
- * to consideration components. Note that each
- * consideration component must be fully met in
- * order for the match operation to be valid.
- * @param recipient The intended recipient for all unspent offer
- * item amounts, or the caller if the null address
- * is supplied.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or native
- * tokens will not be reflected as part of this array.
- */
- function matchAdvancedOrders(
- AdvancedOrder[] calldata orders,
- CriteriaResolver[] calldata criteriaResolvers,
- Fulfillment[] calldata fulfillments,
- address recipient
- ) external payable returns (Execution[] memory executions);
-
- /**
- * @notice Cancel an arbitrary number of orders. Note that only the offerer
- * or the zone of a given order may cancel it. Callers should ensure
- * that the intended order was cancelled by calling `getOrderStatus`
- * and confirming that `isCancelled` returns `true`.
- *
- * @param orders The orders to cancel.
- *
- * @return cancelled A boolean indicating whether the supplied orders have
- * been successfully cancelled.
- */
- function cancel(
- OrderComponents[] calldata orders
- ) external returns (bool cancelled);
-
- /**
- * @notice Validate an arbitrary number of orders, thereby registering their
- * signatures as valid and allowing the fulfiller to skip signature
- * verification on fulfillment. Note that validated orders may still
- * be unfulfillable due to invalid item amounts or other factors;
- * callers should determine whether validated orders are fulfillable
- * by simulating the fulfillment call prior to execution. Also note
- * that anyone can validate a signed order, but only the offerer can
- * validate an order without supplying a signature.
- *
- * @param orders The orders to validate.
- *
- * @return validated A boolean indicating whether the supplied orders have
- * been successfully validated.
- */
- function validate(
- Order[] calldata orders
- ) external returns (bool validated);
-
- /**
- * @notice Cancel all orders from a given offerer with a given zone in bulk
- * by incrementing a counter. Note that only the offerer may
- * increment the counter.
- *
- * @return newCounter The new counter.
- */
- function incrementCounter() external returns (uint256 newCounter);
-
- /**
- * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
- * the native token for the given chain) as consideration for the
- * order. An arbitrary number of "additional recipients" may also be
- * supplied which will each receive native tokens from the fulfiller
- * as consideration. Note that this function costs less gas than
- * `fulfillBasicOrder` due to the zero bytes in the function
- * selector (0x00000000) which also results in earlier function
- * dispatch.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer must first approve this contract (or
- * their preferred conduit if indicated by the order) for
- * their offered ERC721 token to be transferred.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillBasicOrder_efficient_6GL6yc(
- BasicOrderParameters calldata parameters
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Retrieve the order hash for a given order.
- *
- * @param order The components of the order.
- *
- * @return orderHash The order hash.
- */
- function getOrderHash(
- OrderComponents calldata order
- ) external view returns (bytes32 orderHash);
-
- /**
- * @notice Retrieve the status of a given order by hash, including whether
- * the order has been cancelled or validated and the fraction of the
- * order that has been filled.
- *
- * @param orderHash The order hash in question.
- *
- * @return isValidated A boolean indicating whether the order in question
- * has been validated (i.e. previously approved or
- * partially filled).
- * @return isCancelled A boolean indicating whether the order in question
- * has been cancelled.
- * @return totalFilled The total portion of the order that has been filled
- * (i.e. the "numerator").
- * @return totalSize The total size of the order that is either filled or
- * unfilled (i.e. the "denominator").
- */
- function getOrderStatus(
- bytes32 orderHash
- )
- external
- view
- returns (
- bool isValidated,
- bool isCancelled,
- uint256 totalFilled,
- uint256 totalSize
- );
-
- /**
- * @notice Retrieve the current counter for a given offerer.
- *
- * @param offerer The offerer in question.
- *
- * @return counter The current counter.
- */
- function getCounter(
- address offerer
- ) external view returns (uint256 counter);
-
- /**
- * @notice Retrieve configuration information for this contract.
- *
- * @return version The contract version.
- * @return domainSeparator The domain separator for this contract.
- * @return conduitController The conduit Controller set for this contract.
- */
- function information()
- external
- view
- returns (
- string memory version,
- bytes32 domainSeparator,
- address conduitController
- );
-
- function getContractOffererNonce(
- address contractOfferer
- ) external view returns (uint256 nonce);
-
- /**
- * @notice Retrieve the name of this contract.
- *
- * @return contractName The name of this contract.
- */
- function name() external view returns (string memory contractName);
-}
diff --git a/contracts/interfaces/ContractOffererInterface.sol b/contracts/interfaces/ContractOffererInterface.sol
deleted file mode 100644
index 72b6b1ff5..000000000
--- a/contracts/interfaces/ContractOffererInterface.sol
+++ /dev/null
@@ -1,106 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- ReceivedItem,
- Schema,
- SpentItem
-} from "../lib/ConsiderationStructs.sol";
-import { IERC165 } from "../interfaces/IERC165.sol";
-
-/**
- * @title ContractOffererInterface
- * @notice Contains the minimum interfaces needed to interact with a contract
- * offerer.
- */
-interface ContractOffererInterface is IERC165 {
- /**
- * @dev Generates an order with the specified minimum and maximum spent
- * items, and optional context (supplied as extraData).
- *
- * @param fulfiller The address of the fulfiller.
- * @param minimumReceived The minimum items that the caller is willing to
- * receive.
- * @param maximumSpent The maximum items the caller is willing to spend.
- * @param context Additional context of the order.
- *
- * @return offer A tuple containing the offer items.
- * @return consideration A tuple containing the consideration items.
- */
- function generateOrder(
- address fulfiller,
- SpentItem[] calldata minimumReceived,
- SpentItem[] calldata maximumSpent,
- bytes calldata context // encoded based on the schemaID
- )
- external
- returns (SpentItem[] memory offer, ReceivedItem[] memory consideration);
-
- /**
- * @dev Ratifies an order with the specified offer, consideration, and
- * optional context (supplied as extraData).
- *
- * @param offer The offer items.
- * @param consideration The consideration items.
- * @param context Additional context of the order.
- * @param orderHashes The hashes to ratify.
- * @param contractNonce The nonce of the contract.
- *
- * @return ratifyOrderMagicValue The magic value returned by the contract
- * offerer.
- */
- function ratifyOrder(
- SpentItem[] calldata offer,
- ReceivedItem[] calldata consideration,
- bytes calldata context, // encoded based on the schemaID
- bytes32[] calldata orderHashes,
- uint256 contractNonce
- ) external returns (bytes4 ratifyOrderMagicValue);
-
- /**
- * @dev View function to preview an order generated in response to a minimum
- * set of received items, maximum set of spent items, and context
- * (supplied as extraData).
- *
- * @param caller The address of the caller (e.g. Seaport).
- * @param fulfiller The address of the fulfiller (e.g. the account
- * calling Seaport).
- * @param minimumReceived The minimum items that the caller is willing to
- * receive.
- * @param maximumSpent The maximum items the caller is willing to spend.
- * @param context Additional context of the order.
- *
- * @return offer A tuple containing the offer items.
- * @return consideration A tuple containing the consideration items.
- */
- function previewOrder(
- address caller,
- address fulfiller,
- SpentItem[] calldata minimumReceived,
- SpentItem[] calldata maximumSpent,
- bytes calldata context // encoded based on the schemaID
- )
- external
- view
- returns (SpentItem[] memory offer, ReceivedItem[] memory consideration);
-
- /**
- * @dev Gets the metadata for this contract offerer.
- *
- * @return name The name of the contract offerer.
- * @return schemas The schemas supported by the contract offerer.
- */
- function getSeaportMetadata()
- external
- view
- returns (
- string memory name,
- Schema[] memory schemas // map to Seaport Improvement Proposal IDs
- );
-
- function supportsInterface(
- bytes4 interfaceId
- ) external view override returns (bool);
-
- // Additional functions and/or events based on implemented schemaIDs
-}
diff --git a/contracts/interfaces/CriteriaResolutionErrors.sol b/contracts/interfaces/CriteriaResolutionErrors.sol
deleted file mode 100644
index 641032eec..000000000
--- a/contracts/interfaces/CriteriaResolutionErrors.sol
+++ /dev/null
@@ -1,70 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import { Side } from "../lib/ConsiderationEnums.sol";
-
-/**
- * @title CriteriaResolutionErrors
- * @author 0age
- * @notice CriteriaResolutionErrors contains all errors related to criteria
- * resolution.
- */
-interface CriteriaResolutionErrors {
- /**
- * @dev Revert with an error when providing a criteria resolver that refers
- * to an order that has not been supplied.
- *
- * @param side The side of the order that was not supplied.
- */
- error OrderCriteriaResolverOutOfRange(Side side);
-
- /**
- * @dev Revert with an error if an offer item still has unresolved criteria
- * after applying all criteria resolvers.
- *
- * @param orderIndex The index of the order that contains the offer item.
- * @param offerIndex The index of the offer item that still has unresolved
- * criteria.
- */
- error UnresolvedOfferCriteria(uint256 orderIndex, uint256 offerIndex);
-
- /**
- * @dev Revert with an error if a consideration item still has unresolved
- * criteria after applying all criteria resolvers.
- *
- * @param orderIndex The index of the order that contains the
- * consideration item.
- * @param considerationIndex The index of the consideration item that still
- * has unresolved criteria.
- */
- error UnresolvedConsiderationCriteria(
- uint256 orderIndex,
- uint256 considerationIndex
- );
-
- /**
- * @dev Revert with an error when providing a criteria resolver that refers
- * to an order with an offer item that has not been supplied.
- */
- error OfferCriteriaResolverOutOfRange();
-
- /**
- * @dev Revert with an error when providing a criteria resolver that refers
- * to an order with a consideration item that has not been supplied.
- */
- error ConsiderationCriteriaResolverOutOfRange();
-
- /**
- * @dev Revert with an error when providing a criteria resolver that refers
- * to an order with an item that does not expect a criteria to be
- * resolved.
- */
- error CriteriaNotEnabledForItem();
-
- /**
- * @dev Revert with an error when providing a criteria resolver that
- * contains an invalid proof with respect to the given item and
- * chosen identifier.
- */
- error InvalidProof();
-}
diff --git a/contracts/interfaces/EIP1271Interface.sol b/contracts/interfaces/EIP1271Interface.sol
deleted file mode 100644
index cbc54ea4f..000000000
--- a/contracts/interfaces/EIP1271Interface.sol
+++ /dev/null
@@ -1,22 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title EIP1271Interface
- * @notice Interface for the EIP-1271 standard signature validation method for
- * contracts.
- */
-interface EIP1271Interface {
- /**
- * @dev Validates a smart contract signature
- *
- * @param digest bytes32 The digest of the data to be signed.
- * @param signature bytes The signature of the data to be validated.
- *
- * @return bytes4 The magic value, if the signature is valid.
- */
- function isValidSignature(
- bytes32 digest,
- bytes calldata signature
- ) external view returns (bytes4);
-}
diff --git a/contracts/interfaces/ERC165.sol b/contracts/interfaces/ERC165.sol
deleted file mode 100644
index 2f46133dd..000000000
--- a/contracts/interfaces/ERC165.sol
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: MIT
-// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
-
-pragma solidity ^0.8.7;
-
-import "./IERC165.sol";
-
-/**
- * @dev Implementation of the {IERC165} interface.
- *
- * Contracts that want to implement ERC165 should inherit from this contract
- * and override {supportsInterface} to check for the additional interface id
- * that will be supported.
- *
- * Alternatively, {ERC165Storage} provides an easier to use but more
- * expensive implementation.
- */
-abstract contract ERC165 is IERC165 {
- /**
- * @dev See {IERC165-supportsInterface}.
- */
- function supportsInterface(
- bytes4 interfaceId
- ) public view virtual override returns (bool) {
- return interfaceId == type(IERC165).interfaceId;
- }
-}
diff --git a/contracts/interfaces/FulfillmentApplicationErrors.sol b/contracts/interfaces/FulfillmentApplicationErrors.sol
deleted file mode 100644
index 6cd5bab8a..000000000
--- a/contracts/interfaces/FulfillmentApplicationErrors.sol
+++ /dev/null
@@ -1,45 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import { Side } from "../lib/ConsiderationEnums.sol";
-
-/**
- * @title FulfillmentApplicationErrors
- * @author 0age
- * @notice FulfillmentApplicationErrors contains errors related to fulfillment
- * application and aggregation.
- */
-interface FulfillmentApplicationErrors {
- /**
- * @dev Revert with an error when a fulfillment is provided that does not
- * declare at least one component as part of a call to fulfill
- * available orders.
- */
- error MissingFulfillmentComponentOnAggregation(Side side);
-
- /**
- * @dev Revert with an error when a fulfillment is provided that does not
- * declare at least one offer component and at least one consideration
- * component.
- */
- error OfferAndConsiderationRequiredOnFulfillment();
-
- /**
- * @dev Revert with an error when the initial offer item named by a
- * fulfillment component does not match the type, token, identifier,
- * or conduit preference of the initial consideration item.
- *
- * @param fulfillmentIndex The index of the fulfillment component that
- * does not match the initial offer item.
- */
- error MismatchedFulfillmentOfferAndConsiderationComponents(
- uint256 fulfillmentIndex
- );
-
- /**
- * @dev Revert with an error when an order or item index are out of range
- * or a fulfillment component does not match the type, token,
- * identifier, or conduit preference of the initial consideration item.
- */
- error InvalidFulfillmentComponentData();
-}
diff --git a/contracts/interfaces/IERC1271.sol b/contracts/interfaces/IERC1271.sol
deleted file mode 100644
index 32d694bd5..000000000
--- a/contracts/interfaces/IERC1271.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: MIT
-// OpenZeppelin Contracts v4.4.1 (interfaces/IERC1271.sol)
-
-pragma solidity ^0.8.7;
-
-/**
- * @dev Interface of the ERC1271 standard signature validation method for
- * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271].
- *
- * _Available since v4.1._
- */
-interface IERC1271 {
- /**
- * @dev Should return whether the signature provided is valid for the
- * provided data
- * @param hash Hash of the data to be signed
- * @param signature Signature byte array associated with _data
- */
- function isValidSignature(
- bytes32 hash,
- bytes memory signature
- ) external view returns (bytes4 magicValue);
-}
diff --git a/contracts/interfaces/IERC165.sol b/contracts/interfaces/IERC165.sol
deleted file mode 100644
index 4c270d647..000000000
--- a/contracts/interfaces/IERC165.sol
+++ /dev/null
@@ -1,23 +0,0 @@
-// SPDX-License-Identifier: MIT
-// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
-
-pragma solidity ^0.8.7;
-
-/**
- * @dev Interface of the ERC165 standard, as defined in the
- * https://eips.ethereum.org/EIPS/eip-165[EIP].
- *
- * Implementers can declare support of contract interfaces, which can then be
- * queried by others ({ERC165Checker}).
- *
- * For an implementation, see {ERC165}.
- */
-interface IERC165 {
- /**
- * @dev Returns true if this contract implements the interface defined by
- * `interfaceId`.
- *
- * This function call must use less than 30 000 gas.
- */
- function supportsInterface(bytes4 interfaceId) external view returns (bool);
-}
diff --git a/contracts/interfaces/IERC2981.sol b/contracts/interfaces/IERC2981.sol
deleted file mode 100644
index 75e57ac9a..000000000
--- a/contracts/interfaces/IERC2981.sol
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: MIT
-// OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol)
-
-pragma solidity ^0.8.7;
-
-import "./IERC165.sol";
-
-/**
- * @dev Interface for the NFT Royalty Standard.
- *
- * A standardized way to retrieve royalty payment information for
- * non-fungible tokens (NFTs) to enable universal support for royalty payments
- * across all NFT marketplaces and ecosystem participants.
- *
- * _Available since v4.5._
- */
-interface IERC2981 is IERC165 {
- /**
- * @dev Returns how much royalty is owed and to whom, based on a sale price
- * that may be denominated in any unit of exchange. The royalty amount
- * is denominated and should be paid in that same unit of exchange.
- */
- function royaltyInfo(
- uint256 tokenId,
- uint256 salePrice
- ) external view returns (address receiver, uint256 royaltyAmount);
-}
diff --git a/contracts/interfaces/IERC721Receiver.sol b/contracts/interfaces/IERC721Receiver.sol
deleted file mode 100644
index 01027abd1..000000000
--- a/contracts/interfaces/IERC721Receiver.sol
+++ /dev/null
@@ -1,27 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title ERC721 token receiver interface
- * @dev Interface for any contract that wants to support safeTransfers
- * from ERC721 asset contracts.
- */
-interface IERC721Receiver {
- /**
- * @dev Whenever an ERC721 token is transferred to this contract via
- * safeTransferFrom, this function is called.
- *
- * @param operator The address of the operator.
- * @param from The address of the sender.
- * @param tokenId The ID of the ERC721.
- * @param data Additional data.
- *
- * @return bytes4 The magic value, unless throwing.
- */
- function onERC721Received(
- address operator,
- address from,
- uint256 tokenId,
- bytes calldata data
- ) external returns (bytes4);
-}
diff --git a/contracts/interfaces/ReentrancyErrors.sol b/contracts/interfaces/ReentrancyErrors.sol
deleted file mode 100644
index 9e3685f1d..000000000
--- a/contracts/interfaces/ReentrancyErrors.sol
+++ /dev/null
@@ -1,15 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title ReentrancyErrors
- * @author 0age
- * @notice ReentrancyErrors contains errors related to reentrancy.
- */
-interface ReentrancyErrors {
- /**
- * @dev Revert with an error when a caller attempts to reenter a protected
- * function.
- */
- error NoReentrantCalls();
-}
diff --git a/contracts/interfaces/SeaportInterface.sol b/contracts/interfaces/SeaportInterface.sol
deleted file mode 100644
index e510ed0cb..000000000
--- a/contracts/interfaces/SeaportInterface.sol
+++ /dev/null
@@ -1,479 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- AdvancedOrder,
- BasicOrderParameters,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- Order,
- OrderComponents
-} from "../lib/ConsiderationStructs.sol";
-
-/**
- * @title SeaportInterface
- * @author 0age
- * @custom:version 1.5
- * @notice Seaport is a generalized native token/ERC20/ERC721/ERC1155
- * marketplace. It minimizes external calls to the greatest extent
- * possible and provides lightweight methods for common routes as well
- * as more flexible methods for composing advanced orders.
- *
- * @dev SeaportInterface contains all external function interfaces for Seaport.
- */
-interface SeaportInterface {
- /**
- * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
- * the native token for the given chain) as consideration for the
- * order. An arbitrary number of "additional recipients" may also be
- * supplied which will each receive native tokens from the fulfiller
- * as consideration.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer must first approve this contract (or
- * their preferred conduit if indicated by the order) for
- * their offered ERC721 token to be transferred.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillBasicOrder(
- BasicOrderParameters calldata parameters
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Fulfill an order with an arbitrary number of items for offer and
- * consideration. Note that this function does not support
- * criteria-based orders or partial filling of orders (though
- * filling the remainder of a partially-filled order is supported).
- *
- * @param order The order to fulfill. Note that both the
- * offerer and the fulfiller must first approve
- * this contract (or the corresponding conduit if
- * indicated) to transfer any relevant tokens on
- * their behalf and that contracts must implement
- * `onERC1155Received` to receive ERC1155 tokens
- * as consideration.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Seaport.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillOrder(
- Order calldata order,
- bytes32 fulfillerConduitKey
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Fill an order, fully or partially, with an arbitrary number of
- * items for offer and consideration alongside criteria resolvers
- * containing specific token identifiers and associated proofs.
- *
- * @param advancedOrder The order to fulfill along with the fraction
- * of the order to attempt to fill. Note that
- * both the offerer and the fulfiller must first
- * approve this contract (or their preferred
- * conduit if indicated by the order) to transfer
- * any relevant tokens on their behalf and that
- * contracts must implement `onERC1155Received`
- * to receive ERC1155 tokens as consideration.
- * Also note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount with
- * the supplied fraction for the partial fill to
- * be considered valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a proof
- * that the supplied token identifier is
- * contained in the merkle root held by the item
- * in question's criteria element. Note that an
- * empty criteria indicates that any
- * (transferable) token identifier on the token
- * in question is valid and that no associated
- * proof needs to be supplied.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Seaport.
- * @param recipient The intended recipient for all received items,
- * with `address(0)` indicating that the caller
- * should receive the items.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillAdvancedOrder(
- AdvancedOrder calldata advancedOrder,
- CriteriaResolver[] calldata criteriaResolvers,
- bytes32 fulfillerConduitKey,
- address recipient
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Attempt to fill a group of orders, each with an arbitrary number
- * of items for offer and consideration. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- * Note that this function does not support criteria-based orders or
- * partial filling of orders (though filling the remainder of a
- * partially-filled order is supported).
- *
- * @param orders The orders to fulfill. Note that both
- * the offerer and the fulfiller must first
- * approve this contract (or the
- * corresponding conduit if indicated) to
- * transfer any relevant tokens on their
- * behalf and that contracts must implement
- * `onERC1155Received` to receive ERC1155
- * tokens as consideration.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used, with
- * direct approvals set on this contract.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or
- * native tokens will not be reflected as part of
- * this array.
- */
- function fulfillAvailableOrders(
- Order[] calldata orders,
- FulfillmentComponent[][] calldata offerFulfillments,
- FulfillmentComponent[][] calldata considerationFulfillments,
- bytes32 fulfillerConduitKey,
- uint256 maximumFulfilled
- )
- external
- payable
- returns (bool[] memory availableOrders, Execution[] memory executions);
-
- /**
- * @notice Attempt to fill a group of orders, fully or partially, with an
- * arbitrary number of items for offer and consideration per order
- * alongside criteria resolvers containing specific token
- * identifiers and associated proofs. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- *
- * @param advancedOrders The orders to fulfill along with the
- * fraction of those orders to attempt to
- * fill. Note that both the offerer and the
- * fulfiller must first approve this
- * contract (or their preferred conduit if
- * indicated by the order) to transfer any
- * relevant tokens on their behalf and that
- * contracts must implement
- * `onERC1155Received` to enable receipt of
- * ERC1155 tokens as consideration. Also
- * note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount
- * with the supplied fraction for an
- * order's partial fill amount to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a
- * proof that the supplied token identifier
- * is contained in the merkle root held by
- * the item in question's criteria element.
- * Note that an empty criteria indicates
- * that any (transferable) token
- * identifier on the token in question is
- * valid and that no associated proof needs
- * to be supplied.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used, with
- * direct approvals set on this contract.
- * @param recipient The intended recipient for all received
- * items, with `address(0)` indicating that
- * the caller should receive the items.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or
- * native tokens will not be reflected as part of
- * this array.
- */
- function fulfillAvailableAdvancedOrders(
- AdvancedOrder[] calldata advancedOrders,
- CriteriaResolver[] calldata criteriaResolvers,
- FulfillmentComponent[][] calldata offerFulfillments,
- FulfillmentComponent[][] calldata considerationFulfillments,
- bytes32 fulfillerConduitKey,
- address recipient,
- uint256 maximumFulfilled
- )
- external
- payable
- returns (bool[] memory availableOrders, Execution[] memory executions);
-
- /**
- * @notice Match an arbitrary number of orders, each with an arbitrary
- * number of items for offer and consideration along with a set of
- * fulfillments allocating offer components to consideration
- * components. Note that this function does not support
- * criteria-based or partial filling of orders (though filling the
- * remainder of a partially-filled order is supported). Any unspent
- * offer item amounts or native tokens will be transferred to the
- * caller.
- *
- * @param orders The orders to match. Note that both the offerer and
- * fulfiller on each order must first approve this
- * contract (or their conduit if indicated by the order)
- * to transfer any relevant tokens on their behalf and
- * each consideration recipient must implement
- * `onERC1155Received` to enable ERC1155 token receipt.
- * @param fulfillments An array of elements allocating offer components to
- * consideration components. Note that each
- * consideration component must be fully met for the
- * match operation to be valid.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or
- * native tokens will not be reflected as part of this
- * array.
- */
- function matchOrders(
- Order[] calldata orders,
- Fulfillment[] calldata fulfillments
- ) external payable returns (Execution[] memory executions);
-
- /**
- * @notice Match an arbitrary number of full or partial orders, each with an
- * arbitrary number of items for offer and consideration, supplying
- * criteria resolvers containing specific token identifiers and
- * associated proofs as well as fulfillments allocating offer
- * components to consideration components. Any unspent offer item
- * amounts will be transferred to the designated recipient (with the
- * null address signifying to use the caller) and any unspent native
- * tokens will be returned to the caller.
- *
- * @param orders The advanced orders to match. Note that both the
- * offerer and fulfiller on each order must first
- * approve this contract (or a preferred conduit if
- * indicated by the order) to transfer any relevant
- * tokens on their behalf and each consideration
- * recipient must implement `onERC1155Received` in
- * order to receive ERC1155 tokens. Also note that
- * the offer and consideration components for each
- * order must have no remainder after multiplying
- * the respective amount with the supplied fraction
- * in order for the group of partial fills to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a reference
- * to a specific order as well as that order's
- * offer or consideration, a token identifier, and
- * a proof that the supplied token identifier is
- * contained in the order's merkle root. Note that
- * an empty root indicates that any (transferable)
- * token identifier is valid and that no associated
- * proof needs to be supplied.
- * @param fulfillments An array of elements allocating offer components
- * to consideration components. Note that each
- * consideration component must be fully met in
- * order for the match operation to be valid.
- * @param recipient The intended recipient for all unspent offer
- * item amounts, or the caller if the null address
- * is supplied.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or native
- * tokens will not be reflected as part of this array.
- */
- function matchAdvancedOrders(
- AdvancedOrder[] calldata orders,
- CriteriaResolver[] calldata criteriaResolvers,
- Fulfillment[] calldata fulfillments,
- address recipient
- ) external payable returns (Execution[] memory executions);
-
- /**
- * @notice Cancel an arbitrary number of orders. Note that only the offerer
- * or the zone of a given order may cancel it. Callers should ensure
- * that the intended order was cancelled by calling `getOrderStatus`
- * and confirming that `isCancelled` returns `true`.
- *
- * @param orders The orders to cancel.
- *
- * @return cancelled A boolean indicating whether the supplied orders have
- * been successfully cancelled.
- */
- function cancel(
- OrderComponents[] calldata orders
- ) external returns (bool cancelled);
-
- /**
- * @notice Validate an arbitrary number of orders, thereby registering their
- * signatures as valid and allowing the fulfiller to skip signature
- * verification on fulfillment. Note that validated orders may still
- * be unfulfillable due to invalid item amounts or other factors;
- * callers should determine whether validated orders are fulfillable
- * by simulating the fulfillment call prior to execution. Also note
- * that anyone can validate a signed order, but only the offerer can
- * validate an order without supplying a signature.
- *
- * @param orders The orders to validate.
- *
- * @return validated A boolean indicating whether the supplied orders have
- * been successfully validated.
- */
- function validate(
- Order[] calldata orders
- ) external returns (bool validated);
-
- /**
- * @notice Cancel all orders from a given offerer with a given zone in bulk
- * by incrementing a counter. Note that only the offerer may
- * increment the counter.
- *
- * @return newCounter The new counter.
- */
- function incrementCounter() external returns (uint256 newCounter);
-
- /**
- * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
- * the native token for the given chain) as consideration for the
- * order. An arbitrary number of "additional recipients" may also be
- * supplied which will each receive native tokens from the fulfiller
- * as consideration. Note that this function costs less gas than
- * `fulfillBasicOrder` due to the zero bytes in the function
- * selector (0x00000000) which also results in earlier function
- * dispatch.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer must first approve this contract (or
- * their preferred conduit if indicated by the order) for
- * their offered ERC721 token to be transferred.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillBasicOrder_efficient_6GL6yc(
- BasicOrderParameters calldata parameters
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Retrieve the order hash for a given order.
- *
- * @param order The components of the order.
- *
- * @return orderHash The order hash.
- */
- function getOrderHash(
- OrderComponents calldata order
- ) external view returns (bytes32 orderHash);
-
- /**
- * @notice Retrieve the status of a given order by hash, including whether
- * the order has been cancelled or validated and the fraction of the
- * order that has been filled.
- *
- * @param orderHash The order hash in question.
- *
- * @return isValidated A boolean indicating whether the order in question
- * has been validated (i.e. previously approved or
- * partially filled).
- * @return isCancelled A boolean indicating whether the order in question
- * has been cancelled.
- * @return totalFilled The total portion of the order that has been filled
- * (i.e. the "numerator").
- * @return totalSize The total size of the order that is either filled or
- * unfilled (i.e. the "denominator").
- */
- function getOrderStatus(
- bytes32 orderHash
- )
- external
- view
- returns (
- bool isValidated,
- bool isCancelled,
- uint256 totalFilled,
- uint256 totalSize
- );
-
- /**
- * @notice Retrieve the current counter for a given offerer.
- *
- * @param offerer The offerer in question.
- *
- * @return counter The current counter.
- */
- function getCounter(
- address offerer
- ) external view returns (uint256 counter);
-
- /**
- * @notice Retrieve configuration information for this contract.
- *
- * @return version The contract version.
- * @return domainSeparator The domain separator for this contract.
- * @return conduitController The conduit Controller set for this contract.
- */
- function information()
- external
- view
- returns (
- string memory version,
- bytes32 domainSeparator,
- address conduitController
- );
-
- function getContractOffererNonce(
- address contractOfferer
- ) external view returns (uint256 nonce);
-
- /**
- * @notice Retrieve the name of this contract.
- *
- * @return contractName The name of this contract.
- */
- function name() external view returns (string memory contractName);
-}
diff --git a/contracts/interfaces/SeaportRouterInterface.sol b/contracts/interfaces/SeaportRouterInterface.sol
deleted file mode 100644
index 67423ca31..000000000
--- a/contracts/interfaces/SeaportRouterInterface.sol
+++ /dev/null
@@ -1,110 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- AdvancedOrder,
- CriteriaResolver,
- FulfillmentComponent
-} from "../lib/ConsiderationStructs.sol";
-
-import { Execution } from "../lib/ConsiderationStructs.sol";
-
-/**
- * @title SeaportRouterInterface
- * @author Ryan Ghods (ralxz.eth), 0age (0age.eth), James Wenzel (emo.eth)
- * @notice A utility contract for fulfilling orders with multiple
- * Seaport versions. DISCLAIMER: This contract only works when
- * all consideration items across all listings are native tokens.
- */
-interface SeaportRouterInterface {
- /**
- * @dev Revert with an error when attempting to fulfill any number of
- * available orders when none are fulfillable.
- */
- error NoSpecifiedOrdersAvailable();
-
- /**
- * @dev Advanced order parameters for use through the
- * FulfillAvailableAdvancedOrdersParams struct.
- */
- struct AdvancedOrderParams {
- AdvancedOrder[] advancedOrders;
- CriteriaResolver[] criteriaResolvers;
- FulfillmentComponent[][] offerFulfillments;
- FulfillmentComponent[][] considerationFulfillments;
- uint256 etherValue; /// The ether value to send with the set of orders.
- }
-
- /**
- * @dev Parameters for using fulfillAvailableAdvancedOrders
- * through SeaportRouter.
- */
- struct FulfillAvailableAdvancedOrdersParams {
- address[] seaportContracts;
- AdvancedOrderParams[] advancedOrderParams;
- bytes32 fulfillerConduitKey;
- address recipient;
- uint256 maximumFulfilled;
- }
-
- /**
- * @dev Calldata params for calling FulfillAvailableAdvancedOrders.
- */
- struct CalldataParams {
- AdvancedOrder[] advancedOrders;
- CriteriaResolver[] criteriaResolvers;
- FulfillmentComponent[][] offerFulfillments;
- FulfillmentComponent[][] considerationFulfillments;
- bytes32 fulfillerConduitKey;
- address recipient;
- uint256 maximumFulfilled;
- }
-
- /**
- * @dev Revert with an error if a provided Seaport contract is not allowed
- * to be used in the router.
- */
- error SeaportNotAllowed(address seaport);
-
- /**
- * @dev Revert with an error if an ether transfer back to the fulfiller
- * fails.
- */
- error EtherReturnTransferFailed(
- address recipient,
- uint256 amount,
- bytes returnData
- );
-
- /**
- * @dev Fallback function to receive excess ether, in case total amount of
- * ether sent is more than the amount required to fulfill the order.
- */
- receive() external payable;
-
- /**
- * @notice Fulfill available advanced orders through multiple Seaport
- * versions.
- * See {SeaportInterface-fulfillAvailableAdvancedOrders}
- *
- * @param params The parameters for fulfilling available advanced orders.
- */
- function fulfillAvailableAdvancedOrders(
- FulfillAvailableAdvancedOrdersParams calldata params
- )
- external
- payable
- returns (
- bool[][] memory availableOrders,
- Execution[][] memory executions
- );
-
- /**
- * @notice Returns the Seaport contracts allowed to be used through this
- * router.
- */
- function getAllowedSeaportContracts()
- external
- view
- returns (address[] memory);
-}
diff --git a/contracts/interfaces/SignatureVerificationErrors.sol b/contracts/interfaces/SignatureVerificationErrors.sol
deleted file mode 100644
index f0fdd04c1..000000000
--- a/contracts/interfaces/SignatureVerificationErrors.sol
+++ /dev/null
@@ -1,36 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title SignatureVerificationErrors
- * @author 0age
- * @notice SignatureVerificationErrors contains all errors related to signature
- * verification.
- */
-interface SignatureVerificationErrors {
- /**
- * @dev Revert with an error when a signature that does not contain a v
- * value of 27 or 28 has been supplied.
- *
- * @param v The invalid v value.
- */
- error BadSignatureV(uint8 v);
-
- /**
- * @dev Revert with an error when the signer recovered by the supplied
- * signature does not match the offerer or an allowed EIP-1271 signer
- * as specified by the offerer in the event they are a contract.
- */
- error InvalidSigner();
-
- /**
- * @dev Revert with an error when a signer cannot be recovered from the
- * supplied signature.
- */
- error InvalidSignature();
-
- /**
- * @dev Revert with an error when an EIP-1271 call to an account fails.
- */
- error BadContractSignature();
-}
diff --git a/contracts/interfaces/TokenTransferrerErrors.sol b/contracts/interfaces/TokenTransferrerErrors.sol
deleted file mode 100644
index 954d85f12..000000000
--- a/contracts/interfaces/TokenTransferrerErrors.sol
+++ /dev/null
@@ -1,97 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title TokenTransferrerErrors
- */
-interface TokenTransferrerErrors {
- /**
- * @dev Revert with an error when an ERC721 transfer with amount other than
- * one is attempted.
- *
- * @param amount The amount of the ERC721 tokens to transfer.
- */
- error InvalidERC721TransferAmount(uint256 amount);
-
- /**
- * @dev Revert with an error when attempting to fulfill an order where an
- * item has an amount of zero.
- */
- error MissingItemAmount();
-
- /**
- * @dev Revert with an error when attempting to fulfill an order where an
- * item has unused parameters. This includes both the token and the
- * identifier parameters for native transfers as well as the identifier
- * parameter for ERC20 transfers. Note that the conduit does not
- * perform this check, leaving it up to the calling channel to enforce
- * when desired.
- */
- error UnusedItemParameters();
-
- /**
- * @dev Revert with an error when an ERC20, ERC721, or ERC1155 token
- * transfer reverts.
- *
- * @param token The token for which the transfer was attempted.
- * @param from The source of the attempted transfer.
- * @param to The recipient of the attempted transfer.
- * @param identifier The identifier for the attempted transfer.
- * @param amount The amount for the attempted transfer.
- */
- error TokenTransferGenericFailure(
- address token,
- address from,
- address to,
- uint256 identifier,
- uint256 amount
- );
-
- /**
- * @dev Revert with an error when a batch ERC1155 token transfer reverts.
- *
- * @param token The token for which the transfer was attempted.
- * @param from The source of the attempted transfer.
- * @param to The recipient of the attempted transfer.
- * @param identifiers The identifiers for the attempted transfer.
- * @param amounts The amounts for the attempted transfer.
- */
- error ERC1155BatchTransferGenericFailure(
- address token,
- address from,
- address to,
- uint256[] identifiers,
- uint256[] amounts
- );
-
- /**
- * @dev Revert with an error when an ERC20 token transfer returns a falsey
- * value.
- *
- * @param token The token for which the ERC20 transfer was attempted.
- * @param from The source of the attempted ERC20 transfer.
- * @param to The recipient of the attempted ERC20 transfer.
- * @param amount The amount for the attempted ERC20 transfer.
- */
- error BadReturnValueFromERC20OnTransfer(
- address token,
- address from,
- address to,
- uint256 amount
- );
-
- /**
- * @dev Revert with an error when an account being called as an assumed
- * contract does not have code and returns no data.
- *
- * @param account The account that should contain code.
- */
- error NoContract(address account);
-
- /**
- * @dev Revert with an error when attempting to execute an 1155 batch
- * transfer using calldata not produced by default ABI encoding or with
- * different lengths for ids and amounts arrays.
- */
- error Invalid1155BatchTransferEncoding();
-}
diff --git a/contracts/interfaces/TransferHelperErrors.sol b/contracts/interfaces/TransferHelperErrors.sol
deleted file mode 100644
index 88ffc106a..000000000
--- a/contracts/interfaces/TransferHelperErrors.sol
+++ /dev/null
@@ -1,85 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/**
- * @title TransferHelperErrors
- */
-interface TransferHelperErrors {
- /**
- * @dev Revert with an error when attempting to execute transfers with a
- * NATIVE itemType.
- */
- error InvalidItemType();
-
- /**
- * @dev Revert with an error when an ERC721 transfer with amount other than
- * one is attempted.
- *
- * @param amount The amount of the ERC721 tokens to transfer.
- */
- error InvalidERC721TransferAmount(uint256 amount);
-
- /**
- * @dev Revert with an error when attempting to execute an ERC721 transfer
- * to an invalid recipient.
- */
- error InvalidERC721Recipient(address recipient);
-
- /**
- * @dev Revert with an error when a call to an ERC721 receiver reverts with
- * bytes data.
- */
- error ERC721ReceiverErrorRevertBytes(
- bytes reason,
- address receiver,
- address sender,
- uint256 identifier
- );
-
- /**
- * @dev Revert with an error when a call to an ERC721 receiver reverts with
- * string reason.
- */
- error ERC721ReceiverErrorRevertString(
- string reason,
- address receiver,
- address sender,
- uint256 identifier
- );
-
- /**
- * @dev Revert with an error when an ERC20 token has an invalid identifier.
- */
- error InvalidERC20Identifier();
-
- /**
- * @dev Revert with an error if the recipient is the zero address.
- */
- error RecipientCannotBeZeroAddress();
-
- /**
- * @dev Revert with an error when attempting to fill an order referencing an
- * invalid conduit (i.e. one that has not been deployed).
- */
- error InvalidConduit(bytes32 conduitKey, address conduit);
-
- /**
- * @dev Revert with an error when a call to a conduit reverts with a
- * reason string.
- */
- error ConduitErrorRevertString(
- string reason,
- bytes32 conduitKey,
- address conduit
- );
-
- /**
- * @dev Revert with an error when a call to a conduit reverts with bytes
- * data.
- */
- error ConduitErrorRevertBytes(
- bytes reason,
- bytes32 conduitKey,
- address conduit
- );
-}
diff --git a/contracts/interfaces/TransferHelperInterface.sol b/contracts/interfaces/TransferHelperInterface.sol
deleted file mode 100644
index c9478f32c..000000000
--- a/contracts/interfaces/TransferHelperInterface.sol
+++ /dev/null
@@ -1,19 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- TransferHelperItemsWithRecipient
-} from "../helpers/TransferHelperStructs.sol";
-
-interface TransferHelperInterface {
- /**
- * @notice Transfer multiple items to a single recipient.
- *
- * @param items The items to transfer.
- * @param conduitKey The key of the conduit performing the bulk transfer.
- */
- function bulkTransfer(
- TransferHelperItemsWithRecipient[] calldata items,
- bytes32 conduitKey
- ) external returns (bytes4);
-}
diff --git a/contracts/interfaces/ZoneInterface.sol b/contracts/interfaces/ZoneInterface.sol
index 04234ff20..048b1e1ac 100644
--- a/contracts/interfaces/ZoneInterface.sol
+++ b/contracts/interfaces/ZoneInterface.sol
@@ -1,9 +1,12 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ZoneParameters, Schema } from "../lib/ConsiderationStructs.sol";
+import {
+ ZoneParameters,
+ Schema
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { IERC165 } from "../interfaces/IERC165.sol";
+import { IERC165 } from "seaport-types/src/interfaces/IERC165.sol";
/**
* @title ZoneInterface
diff --git a/contracts/interfaces/legacy/ConsiderationInterface1_1.sol b/contracts/interfaces/legacy/ConsiderationInterface1_1.sol
deleted file mode 100644
index 8c20c0c56..000000000
--- a/contracts/interfaces/legacy/ConsiderationInterface1_1.sol
+++ /dev/null
@@ -1,433 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.7;
-
-import {
- AdvancedOrder,
- BasicOrderParameters,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- Order,
- OrderComponents
-} from "../../lib/ConsiderationStructs.sol";
-
-/**
- * @title ConsiderationInterface1.1
- * @author 0age
- * @custom:version 1.1
- * *
- * @dev This is the legacy ConsiderationInterface from Seaport 1.1
- */
-interface ConsiderationInterface1_1 {
- /**
- * @notice Fulfill an order offering an ERC721 token by supplying Ether (or
- * the native token for the given chain) as consideration for the
- * order. An arbitrary number of "additional recipients" may also be
- * supplied which will each receive native tokens from the fulfiller
- * as consideration.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer must first approve this contract (or
- * their preferred conduit if indicated by the order) for
- * their offered ERC721 token to be transferred.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillBasicOrder(
- BasicOrderParameters calldata parameters
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Fulfill an order with an arbitrary number of items for offer and
- * consideration. Note that this function does not support
- * criteria-based orders or partial filling of orders (though
- * filling the remainder of a partially-filled order is supported).
- *
- * @param order The order to fulfill. Note that both the
- * offerer and the fulfiller must first approve
- * this contract (or the corresponding conduit if
- * indicated) to transfer any relevant tokens on
- * their behalf and that contracts must implement
- * `onERC1155Received` to receive ERC1155 tokens
- * as consideration.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Consideration.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillOrder(
- Order calldata order,
- bytes32 fulfillerConduitKey
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Fill an order, fully or partially, with an arbitrary number of
- * items for offer and consideration alongside criteria resolvers
- * containing specific token identifiers and associated proofs.
- *
- * @param advancedOrder The order to fulfill along with the fraction
- * of the order to attempt to fill. Note that
- * both the offerer and the fulfiller must first
- * approve this contract (or their preferred
- * conduit if indicated by the order) to transfer
- * any relevant tokens on their behalf and that
- * contracts must implement `onERC1155Received`
- * to receive ERC1155 tokens as consideration.
- * Also note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount with
- * the supplied fraction for the partial fill to
- * be considered valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a proof
- * that the supplied token identifier is
- * contained in the merkle root held by the item
- * in question's criteria element. Note that an
- * empty criteria indicates that any
- * (transferable) token identifier on the token
- * in question is valid and that no associated
- * proof needs to be supplied.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Consideration.
- * @param recipient The intended recipient for all received items,
- * with `address(0)` indicating that the caller
- * should receive the items.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillAdvancedOrder(
- AdvancedOrder calldata advancedOrder,
- CriteriaResolver[] calldata criteriaResolvers,
- bytes32 fulfillerConduitKey,
- address recipient
- ) external payable returns (bool fulfilled);
-
- /**
- * @notice Attempt to fill a group of orders, each with an arbitrary number
- * of items for offer and consideration. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- * Note that this function does not support criteria-based orders or
- * partial filling of orders (though filling the remainder of a
- * partially-filled order is supported).
- *
- * @param orders The orders to fulfill. Note that both
- * the offerer and the fulfiller must first
- * approve this contract (or the
- * corresponding conduit if indicated) to
- * transfer any relevant tokens on their
- * behalf and that contracts must implement
- * `onERC1155Received` to receive ERC1155
- * tokens as consideration.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used, with
- * direct approvals set on this contract.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function fulfillAvailableOrders(
- Order[] calldata orders,
- FulfillmentComponent[][] calldata offerFulfillments,
- FulfillmentComponent[][] calldata considerationFulfillments,
- bytes32 fulfillerConduitKey,
- uint256 maximumFulfilled
- )
- external
- payable
- returns (bool[] memory availableOrders, Execution[] memory executions);
-
- /**
- * @notice Attempt to fill a group of orders, fully or partially, with an
- * arbitrary number of items for offer and consideration per order
- * alongside criteria resolvers containing specific token
- * identifiers and associated proofs. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- *
- * @param advancedOrders The orders to fulfill along with the
- * fraction of those orders to attempt to
- * fill. Note that both the offerer and the
- * fulfiller must first approve this
- * contract (or their preferred conduit if
- * indicated by the order) to transfer any
- * relevant tokens on their behalf and that
- * contracts must implement
- * `onERC1155Received` to enable receipt of
- * ERC1155 tokens as consideration. Also
- * note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount
- * with the supplied fraction for an
- * order's partial fill amount to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a
- * proof that the supplied token identifier
- * is contained in the merkle root held by
- * the item in question's criteria element.
- * Note that an empty criteria indicates
- * that any (transferable) token
- * identifier on the token in question is
- * valid and that no associated proof needs
- * to be supplied.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used, with
- * direct approvals set on this contract.
- * @param recipient The intended recipient for all received
- * items, with `address(0)` indicating that
- * the caller should receive the items.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function fulfillAvailableAdvancedOrders(
- AdvancedOrder[] calldata advancedOrders,
- CriteriaResolver[] calldata criteriaResolvers,
- FulfillmentComponent[][] calldata offerFulfillments,
- FulfillmentComponent[][] calldata considerationFulfillments,
- bytes32 fulfillerConduitKey,
- address recipient,
- uint256 maximumFulfilled
- )
- external
- payable
- returns (bool[] memory availableOrders, Execution[] memory executions);
-
- /**
- * @notice Match an arbitrary number of orders, each with an arbitrary
- * number of items for offer and consideration along with as set of
- * fulfillments allocating offer components to consideration
- * components. Note that this function does not support
- * criteria-based or partial filling of orders (though filling the
- * remainder of a partially-filled order is supported).
- *
- * @param orders The orders to match. Note that both the offerer and
- * fulfiller on each order must first approve this
- * contract (or their conduit if indicated by the order)
- * to transfer any relevant tokens on their behalf and
- * each consideration recipient must implement
- * `onERC1155Received` to enable ERC1155 token receipt.
- * @param fulfillments An array of elements allocating offer components to
- * consideration components. Note that each
- * consideration component must be fully met for the
- * match operation to be valid.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function matchOrders(
- Order[] calldata orders,
- Fulfillment[] calldata fulfillments
- ) external payable returns (Execution[] memory executions);
-
- /**
- * @notice Match an arbitrary number of full or partial orders, each with an
- * arbitrary number of items for offer and consideration, supplying
- * criteria resolvers containing specific token identifiers and
- * associated proofs as well as fulfillments allocating offer
- * components to consideration components.
- *
- * @param orders The advanced orders to match. Note that both the
- * offerer and fulfiller on each order must first
- * approve this contract (or a preferred conduit if
- * indicated by the order) to transfer any relevant
- * tokens on their behalf and each consideration
- * recipient must implement `onERC1155Received` in
- * order to receive ERC1155 tokens. Also note that
- * the offer and consideration components for each
- * order must have no remainder after multiplying
- * the respective amount with the supplied fraction
- * in order for the group of partial fills to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a reference
- * to a specific order as well as that order's
- * offer or consideration, a token identifier, and
- * a proof that the supplied token identifier is
- * contained in the order's merkle root. Note that
- * an empty root indicates that any (transferable)
- * token identifier is valid and that no associated
- * proof needs to be supplied.
- * @param fulfillments An array of elements allocating offer components
- * to consideration components. Note that each
- * consideration component must be fully met in
- * order for the match operation to be valid.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function matchAdvancedOrders(
- AdvancedOrder[] calldata orders,
- CriteriaResolver[] calldata criteriaResolvers,
- Fulfillment[] calldata fulfillments
- ) external payable returns (Execution[] memory executions);
-
- /**
- * @notice Cancel an arbitrary number of orders. Note that only the offerer
- * or the zone of a given order may cancel it. Callers should ensure
- * that the intended order was cancelled by calling `getOrderStatus`
- * and confirming that `isCancelled` returns `true`.
- *
- * @param orders The orders to cancel.
- *
- * @return cancelled A boolean indicating whether the supplied orders have
- * been successfully cancelled.
- */
- function cancel(
- OrderComponents[] calldata orders
- ) external returns (bool cancelled);
-
- /**
- * @notice Validate an arbitrary number of orders, thereby registering their
- * signatures as valid and allowing the fulfiller to skip signature
- * verification on fulfillment. Note that validated orders may still
- * be unfulfillable due to invalid item amounts or other factors;
- * callers should determine whether validated orders are fulfillable
- * by simulating the fulfillment call prior to execution. Also note
- * that anyone can validate a signed order, but only the offerer can
- * validate an order without supplying a signature.
- *
- * @param orders The orders to validate.
- *
- * @return validated A boolean indicating whether the supplied orders have
- * been successfully validated.
- */
- function validate(
- Order[] calldata orders
- ) external returns (bool validated);
-
- /**
- * @notice Cancel all orders from a given offerer with a given zone in bulk
- * by incrementing a counter. Note that only the offerer may
- * increment the counter.
- *
- * @return newCounter The new counter.
- */
- function incrementCounter() external returns (uint256 newCounter);
-
- /**
- * @notice Retrieve the order hash for a given order.
- *
- * @param order The components of the order.
- *
- * @return orderHash The order hash.
- */
- function getOrderHash(
- OrderComponents calldata order
- ) external view returns (bytes32 orderHash);
-
- /**
- * @notice Retrieve the status of a given order by hash, including whether
- * the order has been cancelled or validated and the fraction of the
- * order that has been filled.
- *
- * @param orderHash The order hash in question.
- *
- * @return isValidated A boolean indicating whether the order in question
- * has been validated (i.e. previously approved or
- * partially filled).
- * @return isCancelled A boolean indicating whether the order in question
- * has been cancelled.
- * @return totalFilled The total portion of the order that has been filled
- * (i.e. the "numerator").
- * @return totalSize The total size of the order that is either filled or
- * unfilled (i.e. the "denominator").
- */
- function getOrderStatus(
- bytes32 orderHash
- )
- external
- view
- returns (
- bool isValidated,
- bool isCancelled,
- uint256 totalFilled,
- uint256 totalSize
- );
-
- /**
- * @notice Retrieve the current counter for a given offerer.
- *
- * @param offerer The offerer in question.
- *
- * @return counter The current counter.
- */
- function getCounter(
- address offerer
- ) external view returns (uint256 counter);
-
- /**
- * @notice Retrieve configuration information for this contract.
- *
- * @return version The contract version.
- * @return domainSeparator The domain separator for this contract.
- * @return conduitController The conduit Controller set for this contract.
- */
- function information()
- external
- view
- returns (
- string memory version,
- bytes32 domainSeparator,
- address conduitController
- );
-
- /**
- * @notice Retrieve the name of this contract.
- *
- * @return contractName The name of this contract.
- */
- function name() external view returns (string memory contractName);
-}
diff --git a/contracts/interfaces/legacy/ZoneInterface1_1.sol b/contracts/interfaces/legacy/ZoneInterface1_1.sol
deleted file mode 100644
index 75e1d289a..000000000
--- a/contracts/interfaces/legacy/ZoneInterface1_1.sol
+++ /dev/null
@@ -1,33 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.7;
-
-import {
- AdvancedOrder,
- CriteriaResolver
-} from "../../lib/ConsiderationStructs.sol";
-
-/**
- * @title ZoneInterface1.1
- * @author 0age
- * @custom:version 1.1
- *
- * @dev This is the legacy ZoneInterface from Seaport 1.1
- */
-interface ZoneInterface1_1 {
- // Called by Consideration whenever extraData is not provided by the caller.
- function isValidOrder(
- bytes32 orderHash,
- address caller,
- address offerer,
- bytes32 zoneHash
- ) external view returns (bytes4 validOrderMagicValue);
-
- // Called by Consideration whenever any extraData is provided by the caller.
- function isValidOrderIncludingExtraData(
- bytes32 orderHash,
- address caller,
- AdvancedOrder calldata order,
- bytes32[] calldata priorOrderHashes,
- CriteriaResolver[] calldata criteriaResolvers
- ) external view returns (bytes4 validOrderMagicValue);
-}
diff --git a/contracts/lib/AmountDeriver.sol b/contracts/lib/AmountDeriver.sol
deleted file mode 100644
index e03514af8..000000000
--- a/contracts/lib/AmountDeriver.sol
+++ /dev/null
@@ -1,187 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- AmountDerivationErrors
-} from "../interfaces/AmountDerivationErrors.sol";
-
-import {
- Error_selector_offset,
- InexactFraction_error_length,
- InexactFraction_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @title AmountDeriver
- * @author 0age
- * @notice AmountDeriver contains view and pure functions related to deriving
- * item amounts based on partial fill quantity and on linear
- * interpolation based on current time when the start amount and end
- * amount differ.
- */
-contract AmountDeriver is AmountDerivationErrors {
- /**
- * @dev Internal view function to derive the current amount of a given item
- * based on the current price, the starting price, and the ending
- * price. If the start and end prices differ, the current price will be
- * interpolated on a linear basis. Note that this function expects that
- * the startTime parameter of orderParameters is not greater than the
- * current block timestamp and that the endTime parameter is greater
- * than the current block timestamp. If this condition is not upheld,
- * duration / elapsed / remaining variables will underflow.
- *
- * @param startAmount The starting amount of the item.
- * @param endAmount The ending amount of the item.
- * @param startTime The starting time of the order.
- * @param endTime The end time of the order.
- * @param roundUp A boolean indicating whether the resultant amount
- * should be rounded up or down.
- *
- * @return amount The current amount.
- */
- function _locateCurrentAmount(
- uint256 startAmount,
- uint256 endAmount,
- uint256 startTime,
- uint256 endTime,
- bool roundUp
- ) internal view returns (uint256 amount) {
- // Only modify end amount if it doesn't already equal start amount.
- if (startAmount != endAmount) {
- // Declare variables to derive in the subsequent unchecked scope.
- uint256 duration;
- uint256 elapsed;
- uint256 remaining;
-
- // Skip underflow checks as startTime <= block.timestamp < endTime.
- unchecked {
- // Derive the duration for the order and place it on the stack.
- duration = endTime - startTime;
-
- // Derive time elapsed since the order started & place on stack.
- elapsed = block.timestamp - startTime;
-
- // Derive time remaining until order expires and place on stack.
- remaining = duration - elapsed;
- }
-
- // Aggregate new amounts weighted by time with rounding factor.
- uint256 totalBeforeDivision = ((startAmount * remaining) +
- (endAmount * elapsed));
-
- // Use assembly to combine operations and skip divide-by-zero check.
- assembly {
- // Multiply by iszero(iszero(totalBeforeDivision)) to ensure
- // amount is set to zero if totalBeforeDivision is zero,
- // as intermediate overflow can occur if it is zero.
- amount := mul(
- iszero(iszero(totalBeforeDivision)),
- // Subtract 1 from the numerator and add 1 to the result if
- // roundUp is true to get the proper rounding direction.
- // Division is performed with no zero check as duration
- // cannot be zero as long as startTime < endTime.
- add(
- div(sub(totalBeforeDivision, roundUp), duration),
- roundUp
- )
- )
- }
-
- // Return the current amount.
- return amount;
- }
-
- // Return the original amount as startAmount == endAmount.
- return endAmount;
- }
-
- /**
- * @dev Internal pure function to return a fraction of a given value and to
- * ensure the resultant value does not have any fractional component.
- * Note that this function assumes that zero will never be supplied as
- * the denominator parameter; invalid / undefined behavior will result
- * should a denominator of zero be provided.
- *
- * @param numerator A value indicating the portion of the order that
- * should be filled.
- * @param denominator A value indicating the total size of the order. Note
- * that this value cannot be equal to zero.
- * @param value The value for which to compute the fraction.
- *
- * @return newValue The value after applying the fraction.
- */
- function _getFraction(
- uint256 numerator,
- uint256 denominator,
- uint256 value
- ) internal pure returns (uint256 newValue) {
- // Return value early in cases where the fraction resolves to 1.
- if (numerator == denominator) {
- return value;
- }
-
- // Ensure fraction can be applied to the value with no remainder. Note
- // that the denominator cannot be zero.
- assembly {
- // Ensure new value contains no remainder via mulmod operator.
- // Credit to @hrkrshnn + @axic for proposing this optimal solution.
- if mulmod(value, numerator, denominator) {
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, InexactFraction_error_selector)
-
- // revert(abi.encodeWithSignature("InexactFraction()"))
- revert(Error_selector_offset, InexactFraction_error_length)
- }
- }
-
- // Multiply the numerator by the value and ensure no overflow occurs.
- uint256 valueTimesNumerator = value * numerator;
-
- // Divide and check for remainder. Note that denominator cannot be zero.
- assembly {
- // Perform division without zero check.
- newValue := div(valueTimesNumerator, denominator)
- }
- }
-
- /**
- * @dev Internal view function to apply a fraction to a consideration
- * or offer item.
- *
- * @param startAmount The starting amount of the item.
- * @param endAmount The ending amount of the item.
- * @param numerator A value indicating the portion of the order that
- * should be filled.
- * @param denominator A value indicating the total size of the order.
- * @param startTime The starting time of the order.
- * @param endTime The end time of the order.
- * @param roundUp A boolean indicating whether the resultant
- * amount should be rounded up or down.
- *
- * @return amount The received item to transfer with the final amount.
- */
- function _applyFraction(
- uint256 startAmount,
- uint256 endAmount,
- uint256 numerator,
- uint256 denominator,
- uint256 startTime,
- uint256 endTime,
- bool roundUp
- ) internal view returns (uint256 amount) {
- // If start amount equals end amount, apply fraction to end amount.
- if (startAmount == endAmount) {
- // Apply fraction to end amount.
- amount = _getFraction(numerator, denominator, endAmount);
- } else {
- // Otherwise, apply fraction to both and interpolated final amount.
- amount = _locateCurrentAmount(
- _getFraction(numerator, denominator, startAmount),
- _getFraction(numerator, denominator, endAmount),
- startTime,
- endTime,
- roundUp
- );
- }
- }
-}
diff --git a/contracts/lib/Assertions.sol b/contracts/lib/Assertions.sol
deleted file mode 100644
index d234f032e..000000000
--- a/contracts/lib/Assertions.sol
+++ /dev/null
@@ -1,228 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { OrderParameters } from "./ConsiderationStructs.sol";
-
-import { GettersAndDerivers } from "./GettersAndDerivers.sol";
-
-import {
- TokenTransferrerErrors
-} from "../interfaces/TokenTransferrerErrors.sol";
-
-import { CounterManager } from "./CounterManager.sol";
-
-import {
- AdditionalRecipient_size_shift,
- AddressDirtyUpperBitThreshold,
- BasicOrder_additionalRecipients_head_cdPtr,
- BasicOrder_additionalRecipients_head_ptr,
- BasicOrder_additionalRecipients_length_cdPtr,
- BasicOrder_basicOrderType_cdPtr,
- BasicOrder_basicOrderType_range,
- BasicOrder_considerationToken_cdPtr,
- BasicOrder_offerer_cdPtr,
- BasicOrder_offerToken_cdPtr,
- BasicOrder_parameters_cdPtr,
- BasicOrder_parameters_ptr,
- BasicOrder_signature_cdPtr,
- BasicOrder_signature_ptr,
- BasicOrder_zone_cdPtr
-} from "./ConsiderationConstants.sol";
-
-import {
- Error_selector_offset,
- MissingItemAmount_error_length,
- MissingItemAmount_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-import {
- _revertInvalidBasicOrderParameterEncoding,
- _revertMissingOriginalConsiderationItems
-} from "./ConsiderationErrors.sol";
-
-/**
- * @title Assertions
- * @author 0age
- * @notice Assertions contains logic for making various assertions that do not
- * fit neatly within a dedicated semantic scope.
- */
-contract Assertions is
- GettersAndDerivers,
- CounterManager,
- TokenTransferrerErrors
-{
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(
- address conduitController
- ) GettersAndDerivers(conduitController) {}
-
- /**
- * @dev Internal view function to ensure that the supplied consideration
- * array length on a given set of order parameters is not less than the
- * original consideration array length for that order and to retrieve
- * the current counter for a given order's offerer and zone and use it
- * to derive the order hash.
- *
- * @param orderParameters The parameters of the order to hash.
- *
- * @return The hash.
- */
- function _assertConsiderationLengthAndGetOrderHash(
- OrderParameters memory orderParameters
- ) internal view returns (bytes32) {
- // Ensure supplied consideration array length is not less than original.
- _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
- orderParameters.consideration.length,
- orderParameters.totalOriginalConsiderationItems
- );
-
- // Derive and return order hash using current counter for the offerer.
- return
- _deriveOrderHash(
- orderParameters,
- _getCounter(orderParameters.offerer)
- );
- }
-
- /**
- * @dev Internal pure function to ensure that the supplied consideration
- * array length for an order to be fulfilled is not less than the
- * original consideration array length for that order.
- *
- * @param suppliedConsiderationItemTotal The number of consideration items
- * supplied when fulfilling the order.
- * @param originalConsiderationItemTotal The number of consideration items
- * supplied on initial order creation.
- */
- function _assertConsiderationLengthIsNotLessThanOriginalConsiderationLength(
- uint256 suppliedConsiderationItemTotal,
- uint256 originalConsiderationItemTotal
- ) internal pure {
- // Ensure supplied consideration array length is not less than original.
- if (suppliedConsiderationItemTotal < originalConsiderationItemTotal) {
- _revertMissingOriginalConsiderationItems();
- }
- }
-
- /**
- * @dev Internal pure function to ensure that a given item amount is not
- * zero.
- *
- * @param amount The amount to check.
- */
- function _assertNonZeroAmount(uint256 amount) internal pure {
- assembly {
- if iszero(amount) {
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, MissingItemAmount_error_selector)
-
- // revert(abi.encodeWithSignature("MissingItemAmount()"))
- revert(Error_selector_offset, MissingItemAmount_error_length)
- }
- }
- }
-
- /**
- * @dev Internal pure function to validate calldata offsets for dynamic
- * types in BasicOrderParameters and other parameters. This ensures
- * that functions using the calldata object normally will be using the
- * same data as the assembly functions and that values that are bound
- * to a given range are within that range. Note that no parameters are
- * supplied as all basic order functions use the same calldata
- * encoding.
- */
- function _assertValidBasicOrderParameters() internal pure {
- // Declare a boolean designating basic order parameter offset validity.
- bool validOffsets;
-
- // Utilize assembly in order to read offset data directly from calldata.
- assembly {
- /*
- * Checks:
- * 1. Order parameters struct offset == 0x20
- * 2. Additional recipients arr offset == 0x240
- * 3. Signature offset == 0x260 + (recipients.length * 0x40)
- * 4. BasicOrderType between 0 and 23 (i.e. < 24)
- * 5. Offerer, zone, offer token, and consideration token have no
- * upper dirty bits — each argument is type(uint160).max or less
- */
- validOffsets := and(
- and(
- and(
- // Order parameters at cd 0x04 must have offset of 0x20.
- eq(
- calldataload(BasicOrder_parameters_cdPtr),
- BasicOrder_parameters_ptr
- ),
- // Additional recipients (cd 0x224) arr offset == 0x240.
- eq(
- calldataload(
- BasicOrder_additionalRecipients_head_cdPtr
- ),
- BasicOrder_additionalRecipients_head_ptr
- )
- ),
- // Signature offset == 0x260 + (recipients.length * 0x40).
- eq(
- // Load signature offset from calldata 0x244.
- calldataload(BasicOrder_signature_cdPtr),
- // Expected offset is start of recipients + len * 64.
- add(
- BasicOrder_signature_ptr,
- shl(
- // Each additional recipient has length of 0x40.
- AdditionalRecipient_size_shift,
- // Additional recipients length at cd 0x264.
- calldataload(
- BasicOrder_additionalRecipients_length_cdPtr
- )
- )
- )
- )
- ),
- and(
- // Ensure BasicOrderType parameter is less than 0x18.
- lt(
- // BasicOrderType parameter at calldata offset 0x124.
- calldataload(BasicOrder_basicOrderType_cdPtr),
- // Value should be less than 24.
- BasicOrder_basicOrderType_range
- ),
- // Ensure no dirty upper bits are present on offerer, zone,
- // offer token, or consideration token.
- lt(
- or(
- or(
- // Offerer parameter at calldata offset 0x84.
- calldataload(BasicOrder_offerer_cdPtr),
- // Zone parameter at calldata offset 0xa4.
- calldataload(BasicOrder_zone_cdPtr)
- ),
- or(
- // Offer token parameter at cd offset 0xc4.
- calldataload(BasicOrder_offerToken_cdPtr),
- // Consideration token parameter at offset 0x24.
- calldataload(
- BasicOrder_considerationToken_cdPtr
- )
- )
- ),
- AddressDirtyUpperBitThreshold
- )
- )
- )
- }
-
- // Revert with an error if basic order parameter offsets are invalid.
- if (!validOffsets) {
- _revertInvalidBasicOrderParameterEncoding();
- }
- }
-}
diff --git a/contracts/lib/BasicOrderFulfiller.sol b/contracts/lib/BasicOrderFulfiller.sol
deleted file mode 100644
index 14aa0befc..000000000
--- a/contracts/lib/BasicOrderFulfiller.sol
+++ /dev/null
@@ -1,1398 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- BasicOrderRouteType,
- ItemType,
- OrderType
-} from "./ConsiderationEnums.sol";
-
-import { BasicOrderParameters } from "./ConsiderationStructs.sol";
-
-import { OrderValidator } from "./OrderValidator.sol";
-
-import {
- _revertInsufficientNativeTokensSupplied,
- _revertInvalidMsgValue,
- _revertInvalidERC721TransferAmount,
- _revertUnusedItemParameters
-} from "./ConsiderationErrors.sol";
-
-import {
- AccumulatorDisarmed,
- AdditionalRecipient_size_shift,
- AdditionalRecipient_size,
- BasicOrder_additionalRecipients_data_cdPtr,
- BasicOrder_additionalRecipients_length_cdPtr,
- BasicOrder_basicOrderType_cdPtr,
- BasicOrder_common_params_size,
- BasicOrder_considerationAmount_cdPtr,
- BasicOrder_considerationHashesArray_ptr,
- BasicOrder_considerationIdentifier_cdPtr,
- BasicOrder_considerationItem_endAmount_ptr,
- BasicOrder_considerationItem_identifier_ptr,
- BasicOrder_considerationItem_itemType_ptr,
- BasicOrder_considerationItem_startAmount_ptr,
- BasicOrder_considerationItem_token_ptr,
- BasicOrder_considerationItem_typeHash_ptr,
- BasicOrder_considerationToken_cdPtr,
- BasicOrder_endTime_cdPtr,
- BasicOrder_fulfillerConduit_cdPtr,
- BasicOrder_offerAmount_cdPtr,
- BasicOrder_offeredItemByteMap,
- BasicOrder_offerer_cdPtr,
- BasicOrder_offererConduit_cdPtr,
- BasicOrder_offerIdentifier_cdPtr,
- BasicOrder_offerItem_endAmount_ptr,
- BasicOrder_offerItem_itemType_ptr,
- BasicOrder_offerItem_token_ptr,
- BasicOrder_offerItem_typeHash_ptr,
- BasicOrder_offerToken_cdPtr,
- BasicOrder_order_considerationHashes_ptr,
- BasicOrder_order_counter_ptr,
- BasicOrder_order_offerer_ptr,
- BasicOrder_order_offerHashes_ptr,
- BasicOrder_order_orderType_ptr,
- BasicOrder_order_startTime_ptr,
- BasicOrder_order_typeHash_ptr,
- BasicOrder_receivedItemByteMap,
- BasicOrder_startTime_cdPtr,
- BasicOrder_totalOriginalAdditionalRecipients_cdPtr,
- BasicOrder_zone_cdPtr,
- Common_token_offset,
- Conduit_execute_ConduitTransfer_length_ptr,
- Conduit_execute_ConduitTransfer_length,
- Conduit_execute_ConduitTransfer_offset_ptr,
- Conduit_execute_ConduitTransfer_ptr,
- Conduit_execute_signature,
- Conduit_execute_transferAmount_ptr,
- Conduit_execute_transferIdentifier_ptr,
- Conduit_execute_transferFrom_ptr,
- Conduit_execute_transferItemType_ptr,
- Conduit_execute_transferTo_ptr,
- Conduit_execute_transferToken_ptr,
- EIP712_ConsiderationItem_size,
- EIP712_OfferItem_size,
- EIP712_Order_size,
- FiveWords,
- FourWords,
- FreeMemoryPointerSlot,
- MaskOverLastTwentyBytes,
- OneConduitExecute_size,
- OneWord,
- OneWordShift,
- OrderFulfilled_baseOffset,
- OrderFulfilled_baseSize,
- OrderFulfilled_consideration_body_offset,
- OrderFulfilled_consideration_head_offset,
- OrderFulfilled_consideration_length_baseOffset,
- OrderFulfilled_fulfiller_offset,
- OrderFulfilled_offer_body_offset,
- OrderFulfilled_offer_head_offset,
- OrderFulfilled_offer_length_baseOffset,
- OrderFulfilled_selector,
- ReceivedItem_amount_offset,
- ReceivedItem_size,
- receivedItemsHash_ptr,
- ThreeWords,
- TwoWords,
- ZeroSlot
-} from "./ConsiderationConstants.sol";
-
-import {
- Error_selector_offset,
- InvalidBasicOrderParameterEncoding_error_length,
- InvalidBasicOrderParameterEncoding_error_selector,
- InvalidTime_error_endTime_ptr,
- InvalidTime_error_length,
- InvalidTime_error_selector,
- InvalidTime_error_startTime_ptr,
- MissingOriginalConsiderationItems_error_length,
- MissingOriginalConsiderationItems_error_selector,
- UnusedItemParameters_error_length,
- UnusedItemParameters_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @title BasicOrderFulfiller
- * @author 0age
- * @notice BasicOrderFulfiller contains functionality for fulfilling "basic"
- * orders with minimal overhead. See documentation for details on what
- * qualifies as a basic order.
- */
-contract BasicOrderFulfiller is OrderValidator {
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(address conduitController) OrderValidator(conduitController) {}
-
- /**
- * @dev Internal function to fulfill an order offering an ERC20, ERC721, or
- * ERC1155 item by supplying Ether (or other native tokens), ERC20
- * tokens, an ERC721 item, or an ERC1155 item as consideration. Six
- * permutations are supported: Native token to ERC721, Native token to
- * ERC1155, ERC20 to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and
- * ERC1155 to ERC20 (with native tokens supplied as msg.value). For an
- * order to be eligible for fulfillment via this method, it must
- * contain a single offer item (though that item may have a greater
- * amount if the item is not an ERC721). An arbitrary number of
- * "additional recipients" may also be supplied which will each receive
- * native tokens or ERC20 items from the fulfiller as consideration.
- * Refer to the documentation for a more comprehensive summary of how
- * to utilize this method and what orders are compatible with it.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer and the fulfiller must first approve
- * this contract (or their chosen conduit if indicated)
- * before any tokens can be transferred. Also note that
- * contract recipients of ERC1155 consideration items must
- * implement `onERC1155Received` in order to receive those
- * items.
- *
- * @return A boolean indicating whether the order has been fulfilled.
- */
- function _validateAndFulfillBasicOrder(
- BasicOrderParameters calldata parameters
- ) internal returns (bool) {
- // Declare enums for order type & route to extract from basicOrderType.
- BasicOrderRouteType route;
- OrderType orderType;
-
- // Declare additional recipient item type to derive from the route type.
- ItemType additionalRecipientsItemType;
-
- bytes32 orderHash;
-
- // Utilize assembly to extract the order type and the basic order route.
- assembly {
- // Read basicOrderType from calldata.
- let basicOrderType := calldataload(BasicOrder_basicOrderType_cdPtr)
-
- // Mask all but 2 least-significant bits to derive the order type.
- orderType := and(basicOrderType, 3)
-
- // Divide basicOrderType by four to derive the route.
- route := shr(2, basicOrderType)
-
- // If route > 1 additionalRecipient items are ERC20 (1) else native
- // token (0).
- additionalRecipientsItemType := gt(route, 1)
- }
-
- {
- // Declare temporary variable for enforcing payable status.
- bool correctPayableStatus;
-
- // Utilize assembly to compare the route to the callvalue.
- assembly {
- // route 0 and 1 are payable, otherwise route is not payable.
- correctPayableStatus := eq(
- additionalRecipientsItemType,
- iszero(callvalue())
- )
- }
-
- // Revert if msg.value has not been supplied as part of payable
- // routes or has been supplied as part of non-payable routes.
- if (!correctPayableStatus) {
- _revertInvalidMsgValue(msg.value);
- }
- }
-
- // Declare more arguments that will be derived from route and calldata.
- address additionalRecipientsToken;
- ItemType offeredItemType;
- bool offerTypeIsAdditionalRecipientsType;
-
- // Declare scope for received item type to manage stack pressure.
- {
- ItemType receivedItemType;
-
- // Utilize assembly to retrieve function arguments and cast types.
- assembly {
- // Check if offered item type == additional recipient item type.
- offerTypeIsAdditionalRecipientsType := gt(route, 3)
-
- // If route > 3 additionalRecipientsToken is at 0xc4 else 0x24.
- additionalRecipientsToken := calldataload(
- add(
- BasicOrder_considerationToken_cdPtr,
- mul(
- offerTypeIsAdditionalRecipientsType,
- BasicOrder_common_params_size
- )
- )
- )
-
- // If route > 2, receivedItemType is route - 2. If route is 2,
- // the receivedItemType is ERC20 (1). Otherwise, it is native
- // token (0).
- receivedItemType := byte(route, BasicOrder_receivedItemByteMap)
-
- // If route > 3, offeredItemType is ERC20 (1). Route is 2 or 3,
- // offeredItemType = route. Route is 0 or 1, it is route + 2.
- offeredItemType := byte(route, BasicOrder_offeredItemByteMap)
- }
-
- // Derive & validate order using parameters and update order status.
- orderHash = _prepareBasicFulfillmentFromCalldata(
- parameters,
- orderType,
- receivedItemType,
- additionalRecipientsItemType,
- additionalRecipientsToken,
- offeredItemType
- );
- }
-
- // Declare conduitKey argument used by transfer functions.
- bytes32 conduitKey;
-
- // Utilize assembly to derive conduit (if relevant) based on route.
- assembly {
- // use offerer conduit for routes 0-3, fulfiller conduit otherwise.
- conduitKey := calldataload(
- add(
- BasicOrder_offererConduit_cdPtr,
- shl(OneWordShift, offerTypeIsAdditionalRecipientsType)
- )
- )
- }
-
- // Transfer tokens based on the route.
- if (additionalRecipientsItemType == ItemType.NATIVE) {
- // Ensure neither consideration token nor identifier are set. Note
- // that dirty upper bits in the consideration token will still cause
- // this error to be thrown.
- assembly {
- if or(
- calldataload(BasicOrder_considerationToken_cdPtr),
- calldataload(BasicOrder_considerationIdentifier_cdPtr)
- ) {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, UnusedItemParameters_error_selector)
-
- // revert(abi.encodeWithSignature("UnusedItemParameters()"))
- revert(
- Error_selector_offset,
- UnusedItemParameters_error_length
- )
- }
- }
-
- // Transfer the ERC721 or ERC1155 item, bypassing the accumulator.
- _transferIndividual721Or1155Item(offeredItemType, conduitKey);
-
- // Transfer native to recipients, return excess to caller & wrap up.
- _transferNativeTokensAndFinalize();
- } else {
- // Initialize an accumulator array. From this point forward, no new
- // memory regions can be safely allocated until the accumulator is
- // no longer being utilized, as the accumulator operates in an
- // open-ended fashion from this memory pointer; existing memory may
- // still be accessed and modified, however.
- bytes memory accumulator = new bytes(AccumulatorDisarmed);
-
- // Choose transfer method for ERC721 or ERC1155 item based on route.
- if (route == BasicOrderRouteType.ERC20_TO_ERC721) {
- // Transfer ERC721 to caller using offerer's conduit preference.
- _transferERC721(
- parameters.offerToken,
- parameters.offerer,
- msg.sender,
- parameters.offerIdentifier,
- parameters.offerAmount,
- conduitKey,
- accumulator
- );
- } else if (route == BasicOrderRouteType.ERC20_TO_ERC1155) {
- // Transfer ERC1155 to caller with offerer's conduit preference.
- _transferERC1155(
- parameters.offerToken,
- parameters.offerer,
- msg.sender,
- parameters.offerIdentifier,
- parameters.offerAmount,
- conduitKey,
- accumulator
- );
- } else if (route == BasicOrderRouteType.ERC721_TO_ERC20) {
- // Transfer ERC721 to offerer using caller's conduit preference.
- _transferERC721(
- parameters.considerationToken,
- msg.sender,
- parameters.offerer,
- parameters.considerationIdentifier,
- parameters.considerationAmount,
- conduitKey,
- accumulator
- );
- } else {
- // route == BasicOrderRouteType.ERC1155_TO_ERC20
-
- // Transfer ERC1155 to offerer with caller's conduit preference.
- _transferERC1155(
- parameters.considerationToken,
- msg.sender,
- parameters.offerer,
- parameters.considerationIdentifier,
- parameters.considerationAmount,
- conduitKey,
- accumulator
- );
- }
-
- // Transfer ERC20 tokens to all recipients and wrap up.
- _transferERC20AndFinalize(
- offerTypeIsAdditionalRecipientsType,
- accumulator
- );
-
- // Trigger any remaining accumulated transfers via call to conduit.
- _triggerIfArmed(accumulator);
- }
-
- // Determine whether order is restricted and, if so, that it is valid.
- _assertRestrictedBasicOrderValidity(orderHash, orderType, parameters);
-
- // Clear the reentrancy guard.
- _clearReentrancyGuard();
-
- return true;
- }
-
- /**
- * @dev Internal function to prepare fulfillment of a basic order with
- * manual calldata and memory access. This calculates the order hash,
- * emits an OrderFulfilled event, and asserts basic order validity.
- * Note that calldata offsets must be validated as this function
- * accesses constant calldata pointers for dynamic types that match
- * default ABI encoding, but valid ABI encoding can use arbitrary
- * offsets. Checking that the offsets were produced by default encoding
- * will ensure that other functions using Solidity's calldata accessors
- * (which calculate pointers from the stored offsets) are reading the
- * same data as the order hash is derived from. Also note that this
- * function accesses memory directly.
- *
- * @param parameters The parameters of the basic order.
- * @param orderType The order type.
- * @param receivedItemType The item type of the initial
- * consideration item on the order.
- * @param additionalRecipientsItemType The item type of any additional
- * consideration item on the order.
- * @param additionalRecipientsToken The ERC20 token contract address (if
- * applicable) for any additional
- * consideration item on the order.
- * @param offeredItemType The item type of the offered item on
- * the order.
- * @return orderHash The calculated order hash.
- */
- function _prepareBasicFulfillmentFromCalldata(
- BasicOrderParameters calldata parameters,
- OrderType orderType,
- ItemType receivedItemType,
- ItemType additionalRecipientsItemType,
- address additionalRecipientsToken,
- ItemType offeredItemType
- ) internal returns (bytes32 orderHash) {
- // Ensure this function cannot be triggered during a reentrant call.
- _setReentrancyGuard(false); // Native tokens rejected during execution.
-
- // Verify that calldata offsets for all dynamic types were produced by
- // default encoding. This ensures that the constants used for calldata
- // pointers to dynamic types are the same as those calculated by
- // Solidity using their offsets. Also verify that the basic order type
- // is within range.
- _assertValidBasicOrderParameters();
-
- // Check for invalid time and missing original consideration items.
- // Utilize assembly so that constant calldata pointers can be applied.
- assembly {
- // Ensure current timestamp is between order start time & end time.
- if or(
- gt(calldataload(BasicOrder_startTime_cdPtr), timestamp()),
- iszero(gt(calldataload(BasicOrder_endTime_cdPtr), timestamp()))
- ) {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidTime_error_selector)
-
- // Store arguments.
- mstore(
- InvalidTime_error_startTime_ptr,
- calldataload(BasicOrder_startTime_cdPtr)
- )
- mstore(
- InvalidTime_error_endTime_ptr,
- calldataload(BasicOrder_endTime_cdPtr)
- )
-
- // revert(abi.encodeWithSignature(
- // "InvalidTime(uint256,uint256)",
- // startTime,
- // endTime
- // ))
- revert(Error_selector_offset, InvalidTime_error_length)
- }
-
- // Ensure consideration array length isn't less than total original.
- if lt(
- calldataload(BasicOrder_additionalRecipients_length_cdPtr),
- calldataload(BasicOrder_totalOriginalAdditionalRecipients_cdPtr)
- ) {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, MissingOriginalConsiderationItems_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "MissingOriginalConsiderationItems()"
- // ))
- revert(
- Error_selector_offset,
- MissingOriginalConsiderationItems_error_length
- )
- }
- }
-
- {
- /**
- * First, handle consideration items. Memory Layout:
- * 0x60: final hash of the array of consideration item hashes
- * 0x80-0x160: reused space for EIP712 hashing of each item
- * - 0x80: ConsiderationItem EIP-712 typehash (constant)
- * - 0xa0: itemType
- * - 0xc0: token
- * - 0xe0: identifier
- * - 0x100: startAmount
- * - 0x120: endAmount
- * - 0x140: recipient
- * 0x160-END_ARR: array of consideration item hashes
- * - 0x160: primary consideration item EIP712 hash
- * - 0x180-END_ARR: additional recipient item EIP712 hashes
- * END_ARR: beginning of data for OrderFulfilled event
- * - END_ARR + 0x120: length of ReceivedItem array
- * - END_ARR + 0x140: beginning of data for first ReceivedItem
- * (Note: END_ARR = 0x180 + RECIPIENTS_LENGTH * 0x20)
- */
-
- // Load consideration item typehash from runtime and place on stack.
- bytes32 typeHash = _CONSIDERATION_ITEM_TYPEHASH;
-
- // Utilize assembly to enable reuse of memory regions and use
- // constant pointers when possible.
- assembly {
- /*
- * 1. Calculate the EIP712 ConsiderationItem hash for the
- * primary consideration item of the basic order.
- */
-
- // Write ConsiderationItem type hash and item type to memory.
- mstore(BasicOrder_considerationItem_typeHash_ptr, typeHash)
- mstore(
- BasicOrder_considerationItem_itemType_ptr,
- receivedItemType
- )
-
- // Copy calldata region with (token, identifier, amount) from
- // BasicOrderParameters to ConsiderationItem. The
- // considerationAmount is written to startAmount and endAmount
- // as basic orders do not have dynamic amounts.
- calldatacopy(
- BasicOrder_considerationItem_token_ptr,
- BasicOrder_considerationToken_cdPtr,
- ThreeWords
- )
-
- // Copy calldata region with considerationAmount and offerer
- // from BasicOrderParameters to endAmount and recipient in
- // ConsiderationItem.
- calldatacopy(
- BasicOrder_considerationItem_endAmount_ptr,
- BasicOrder_considerationAmount_cdPtr,
- TwoWords
- )
-
- // Calculate EIP712 ConsiderationItem hash and store it in the
- // array of EIP712 consideration hashes.
- mstore(
- BasicOrder_considerationHashesArray_ptr,
- keccak256(
- BasicOrder_considerationItem_typeHash_ptr,
- EIP712_ConsiderationItem_size
- )
- )
-
- /*
- * 2. Write a ReceivedItem struct for the primary consideration
- * item to the consideration array in OrderFulfilled.
- */
-
- // Get the length of the additional recipients array.
- let totalAdditionalRecipients := calldataload(
- BasicOrder_additionalRecipients_length_cdPtr
- )
-
- // Calculate pointer to length of OrderFulfilled consideration
- // array.
- let eventConsiderationArrPtr := add(
- OrderFulfilled_consideration_length_baseOffset,
- shl(OneWordShift, totalAdditionalRecipients)
- )
-
- // Set the length of the consideration array to the number of
- // additional recipients, plus one for the primary consideration
- // item.
- mstore(
- eventConsiderationArrPtr,
- add(totalAdditionalRecipients, 1)
- )
-
- // Overwrite the consideration array pointer so it points to the
- // body of the first element
- eventConsiderationArrPtr := add(
- eventConsiderationArrPtr,
- OneWord
- )
-
- // Set itemType at start of the ReceivedItem memory region.
- mstore(eventConsiderationArrPtr, receivedItemType)
-
- // Copy calldata region (token, identifier, amount & recipient)
- // from BasicOrderParameters to ReceivedItem memory.
- calldatacopy(
- add(eventConsiderationArrPtr, Common_token_offset),
- BasicOrder_considerationToken_cdPtr,
- FourWords
- )
-
- /*
- * 3. Calculate EIP712 ConsiderationItem hashes for original
- * additional recipients and add a ReceivedItem for each to the
- * consideration array in the OrderFulfilled event. The original
- * additional recipients are all the consideration items signed
- * by the offerer aside from the primary consideration items of
- * the order. Uses memory region from 0x80-0x160 as a buffer for
- * calculating EIP712 ConsiderationItem hashes.
- */
-
- // Put pointer to consideration hashes array on the stack.
- // This will be updated as each additional recipient is hashed
- let
- considerationHashesPtr
- := BasicOrder_considerationHashesArray_ptr
-
- // Write item type, token, & identifier for additional recipient
- // to memory region for hashing EIP712 ConsiderationItem; these
- // values will be reused for each recipient.
- mstore(
- BasicOrder_considerationItem_itemType_ptr,
- additionalRecipientsItemType
- )
- mstore(
- BasicOrder_considerationItem_token_ptr,
- additionalRecipientsToken
- )
- mstore(BasicOrder_considerationItem_identifier_ptr, 0)
-
- // Declare a stack variable where all additional recipients will
- // be combined to guard against providing dirty upper bits.
- let combinedAdditionalRecipients
-
- // Read length of the additionalRecipients array from calldata
- // and iterate.
- totalAdditionalRecipients := calldataload(
- BasicOrder_totalOriginalAdditionalRecipients_cdPtr
- )
- let i := 0
- for {} lt(i, totalAdditionalRecipients) {
- i := add(i, 1)
- } {
- /*
- * Calculate EIP712 ConsiderationItem hash for recipient.
- */
-
- // Retrieve calldata pointer for additional recipient.
- let additionalRecipientCdPtr := add(
- BasicOrder_additionalRecipients_data_cdPtr,
- mul(AdditionalRecipient_size, i)
- )
-
- // Copy startAmount from calldata to the ConsiderationItem
- // struct.
- calldatacopy(
- BasicOrder_considerationItem_startAmount_ptr,
- additionalRecipientCdPtr,
- OneWord
- )
-
- // Copy endAmount and recipient from calldata to the
- // ConsiderationItem struct.
- calldatacopy(
- BasicOrder_considerationItem_endAmount_ptr,
- additionalRecipientCdPtr,
- AdditionalRecipient_size
- )
-
- // Include the recipient as part of combined recipients.
- combinedAdditionalRecipients := or(
- combinedAdditionalRecipients,
- calldataload(add(additionalRecipientCdPtr, OneWord))
- )
-
- // Add 1 word to the pointer as part of each loop to reduce
- // operations needed to get local offset into the array.
- considerationHashesPtr := add(
- considerationHashesPtr,
- OneWord
- )
-
- // Calculate EIP712 ConsiderationItem hash and store it in
- // the array of consideration hashes.
- mstore(
- considerationHashesPtr,
- keccak256(
- BasicOrder_considerationItem_typeHash_ptr,
- EIP712_ConsiderationItem_size
- )
- )
-
- /*
- * Write ReceivedItem to OrderFulfilled data.
- */
-
- // At this point, eventConsiderationArrPtr points to the
- // beginning of the ReceivedItem struct of the previous
- // element in the array. Increase it by the size of the
- // struct to arrive at the pointer for the current element.
- eventConsiderationArrPtr := add(
- eventConsiderationArrPtr,
- ReceivedItem_size
- )
-
- // Write itemType to the ReceivedItem struct.
- mstore(
- eventConsiderationArrPtr,
- additionalRecipientsItemType
- )
-
- // Write token to the next word of the ReceivedItem struct.
- mstore(
- add(eventConsiderationArrPtr, OneWord),
- additionalRecipientsToken
- )
-
- // Copy endAmount & recipient words to ReceivedItem struct.
- calldatacopy(
- add(
- eventConsiderationArrPtr,
- ReceivedItem_amount_offset
- ),
- additionalRecipientCdPtr,
- TwoWords
- )
- }
-
- /*
- * 4. Hash packed array of ConsiderationItem EIP712 hashes:
- * `keccak256(abi.encodePacked(receivedItemHashes))`
- * Note that it is set at 0x60 — all other memory begins at
- * 0x80. 0x60 is the "zero slot" and will be restored at the end
- * of the assembly section and before required by the compiler.
- */
- mstore(
- receivedItemsHash_ptr,
- keccak256(
- BasicOrder_considerationHashesArray_ptr,
- shl(OneWordShift, add(totalAdditionalRecipients, 1))
- )
- )
-
- /*
- * 5. Add a ReceivedItem for each tip to the consideration array
- * in the OrderFulfilled event. The tips are all the
- * consideration items that were not signed by the offerer and
- * were provided by the fulfiller.
- */
-
- // Overwrite length to length of the additionalRecipients array.
- totalAdditionalRecipients := calldataload(
- BasicOrder_additionalRecipients_length_cdPtr
- )
-
- for {} lt(i, totalAdditionalRecipients) {
- i := add(i, 1)
- } {
- // Retrieve calldata pointer for additional recipient.
- let additionalRecipientCdPtr := add(
- BasicOrder_additionalRecipients_data_cdPtr,
- mul(AdditionalRecipient_size, i)
- )
-
- // At this point, eventConsiderationArrPtr points to the
- // beginning of the ReceivedItem struct of the previous
- // element in the array. Increase it by the size of the
- // struct to arrive at the pointer for the current element.
- eventConsiderationArrPtr := add(
- eventConsiderationArrPtr,
- ReceivedItem_size
- )
-
- // Write itemType to the ReceivedItem struct.
- mstore(
- eventConsiderationArrPtr,
- additionalRecipientsItemType
- )
-
- // Write token to the next word of the ReceivedItem struct.
- mstore(
- add(eventConsiderationArrPtr, OneWord),
- additionalRecipientsToken
- )
-
- // Copy endAmount & recipient words to ReceivedItem struct.
- calldatacopy(
- add(
- eventConsiderationArrPtr,
- ReceivedItem_amount_offset
- ),
- additionalRecipientCdPtr,
- TwoWords
- )
-
- // Include the recipient as part of combined recipients.
- combinedAdditionalRecipients := or(
- combinedAdditionalRecipients,
- calldataload(add(additionalRecipientCdPtr, OneWord))
- )
- }
-
- // Ensure no dirty upper bits on combined additional recipients.
- if gt(combinedAdditionalRecipients, MaskOverLastTwentyBytes) {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidBasicOrderParameterEncoding_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "InvalidBasicOrderParameterEncoding()"
- // ))
- revert(
- Error_selector_offset,
- InvalidBasicOrderParameterEncoding_error_length
- )
- }
- }
- }
-
- {
- /**
- * Next, handle offered items. Memory Layout:
- * EIP712 data for OfferItem
- * - 0x80: OfferItem EIP-712 typehash (constant)
- * - 0xa0: itemType
- * - 0xc0: token
- * - 0xe0: identifier (reused for offeredItemsHash)
- * - 0x100: startAmount
- * - 0x120: endAmount
- */
-
- // Place offer item typehash on the stack.
- bytes32 typeHash = _OFFER_ITEM_TYPEHASH;
-
- // Utilize assembly to enable reuse of memory regions when possible.
- assembly {
- /*
- * 1. Calculate OfferItem EIP712 hash
- */
-
- // Write the OfferItem typeHash to memory.
- mstore(BasicOrder_offerItem_typeHash_ptr, typeHash)
-
- // Write the OfferItem item type to memory.
- mstore(BasicOrder_offerItem_itemType_ptr, offeredItemType)
-
- // Copy calldata region with (offerToken, offerIdentifier,
- // offerAmount) from OrderParameters to (token, identifier,
- // startAmount) in OfferItem struct. The offerAmount is written
- // to startAmount and endAmount as basic orders do not have
- // dynamic amounts.
- calldatacopy(
- BasicOrder_offerItem_token_ptr,
- BasicOrder_offerToken_cdPtr,
- ThreeWords
- )
-
- // Copy offerAmount from calldata to endAmount in OfferItem
- // struct.
- calldatacopy(
- BasicOrder_offerItem_endAmount_ptr,
- BasicOrder_offerAmount_cdPtr,
- OneWord
- )
-
- // Compute EIP712 OfferItem hash, write result to scratch space:
- // `keccak256(abi.encode(offeredItem))`
- mstore(
- 0,
- keccak256(
- BasicOrder_offerItem_typeHash_ptr,
- EIP712_OfferItem_size
- )
- )
-
- /*
- * 2. Calculate hash of array of EIP712 hashes and write the
- * result to the corresponding OfferItem struct:
- * `keccak256(abi.encodePacked(offerItemHashes))`
- */
- mstore(BasicOrder_order_offerHashes_ptr, keccak256(0, OneWord))
-
- /*
- * 3. Write SpentItem to offer array in OrderFulfilled event.
- */
- let eventConsiderationArrPtr := add(
- OrderFulfilled_offer_length_baseOffset,
- shl(
- OneWordShift,
- calldataload(
- BasicOrder_additionalRecipients_length_cdPtr
- )
- )
- )
-
- // Set a length of 1 for the offer array.
- mstore(eventConsiderationArrPtr, 1)
-
- // Write itemType to the SpentItem struct.
- mstore(add(eventConsiderationArrPtr, OneWord), offeredItemType)
-
- // Copy calldata region with (offerToken, offerIdentifier,
- // offerAmount) from OrderParameters to (token, identifier,
- // amount) in SpentItem struct.
- calldatacopy(
- add(eventConsiderationArrPtr, AdditionalRecipient_size),
- BasicOrder_offerToken_cdPtr,
- ThreeWords
- )
- }
- }
-
- {
- /**
- * Once consideration items and offer items have been handled,
- * derive the final order hash. Memory Layout:
- * 0x80-0x1c0: EIP712 data for order
- * - 0x80: Order EIP-712 typehash (constant)
- * - 0xa0: orderParameters.offerer
- * - 0xc0: orderParameters.zone
- * - 0xe0: keccak256(abi.encodePacked(offerHashes))
- * - 0x100: keccak256(abi.encodePacked(considerationHashes))
- * - 0x120: orderParameters.basicOrderType (% 4 = orderType)
- * - 0x140: orderParameters.startTime
- * - 0x160: orderParameters.endTime
- * - 0x180: orderParameters.zoneHash
- * - 0x1a0: orderParameters.salt
- * - 0x1c0: orderParameters.conduitKey
- * - 0x1e0: _counters[orderParameters.offerer] (from storage)
- */
-
- // Read the offerer from calldata and place on the stack.
- address offerer;
- assembly {
- offerer := calldataload(BasicOrder_offerer_cdPtr)
- }
-
- // Read offerer's current counter from storage and place on stack.
- uint256 counter = _getCounter(offerer);
-
- // Load order typehash from runtime code and place on stack.
- bytes32 typeHash = _ORDER_TYPEHASH;
-
- assembly {
- // Set the OrderItem typeHash in memory.
- mstore(BasicOrder_order_typeHash_ptr, typeHash)
-
- // Copy offerer and zone from OrderParameters in calldata to the
- // Order struct.
- calldatacopy(
- BasicOrder_order_offerer_ptr,
- BasicOrder_offerer_cdPtr,
- TwoWords
- )
-
- // Copy receivedItemsHash from zero slot to the Order struct.
- mstore(
- BasicOrder_order_considerationHashes_ptr,
- mload(receivedItemsHash_ptr)
- )
-
- // Write the supplied orderType to the Order struct.
- mstore(BasicOrder_order_orderType_ptr, orderType)
-
- // Copy startTime, endTime, zoneHash, salt & conduit from
- // calldata to the Order struct.
- calldatacopy(
- BasicOrder_order_startTime_ptr,
- BasicOrder_startTime_cdPtr,
- FiveWords
- )
-
- // Write offerer's counter, retrieved from storage, to struct.
- mstore(BasicOrder_order_counter_ptr, counter)
-
- // Compute the EIP712 Order hash.
- orderHash := keccak256(
- BasicOrder_order_typeHash_ptr,
- EIP712_Order_size
- )
- }
- }
-
- assembly {
- /**
- * After the order hash has been derived, emit OrderFulfilled event:
- * event OrderFulfilled(
- * bytes32 orderHash,
- * address indexed offerer,
- * address indexed zone,
- * address fulfiller,
- * SpentItem[] offer,
- * > (itemType, token, id, amount)
- * ReceivedItem[] consideration
- * > (itemType, token, id, amount, recipient)
- * )
- * topic0 - OrderFulfilled event signature
- * topic1 - offerer
- * topic2 - zone
- * data:
- * - 0x00: orderHash
- * - 0x20: fulfiller
- * - 0x40: offer arr ptr (0x80)
- * - 0x60: consideration arr ptr (0x120)
- * - 0x80: offer arr len (1)
- * - 0xa0: offer.itemType
- * - 0xc0: offer.token
- * - 0xe0: offer.identifier
- * - 0x100: offer.amount
- * - 0x120: 1 + recipients.length
- * - 0x140: recipient 0
- */
-
- // Derive pointer to start of OrderFulfilled event data.
- let eventDataPtr := add(
- OrderFulfilled_baseOffset,
- shl(
- OneWordShift,
- calldataload(BasicOrder_additionalRecipients_length_cdPtr)
- )
- )
-
- // Write the order hash to the head of the event's data region.
- mstore(eventDataPtr, orderHash)
-
- // Write the fulfiller (i.e. the caller) next for receiver argument.
- mstore(add(eventDataPtr, OrderFulfilled_fulfiller_offset), caller())
-
- // Write the SpentItem and ReceivedItem array offsets (constants).
- mstore(
- // SpentItem array offset
- add(eventDataPtr, OrderFulfilled_offer_head_offset),
- OrderFulfilled_offer_body_offset
- )
- mstore(
- // ReceivedItem array offset
- add(eventDataPtr, OrderFulfilled_consideration_head_offset),
- OrderFulfilled_consideration_body_offset
- )
-
- // Derive total data size including SpentItem and ReceivedItem data.
- // SpentItem portion is already included in the baseSize constant,
- // as there can only be one element in the array.
- let dataSize := add(
- OrderFulfilled_baseSize,
- mul(
- calldataload(BasicOrder_additionalRecipients_length_cdPtr),
- ReceivedItem_size
- )
- )
-
- // Emit OrderFulfilled log with three topics (the event signature
- // as well as the two indexed arguments, the offerer and the zone).
- log3(
- // Supply the pointer for event data in memory.
- eventDataPtr,
- // Supply the size of event data in memory.
- dataSize,
- // Supply the OrderFulfilled event signature.
- OrderFulfilled_selector,
- // Supply the first topic (the offerer).
- calldataload(BasicOrder_offerer_cdPtr),
- // Supply the second topic (the zone).
- calldataload(BasicOrder_zone_cdPtr)
- )
-
- // Restore the zero slot.
- mstore(ZeroSlot, 0)
-
- // Update the free memory pointer so that event data is persisted.
- mstore(FreeMemoryPointerSlot, add(eventDataPtr, dataSize))
- }
-
- // Verify and update the status of the derived order.
- _validateBasicOrderAndUpdateStatus(orderHash, parameters.signature);
-
- // Return the derived order hash.
- return orderHash;
- }
-
- /**
- * @dev Internal function to transfer an individual ERC721 or ERC1155 item
- * from a given originator to a given recipient. The accumulator will
- * be bypassed, meaning that this function should be utilized in cases
- * where multiple item transfers can be accumulated into a single
- * conduit call. Sufficient approvals must be set, either on the
- * respective conduit or on this contract. Note that this function may
- * only be safely called as part of basic orders, as it assumes a
- * specific calldata encoding structure that must first be validated.
- *
- * @param itemType The type of item to transfer, either ERC721 or ERC1155.
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- */
- function _transferIndividual721Or1155Item(
- ItemType itemType,
- bytes32 conduitKey
- ) internal {
- // Retrieve token, from, identifier, and amount from calldata using
- // fixed calldata offsets based on strict basic parameter encoding.
- address token;
- address from;
- uint256 identifier;
- uint256 amount;
- assembly {
- token := calldataload(BasicOrder_offerToken_cdPtr)
- from := calldataload(BasicOrder_offerer_cdPtr)
- identifier := calldataload(BasicOrder_offerIdentifier_cdPtr)
- amount := calldataload(BasicOrder_offerAmount_cdPtr)
- }
-
- // Determine if the transfer is to be performed via a conduit.
- if (conduitKey != bytes32(0)) {
- // Use free memory pointer as calldata offset for the conduit call.
- uint256 callDataOffset;
-
- // Utilize assembly to place each argument in free memory.
- assembly {
- // Retrieve the free memory pointer and use it as the offset.
- callDataOffset := mload(FreeMemoryPointerSlot)
-
- // Write ConduitInterface.execute.selector to memory.
- mstore(callDataOffset, Conduit_execute_signature)
-
- // Write the offset to the ConduitTransfer array in memory.
- mstore(
- add(
- callDataOffset,
- Conduit_execute_ConduitTransfer_offset_ptr
- ),
- Conduit_execute_ConduitTransfer_ptr
- )
-
- // Write the length of the ConduitTransfer array to memory.
- mstore(
- add(
- callDataOffset,
- Conduit_execute_ConduitTransfer_length_ptr
- ),
- Conduit_execute_ConduitTransfer_length
- )
-
- // Write the item type to memory.
- mstore(
- add(callDataOffset, Conduit_execute_transferItemType_ptr),
- itemType
- )
-
- // Write the token to memory.
- mstore(
- add(callDataOffset, Conduit_execute_transferToken_ptr),
- token
- )
-
- // Write the transfer source to memory.
- mstore(
- add(callDataOffset, Conduit_execute_transferFrom_ptr),
- from
- )
-
- // Write the transfer recipient (the caller) to memory.
- mstore(
- add(callDataOffset, Conduit_execute_transferTo_ptr),
- caller()
- )
-
- // Write the token identifier to memory.
- mstore(
- add(callDataOffset, Conduit_execute_transferIdentifier_ptr),
- identifier
- )
-
- // Write the transfer amount to memory.
- mstore(
- add(callDataOffset, Conduit_execute_transferAmount_ptr),
- amount
- )
- }
-
- // Perform the call to the conduit.
- _callConduitUsingOffsets(
- conduitKey,
- callDataOffset,
- OneConduitExecute_size
- );
- } else {
- // Otherwise, determine whether it is an ERC721 or ERC1155 item.
- if (itemType == ItemType.ERC721) {
- // Ensure that exactly one 721 item is being transferred.
- if (amount != 1) {
- _revertInvalidERC721TransferAmount(amount);
- }
-
- // Perform transfer to caller via the token contract directly.
- _performERC721Transfer(token, from, msg.sender, identifier);
- } else {
- // Perform transfer to caller via the token contract directly.
- _performERC1155Transfer(
- token,
- from,
- msg.sender,
- identifier,
- amount
- );
- }
- }
- }
-
- /**
- * @dev Internal function to transfer Ether (or other native tokens) to a
- * given recipient as part of basic order fulfillment. Note that
- * conduits are not utilized for native tokens as the transferred
- * amount must be provided as msg.value. Also note that this function
- * may only be safely called as part of basic orders, as it assumes a
- * specific calldata encoding structure that must first be validated.
- */
- function _transferNativeTokensAndFinalize() internal {
- // Put native token value supplied by the caller on the stack.
- uint256 nativeTokensRemaining = msg.value;
-
- // Retrieve consideration amount, offerer, and total size of additional
- // recipients data from calldata using fixed offsets and place on stack.
- uint256 amount;
- address payable to;
- uint256 totalAdditionalRecipientsDataSize;
- assembly {
- amount := calldataload(BasicOrder_considerationAmount_cdPtr)
- to := calldataload(BasicOrder_offerer_cdPtr)
- totalAdditionalRecipientsDataSize := shl(
- AdditionalRecipient_size_shift,
- calldataload(BasicOrder_additionalRecipients_length_cdPtr)
- )
- }
-
- uint256 additionalRecipientAmount;
- address payable recipient;
-
- // Skip overflow check as for loop is indexed starting at zero.
- unchecked {
- // Iterate over additional recipient data by two-word element.
- for (
- uint256 i = 0;
- i < totalAdditionalRecipientsDataSize;
- i += AdditionalRecipient_size
- ) {
- assembly {
- // Retrieve calldata pointer for additional recipient.
- let additionalRecipientCdPtr := add(
- BasicOrder_additionalRecipients_data_cdPtr,
- i
- )
-
- additionalRecipientAmount := calldataload(
- additionalRecipientCdPtr
- )
- recipient := calldataload(
- add(OneWord, additionalRecipientCdPtr)
- )
- }
-
- // Ensure that sufficient native tokens are available.
- if (additionalRecipientAmount > nativeTokensRemaining) {
- _revertInsufficientNativeTokensSupplied();
- }
-
- // Reduce native token value available. Skip underflow check as
- // subtracted value is confirmed above as less than remaining.
- nativeTokensRemaining -= additionalRecipientAmount;
-
- // Transfer native tokens to the additional recipient.
- _transferNativeTokens(recipient, additionalRecipientAmount);
- }
- }
-
- // Ensure that sufficient native tokens are still available.
- if (amount > nativeTokensRemaining) {
- _revertInsufficientNativeTokensSupplied();
- }
-
- // Transfer native tokens to the offerer.
- _transferNativeTokens(to, amount);
-
- // If any native tokens remain after transfers, return to the caller.
- if (nativeTokensRemaining > amount) {
- // Skip underflow check as nativeTokensRemaining > amount.
- unchecked {
- // Transfer remaining native tokens to the caller.
- _transferNativeTokens(
- payable(msg.sender),
- nativeTokensRemaining - amount
- );
- }
- }
- }
-
- /**
- * @dev Internal function to transfer ERC20 tokens to a given recipient as
- * part of basic order fulfillment. Note that this function may only be
- * safely called as part of basic orders, as it assumes a specific
- * calldata encoding structure that must first be validated. Also note
- * that basic order parameters are retrieved using fixed offsets, this
- * requires that strict basic order encoding has already been verified.
- *
- * @param fromOfferer A boolean indicating whether to decrement amount from
- * the offered amount.
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- */
- function _transferERC20AndFinalize(
- bool fromOfferer,
- bytes memory accumulator
- ) internal {
- // Declare from and to variables determined by fromOfferer value.
- address from;
- address to;
-
- // Declare token and amount variables determined by fromOfferer value.
- address token;
- uint256 amount;
-
- // Declare and check identifier variable within an isolated scope.
- {
- // Declare identifier variable determined by fromOfferer value.
- uint256 identifier;
-
- // Set ERC20 token transfer variables based on fromOfferer boolean.
- if (fromOfferer) {
- // Use offerer as from value, msg.sender as to value, and offer
- // token, identifier, & amount values if token is from offerer.
- assembly {
- from := calldataload(BasicOrder_offerer_cdPtr)
- to := caller()
- token := calldataload(BasicOrder_offerToken_cdPtr)
- identifier := calldataload(BasicOrder_offerIdentifier_cdPtr)
- amount := calldataload(BasicOrder_offerAmount_cdPtr)
- }
- } else {
- // Otherwise, use msg.sender as from value, offerer as to value,
- // and consideration token, identifier, and amount values.
- assembly {
- from := caller()
- to := calldataload(BasicOrder_offerer_cdPtr)
- token := calldataload(BasicOrder_considerationToken_cdPtr)
- identifier := calldataload(
- BasicOrder_considerationIdentifier_cdPtr
- )
- amount := calldataload(BasicOrder_considerationAmount_cdPtr)
- }
- }
-
- // Ensure that no identifier is supplied.
- if (identifier != 0) {
- _revertUnusedItemParameters();
- }
- }
-
- // Determine the appropriate conduit to utilize.
- bytes32 conduitKey;
-
- // Utilize assembly to derive conduit (if relevant) based on route.
- assembly {
- // Use offerer conduit if fromOfferer, fulfiller conduit otherwise.
- conduitKey := calldataload(
- sub(
- BasicOrder_fulfillerConduit_cdPtr,
- shl(OneWordShift, fromOfferer)
- )
- )
- }
-
- // Retrieve total size of additional recipients data and place on stack.
- uint256 totalAdditionalRecipientsDataSize;
- assembly {
- totalAdditionalRecipientsDataSize := shl(
- AdditionalRecipient_size_shift,
- calldataload(BasicOrder_additionalRecipients_length_cdPtr)
- )
- }
-
- uint256 additionalRecipientAmount;
- address recipient;
-
- // Iterate over each additional recipient.
- for (uint256 i = 0; i < totalAdditionalRecipientsDataSize; ) {
- assembly {
- // Retrieve calldata pointer for additional recipient.
- let additionalRecipientCdPtr := add(
- BasicOrder_additionalRecipients_data_cdPtr,
- i
- )
-
- additionalRecipientAmount := calldataload(
- additionalRecipientCdPtr
- )
- recipient := calldataload(
- add(OneWord, additionalRecipientCdPtr)
- )
- }
-
- // Decrement the amount to transfer to fulfiller if indicated.
- if (fromOfferer) {
- amount -= additionalRecipientAmount;
- }
-
- // Transfer ERC20 tokens to additional recipient given approval.
- _transferERC20(
- token,
- from,
- recipient,
- additionalRecipientAmount,
- conduitKey,
- accumulator
- );
-
- // Skip overflow check as for loop is indexed starting at zero.
- unchecked {
- i += AdditionalRecipient_size;
- }
- }
-
- // Transfer ERC20 token amount (from account must have proper approval).
- _transferERC20(token, from, to, amount, conduitKey, accumulator);
- }
-}
diff --git a/contracts/lib/Consideration.sol b/contracts/lib/Consideration.sol
deleted file mode 100644
index 51b87f8f4..000000000
--- a/contracts/lib/Consideration.sol
+++ /dev/null
@@ -1,816 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- ConsiderationInterface
-} from "../interfaces/ConsiderationInterface.sol";
-
-import {
- AdvancedOrder,
- BasicOrderParameters,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- Order,
- OrderComponents
-} from "./ConsiderationStructs.sol";
-
-import { OrderCombiner } from "./OrderCombiner.sol";
-
-import {
- CalldataStart,
- CalldataPointer
-} from "../helpers/PointerLibraries.sol";
-
-import {
- Offset_fulfillAdvancedOrder_criteriaResolvers,
- Offset_fulfillAvailableAdvancedOrders_cnsdrationFlflmnts,
- Offset_fulfillAvailableAdvancedOrders_criteriaResolvers,
- Offset_fulfillAvailableAdvancedOrders_offerFulfillments,
- Offset_fulfillAvailableOrders_considerationFulfillments,
- Offset_fulfillAvailableOrders_offerFulfillments,
- Offset_matchAdvancedOrders_criteriaResolvers,
- Offset_matchAdvancedOrders_fulfillments,
- Offset_matchOrders_fulfillments,
- OrderParameters_counter_offset
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title Consideration
- * @author 0age (0age.eth)
- * @custom:coauthor d1ll0n (d1ll0n.eth)
- * @custom:coauthor transmissions11 (t11s.eth)
- * @custom:coauthor James Wenzel (emo.eth)
- * @custom:version 1.5
- * @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155
- * marketplace that provides lightweight methods for common routes as
- * well as more flexible methods for composing advanced orders or groups
- * of orders. Each order contains an arbitrary number of items that may
- * be spent (the "offer") along with an arbitrary number of items that
- * must be received back by the indicated recipients (the
- * "consideration").
- */
-contract Consideration is ConsiderationInterface, OrderCombiner {
- /**
- * @notice Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(address conduitController) OrderCombiner(conduitController) {}
-
- /**
- * @notice Accept native token transfers during execution that may then be
- * used to facilitate native token transfers, where any tokens that
- * remain will be transferred to the caller. Native tokens are only
- * acceptable mid-fulfillment (and not during basic fulfillment).
- */
- receive() external payable {
- // Ensure the reentrancy guard is currently set to accept native tokens.
- _assertAcceptingNativeTokens();
- }
-
- /**
- * @notice Fulfill an order offering an ERC20, ERC721, or ERC1155 item by
- * supplying Ether (or other native tokens), ERC20 tokens, an ERC721
- * item, or an ERC1155 item as consideration. Six permutations are
- * supported: Native token to ERC721, Native token to ERC1155, ERC20
- * to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and ERC1155 to
- * ERC20 (with native tokens supplied as msg.value). For an order to
- * be eligible for fulfillment via this method, it must contain a
- * single offer item (though that item may have a greater amount if
- * the item is not an ERC721). An arbitrary number of "additional
- * recipients" may also be supplied which will each receive native
- * tokens or ERC20 items from the fulfiller as consideration. Refer
- * to the documentation for a more comprehensive summary of how to
- * utilize this method and what orders are compatible with it.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer and the fulfiller must first approve
- * this contract (or their chosen conduit if indicated)
- * before any tokens can be transferred. Also note that
- * contract recipients of ERC1155 consideration items must
- * implement `onERC1155Received` to receive those items.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillBasicOrder(
- BasicOrderParameters calldata parameters
- ) external payable override returns (bool fulfilled) {
- // Validate and fulfill the basic order.
- fulfilled = _validateAndFulfillBasicOrder(parameters);
- }
-
- /**
- * @notice Fulfill an order offering an ERC20, ERC721, or ERC1155 item by
- * supplying Ether (or other native tokens), ERC20 tokens, an ERC721
- * item, or an ERC1155 item as consideration. Six permutations are
- * supported: Native token to ERC721, Native token to ERC1155, ERC20
- * to ERC721, ERC20 to ERC1155, ERC721 to ERC20, and ERC1155 to
- * ERC20 (with native tokens supplied as msg.value). For an order to
- * be eligible for fulfillment via this method, it must contain a
- * single offer item (though that item may have a greater amount if
- * the item is not an ERC721). An arbitrary number of "additional
- * recipients" may also be supplied which will each receive native
- * tokens or ERC20 items from the fulfiller as consideration. Refer
- * to the documentation for a more comprehensive summary of how to
- * utilize this method and what orders are compatible with it. Note
- * that this function costs less gas than `fulfillBasicOrder` due to
- * the zero bytes in the function selector (0x00000000) which also
- * results in earlier function dispatch.
- *
- * @param parameters Additional information on the fulfilled order. Note
- * that the offerer and the fulfiller must first approve
- * this contract (or their chosen conduit if indicated)
- * before any tokens can be transferred. Also note that
- * contract recipients of ERC1155 consideration items must
- * implement `onERC1155Received` to receive those items.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillBasicOrder_efficient_6GL6yc(
- BasicOrderParameters calldata parameters
- ) external payable override returns (bool fulfilled) {
- // Validate and fulfill the basic order.
- fulfilled = _validateAndFulfillBasicOrder(parameters);
- }
-
- /**
- * @notice Fulfill an order with an arbitrary number of items for offer and
- * consideration. Note that this function does not support
- * criteria-based orders or partial filling of orders (though
- * filling the remainder of a partially-filled order is supported).
- *
- * @custom:param order The order to fulfill. Note that both the
- * offerer and the fulfiller must first approve
- * this contract (or the corresponding conduit if
- * indicated) to transfer any relevant tokens on
- * their behalf and that contracts must implement
- * `onERC1155Received` to receive ERC1155 tokens
- * as consideration.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used (and direct approvals set on
- * this contract).
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillOrder(
- /**
- * @custom:name order
- */
- Order calldata,
- bytes32 fulfillerConduitKey
- ) external payable override returns (bool fulfilled) {
- // Convert order to "advanced" order, then validate and fulfill it.
- fulfilled = _validateAndFulfillAdvancedOrder(
- _toAdvancedOrderReturnType(_decodeOrderAsAdvancedOrder)(
- CalldataStart.pptr()
- ),
- new CriteriaResolver[](0), // No criteria resolvers supplied.
- fulfillerConduitKey,
- msg.sender
- );
- }
-
- /**
- * @notice Fill an order, fully or partially, with an arbitrary number of
- * items for offer and consideration alongside criteria resolvers
- * containing specific token identifiers and associated proofs.
- *
- * @custom:param advancedOrder The order to fulfill along with the
- * fraction of the order to attempt to fill.
- * Note that both the offerer and the
- * fulfiller must first approve this
- * contract (or their conduit if indicated
- * by the order) to transfer any relevant
- * tokens on their behalf and that contracts
- * must implement `onERC1155Received` to
- * receive ERC1155 tokens as consideration.
- * Also note that all offer and
- * consideration components must have no
- * remainder after multiplication of the
- * respective amount with the supplied
- * fraction for the partial fill to be
- * considered valid.
- * @custom:param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a
- * proof that the supplied token identifier
- * is contained in the merkle root held by
- * the item in question's criteria element.
- * Note that an empty criteria indicates
- * that any (transferable) token identifier
- * on the token in question is valid and
- * that no associated proof needs to be
- * supplied.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used (and
- * direct approvals set on this contract).
- * @param recipient The intended recipient for all received
- * items, with `address(0)` indicating that
- * the caller should receive the items.
- *
- * @return fulfilled A boolean indicating whether the order has been
- * successfully fulfilled.
- */
- function fulfillAdvancedOrder(
- /**
- * @custom:name advancedOrder
- */
- AdvancedOrder calldata,
- /**
- * @custom:name criteriaResolvers
- */
- CriteriaResolver[] calldata,
- bytes32 fulfillerConduitKey,
- address recipient
- ) external payable override returns (bool fulfilled) {
- // Validate and fulfill the order.
- fulfilled = _validateAndFulfillAdvancedOrder(
- _toAdvancedOrderReturnType(_decodeAdvancedOrder)(
- CalldataStart.pptr()
- ),
- _toCriteriaResolversReturnType(_decodeCriteriaResolvers)(
- CalldataStart.pptr(
- Offset_fulfillAdvancedOrder_criteriaResolvers
- )
- ),
- fulfillerConduitKey,
- _substituteCallerForEmptyRecipient(recipient)
- );
- }
-
- /**
- * @notice Attempt to fill a group of orders, each with an arbitrary number
- * of items for offer and consideration. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- * Note that this function does not support criteria-based orders or
- * partial filling of orders (though filling the remainder of a
- * partially-filled order is supported).
- *
- * @custom:param orders The orders to fulfill. Note that
- * both the offerer and the
- * fulfiller must first approve this
- * contract (or the corresponding
- * conduit if indicated) to transfer
- * any relevant tokens on their
- * behalf and that contracts must
- * implement `onERC1155Received` to
- * receive ERC1155 tokens as
- * consideration.
- * @custom:param offerFulfillments An array of FulfillmentComponent
- * arrays indicating which offer
- * items to attempt to aggregate
- * when preparing executions. Note
- * that any offer items not included
- * as part of a fulfillment will be
- * sent unaggregated to the caller.
- * @custom:param considerationFulfillments An array of FulfillmentComponent
- * arrays indicating which
- * consideration items to attempt to
- * aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what
- * conduit, if any, to source the
- * fulfiller's token approvals from.
- * The zero hash signifies that no
- * conduit should be used (and
- * direct approvals set on this
- * contract).
- * @param maximumFulfilled The maximum number of orders to
- * fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function fulfillAvailableOrders(
- /**
- * @custom:name orders
- */
- Order[] calldata,
- /**
- * @custom:name offerFulfillments
- */
- FulfillmentComponent[][] calldata,
- /**
- * @custom:name considerationFulfillments
- */
- FulfillmentComponent[][] calldata,
- bytes32 fulfillerConduitKey,
- uint256 maximumFulfilled
- )
- external
- payable
- override
- returns (
- bool[] memory /* availableOrders */,
- Execution[] memory /* executions */
- )
- {
- // Convert orders to "advanced" orders and fulfill all available orders.
- return
- _fulfillAvailableAdvancedOrders(
- _toAdvancedOrdersReturnType(_decodeOrdersAsAdvancedOrders)(
- CalldataStart.pptr()
- ), // Convert to advanced orders.
- new CriteriaResolver[](0), // No criteria resolvers supplied.
- _toNestedFulfillmentComponentsReturnType(
- _decodeNestedFulfillmentComponents
- )(
- CalldataStart.pptr(
- Offset_fulfillAvailableOrders_offerFulfillments
- )
- ),
- _toNestedFulfillmentComponentsReturnType(
- _decodeNestedFulfillmentComponents
- )(
- CalldataStart.pptr(
- Offset_fulfillAvailableOrders_considerationFulfillments
- )
- ),
- fulfillerConduitKey,
- msg.sender,
- maximumFulfilled
- );
- }
-
- /**
- * @notice Attempt to fill a group of orders, fully or partially, with an
- * arbitrary number of items for offer and consideration per order
- * alongside criteria resolvers containing specific token
- * identifiers and associated proofs. Any order that is not
- * currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- *
- * @custom:param advancedOrders The orders to fulfill along with
- * the fraction of those orders to
- * attempt to fill. Note that both
- * the offerer and the fulfiller
- * must first approve this contract
- * (or their conduit if indicated by
- * the order) to transfer any
- * relevant tokens on their behalf
- * and that contracts must implement
- * `onERC1155Received` to receive
- * ERC1155 tokens as consideration.
- * Also note that all offer and
- * consideration components must
- * have no remainder after
- * multiplication of the respective
- * amount with the supplied fraction
- * for an order's partial fill
- * amount to be considered valid.
- * @custom:param criteriaResolvers An array where each element
- * contains a reference to a
- * specific offer or consideration,
- * a token identifier, and a proof
- * that the supplied token
- * identifier is contained in the
- * merkle root held by the item in
- * question's criteria element. Note
- * that an empty criteria indicates
- * that any (transferable) token
- * identifier on the token in
- * question is valid and that no
- * associated proof needs to be
- * supplied.
- * @custom:param offerFulfillments An array of FulfillmentComponent
- * arrays indicating which offer
- * items to attempt to aggregate
- * when preparing executions. Note
- * that any offer items not included
- * as part of a fulfillment will be
- * sent unaggregated to the caller.
- * @custom:param considerationFulfillments An array of FulfillmentComponent
- * arrays indicating which
- * consideration items to attempt to
- * aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what
- * conduit, if any, to source the
- * fulfiller's token approvals from.
- * The zero hash signifies that no
- * conduit should be used (and
- * direct approvals set on this
- * contract).
- * @param recipient The intended recipient for all
- * received items, with `address(0)`
- * indicating that the caller should
- * receive the offer items.
- * @param maximumFulfilled The maximum number of orders to
- * fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function fulfillAvailableAdvancedOrders(
- /**
- * @custom:name advancedOrders
- */
- AdvancedOrder[] calldata,
- /**
- * @custom:name criteriaResolvers
- */
- CriteriaResolver[] calldata,
- /**
- * @custom:name offerFulfillments
- */
- FulfillmentComponent[][] calldata,
- /**
- * @custom:name considerationFulfillments
- */
- FulfillmentComponent[][] calldata,
- bytes32 fulfillerConduitKey,
- address recipient,
- uint256 maximumFulfilled
- )
- external
- payable
- override
- returns (
- bool[] memory /* availableOrders */,
- Execution[] memory /* executions */
- )
- {
- // Fulfill all available orders.
- return
- _fulfillAvailableAdvancedOrders(
- _toAdvancedOrdersReturnType(_decodeAdvancedOrders)(
- CalldataStart.pptr()
- ),
- _toCriteriaResolversReturnType(_decodeCriteriaResolvers)(
- CalldataStart.pptr(
- Offset_fulfillAvailableAdvancedOrders_criteriaResolvers
- )
- ),
- _toNestedFulfillmentComponentsReturnType(
- _decodeNestedFulfillmentComponents
- )(
- CalldataStart.pptr(
- Offset_fulfillAvailableAdvancedOrders_offerFulfillments
- )
- ),
- _toNestedFulfillmentComponentsReturnType(
- _decodeNestedFulfillmentComponents
- )(
- CalldataStart.pptr(
- Offset_fulfillAvailableAdvancedOrders_cnsdrationFlflmnts
- )
- ),
- fulfillerConduitKey,
- _substituteCallerForEmptyRecipient(recipient),
- maximumFulfilled
- );
- }
-
- /**
- * @notice Match an arbitrary number of orders, each with an arbitrary
- * number of items for offer and consideration along with a set of
- * fulfillments allocating offer components to consideration
- * components. Note that this function does not support
- * criteria-based or partial filling of orders (though filling the
- * remainder of a partially-filled order is supported). Any unspent
- * offer item amounts or native tokens will be transferred to the
- * caller.
- *
- * @custom:param orders The orders to match. Note that both the
- * offerer and fulfiller on each order must first
- * approve this contract (or their conduit if
- * indicated by the order) to transfer any
- * relevant tokens on their behalf and each
- * consideration recipient must implement
- * `onERC1155Received` to receive ERC1155 tokens.
- * @custom:param fulfillments An array of elements allocating offer
- * components to consideration components. Note
- * that each consideration component must be
- * fully met for the match operation to be valid,
- * and that any unspent offer items will be sent
- * unaggregated to the caller.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or native
- * tokens will not be reflected as part of this array.
- */
- function matchOrders(
- /**
- * @custom:name orders
- */
- Order[] calldata,
- /**
- * @custom:name fulfillments
- */
- Fulfillment[] calldata
- ) external payable override returns (Execution[] memory /* executions */) {
- // Convert to advanced, validate, and match orders using fulfillments.
- return
- _matchAdvancedOrders(
- _toAdvancedOrdersReturnType(_decodeOrdersAsAdvancedOrders)(
- CalldataStart.pptr()
- ),
- new CriteriaResolver[](0), // No criteria resolvers supplied.
- _toFulfillmentsReturnType(_decodeFulfillments)(
- CalldataStart.pptr(Offset_matchOrders_fulfillments)
- ),
- msg.sender
- );
- }
-
- /**
- * @notice Match an arbitrary number of full, partial, or contract orders,
- * each with an arbitrary number of items for offer and
- * consideration, supplying criteria resolvers containing specific
- * token identifiers and associated proofs as well as fulfillments
- * allocating offer components to consideration components. Any
- * unspent offer item amounts will be transferred to the designated
- * recipient (with the null address signifying to use the caller)
- * and any unspent native tokens will be returned to the caller.
- *
- * @custom:param advancedOrders The advanced orders to match. Note that
- * both the offerer and fulfiller on each
- * order must first approve this contract
- * (or their conduit if indicated by the
- * order) to transfer any relevant tokens on
- * their behalf and each consideration
- * recipient must implement
- * `onERC1155Received` to receive ERC1155
- * tokens. Also note that the offer and
- * consideration components for each order
- * must have no remainder after multiplying
- * the respective amount with the supplied
- * fraction for the group of partial fills
- * to be considered valid.
- * @custom:param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a
- * proof that the supplied token identifier
- * is contained in the merkle root held by
- * the item in question's criteria element.
- * Note that an empty criteria indicates
- * that any (transferable) token identifier
- * on the token in question is valid and
- * that no associated proof needs to be
- * supplied.
- * @custom:param fulfillments An array of elements allocating offer
- * components to consideration components.
- * Note that each consideration component
- * must be fully met for the match operation
- * to be valid, and that any unspent offer
- * items will be sent unaggregated to the
- * designated recipient.
- * @param recipient The intended recipient for all unspent
- * offer item amounts, or the caller if the
- * null address is supplied.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders. Note that unspent offer item amounts or
- * native tokens will not be reflected as part of this
- * array.
- */
- function matchAdvancedOrders(
- /**
- * @custom:name advancedOrders
- */
- AdvancedOrder[] calldata,
- /**
- * @custom:name criteriaResolvers
- */
- CriteriaResolver[] calldata,
- /**
- * @custom:name fulfillments
- */
- Fulfillment[] calldata,
- address recipient
- ) external payable override returns (Execution[] memory /* executions */) {
- // Validate and match the advanced orders using supplied fulfillments.
- return
- _matchAdvancedOrders(
- _toAdvancedOrdersReturnType(_decodeAdvancedOrders)(
- CalldataStart.pptr()
- ),
- _toCriteriaResolversReturnType(_decodeCriteriaResolvers)(
- CalldataStart.pptr(
- Offset_matchAdvancedOrders_criteriaResolvers
- )
- ),
- _toFulfillmentsReturnType(_decodeFulfillments)(
- CalldataStart.pptr(Offset_matchAdvancedOrders_fulfillments)
- ),
- _substituteCallerForEmptyRecipient(recipient)
- );
- }
-
- /**
- * @notice Cancel an arbitrary number of orders. Note that only the offerer
- * or the zone of a given order may cancel it. Callers should ensure
- * that the intended order was cancelled by calling `getOrderStatus`
- * and confirming that `isCancelled` returns `true`.
- *
- * @param orders The orders to cancel.
- *
- * @return cancelled A boolean indicating whether the supplied orders have
- * been successfully cancelled.
- */
- function cancel(
- OrderComponents[] calldata orders
- ) external override returns (bool cancelled) {
- // Cancel the orders.
- cancelled = _cancel(orders);
- }
-
- /**
- * @notice Validate an arbitrary number of orders, thereby registering their
- * signatures as valid and allowing the fulfiller to skip signature
- * verification on fulfillment. Note that validated orders may still
- * be unfulfillable due to invalid item amounts or other factors;
- * callers should determine whether validated orders are fulfillable
- * by simulating the fulfillment call prior to execution. Also note
- * that anyone can validate a signed order, but only the offerer can
- * validate an order without supplying a signature.
- *
- * @custom:param orders The orders to validate.
- *
- * @return validated A boolean indicating whether the supplied orders have
- * been successfully validated.
- */
- function validate(
- /**
- * @custom:name orders
- */
- Order[] calldata
- ) external override returns (bool /* validated */) {
- return
- _validate(_toOrdersReturnType(_decodeOrders)(CalldataStart.pptr()));
- }
-
- /**
- * @notice Cancel all orders from a given offerer with a given zone in bulk
- * by incrementing a counter. Note that only the offerer may
- * increment the counter.
- *
- * @return newCounter The new counter.
- */
- function incrementCounter() external override returns (uint256 newCounter) {
- // Increment current counter for the supplied offerer. Note that the
- // counter is incremented by a large, quasi-random interval.
- newCounter = _incrementCounter();
- }
-
- /**
- * @notice Retrieve the order hash for a given order.
- *
- * @custom:param order The components of the order.
- *
- * @return orderHash The order hash.
- */
- function getOrderHash(
- /**
- * @custom:name order
- */
- OrderComponents calldata
- ) external view override returns (bytes32 orderHash) {
- CalldataPointer orderPointer = CalldataStart.pptr();
-
- // Derive order hash by supplying order parameters along with counter.
- orderHash = _deriveOrderHash(
- _toOrderParametersReturnType(
- _decodeOrderComponentsAsOrderParameters
- )(orderPointer),
- // Read order counter
- orderPointer.offset(OrderParameters_counter_offset).readUint256()
- );
- }
-
- /**
- * @notice Retrieve the status of a given order by hash, including whether
- * the order has been cancelled or validated and the fraction of the
- * order that has been filled. Since the _orderStatus[orderHash]
- * does not get set for contract orders, getOrderStatus will always
- * return (false, false, 0, 0) for those hashes. Note that this
- * function is susceptible to view reentrancy and so should be used
- * with care when calling from other contracts.
- *
- * @param orderHash The order hash in question.
- *
- * @return isValidated A boolean indicating whether the order in question
- * has been validated (i.e. previously approved or
- * partially filled).
- * @return isCancelled A boolean indicating whether the order in question
- * has been cancelled.
- * @return totalFilled The total portion of the order that has been filled
- * (i.e. the "numerator").
- * @return totalSize The total size of the order that is either filled or
- * unfilled (i.e. the "denominator").
- */
- function getOrderStatus(
- bytes32 orderHash
- )
- external
- view
- override
- returns (
- bool isValidated,
- bool isCancelled,
- uint256 totalFilled,
- uint256 totalSize
- )
- {
- // Retrieve the order status using the order hash.
- return _getOrderStatus(orderHash);
- }
-
- /**
- * @notice Retrieve the current counter for a given offerer.
- *
- * @param offerer The offerer in question.
- *
- * @return counter The current counter.
- */
- function getCounter(
- address offerer
- ) external view override returns (uint256 counter) {
- // Return the counter for the supplied offerer.
- counter = _getCounter(offerer);
- }
-
- /**
- * @notice Retrieve configuration information for this contract.
- *
- * @return version The contract version.
- * @return domainSeparator The domain separator for this contract.
- * @return conduitController The conduit Controller set for this contract.
- */
- function information()
- external
- view
- override
- returns (
- string memory version,
- bytes32 domainSeparator,
- address conduitController
- )
- {
- // Return the information for this contract.
- return _information();
- }
-
- /**
- * @dev Gets the contract offerer nonce for the specified contract offerer.
- * Note that this function is susceptible to view reentrancy and so
- * should be used with care when calling from other contracts.
- *
- * @param contractOfferer The contract offerer for which to get the nonce.
- *
- * @return nonce The contract offerer nonce.
- */
- function getContractOffererNonce(
- address contractOfferer
- ) external view override returns (uint256 nonce) {
- nonce = _contractNonces[contractOfferer];
- }
-
- /**
- * @notice Retrieve the name of this contract.
- *
- * @return contractName The name of this contract.
- */
- function name()
- external
- pure
- override
- returns (string memory /* contractName */)
- {
- // Return the name of the contract.
- return _name();
- }
-}
diff --git a/contracts/lib/ConsiderationBase.sol b/contracts/lib/ConsiderationBase.sol
deleted file mode 100644
index 891f3ae20..000000000
--- a/contracts/lib/ConsiderationBase.sol
+++ /dev/null
@@ -1,479 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- ConduitControllerInterface
-} from "../interfaces/ConduitControllerInterface.sol";
-
-import {
- ConsiderationEventsAndErrors
-} from "../interfaces/ConsiderationEventsAndErrors.sol";
-
-import {
- BulkOrder_Typehash_Height_One,
- BulkOrder_Typehash_Height_Two,
- BulkOrder_Typehash_Height_Three,
- BulkOrder_Typehash_Height_Four,
- BulkOrder_Typehash_Height_Five,
- BulkOrder_Typehash_Height_Six,
- BulkOrder_Typehash_Height_Seven,
- BulkOrder_Typehash_Height_Eight,
- BulkOrder_Typehash_Height_Nine,
- BulkOrder_Typehash_Height_Ten,
- BulkOrder_Typehash_Height_Eleven,
- BulkOrder_Typehash_Height_Twelve,
- BulkOrder_Typehash_Height_Thirteen,
- BulkOrder_Typehash_Height_Fourteen,
- BulkOrder_Typehash_Height_Fifteen,
- BulkOrder_Typehash_Height_Sixteen,
- BulkOrder_Typehash_Height_Seventeen,
- BulkOrder_Typehash_Height_Eighteen,
- BulkOrder_Typehash_Height_Nineteen,
- BulkOrder_Typehash_Height_Twenty,
- BulkOrder_Typehash_Height_TwentyOne,
- BulkOrder_Typehash_Height_TwentyTwo,
- BulkOrder_Typehash_Height_TwentyThree,
- BulkOrder_Typehash_Height_TwentyFour,
- EIP712_domainData_chainId_offset,
- EIP712_domainData_nameHash_offset,
- EIP712_domainData_size,
- EIP712_domainData_verifyingContract_offset,
- EIP712_domainData_versionHash_offset,
- FreeMemoryPointerSlot,
- NameLengthPtr,
- NameWithLength,
- OneWord,
- Slot0x80,
- ThreeWords,
- ZeroSlot
-} from "./ConsiderationConstants.sol";
-
-import { ConsiderationDecoder } from "./ConsiderationDecoder.sol";
-
-import { ConsiderationEncoder } from "./ConsiderationEncoder.sol";
-
-/**
- * @title ConsiderationBase
- * @author 0age
- * @notice ConsiderationBase contains immutable constants and constructor logic.
- */
-contract ConsiderationBase is
- ConsiderationDecoder,
- ConsiderationEncoder,
- ConsiderationEventsAndErrors
-{
- // Precompute hashes, original chainId, and domain separator on deployment.
- bytes32 internal immutable _NAME_HASH;
- bytes32 internal immutable _VERSION_HASH;
- bytes32 internal immutable _EIP_712_DOMAIN_TYPEHASH;
- bytes32 internal immutable _OFFER_ITEM_TYPEHASH;
- bytes32 internal immutable _CONSIDERATION_ITEM_TYPEHASH;
- bytes32 internal immutable _ORDER_TYPEHASH;
- uint256 internal immutable _CHAIN_ID;
- bytes32 internal immutable _DOMAIN_SEPARATOR;
-
- // Allow for interaction with the conduit controller.
- ConduitControllerInterface internal immutable _CONDUIT_CONTROLLER;
-
- // Cache the conduit creation code hash used by the conduit controller.
- bytes32 internal immutable _CONDUIT_CREATION_CODE_HASH;
-
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(address conduitController) {
- // Derive name and version hashes alongside required EIP-712 typehashes.
- (
- _NAME_HASH,
- _VERSION_HASH,
- _EIP_712_DOMAIN_TYPEHASH,
- _OFFER_ITEM_TYPEHASH,
- _CONSIDERATION_ITEM_TYPEHASH,
- _ORDER_TYPEHASH
- ) = _deriveTypehashes();
-
- // Store the current chainId and derive the current domain separator.
- _CHAIN_ID = block.chainid;
- _DOMAIN_SEPARATOR = _deriveDomainSeparator();
-
- // Set the supplied conduit controller.
- _CONDUIT_CONTROLLER = ConduitControllerInterface(conduitController);
-
- // Retrieve the conduit creation code hash from the supplied controller.
- (_CONDUIT_CREATION_CODE_HASH, ) = (
- _CONDUIT_CONTROLLER.getConduitCodeHashes()
- );
- }
-
- /**
- * @dev Internal view function to derive the EIP-712 domain separator.
- *
- * @return domainSeparator The derived domain separator.
- */
- function _deriveDomainSeparator()
- internal
- view
- returns (bytes32 domainSeparator)
- {
- bytes32 typehash = _EIP_712_DOMAIN_TYPEHASH;
- bytes32 nameHash = _NAME_HASH;
- bytes32 versionHash = _VERSION_HASH;
-
- // Leverage scratch space and other memory to perform an efficient hash.
- assembly {
- // Retrieve the free memory pointer; it will be replaced afterwards.
- let freeMemoryPointer := mload(FreeMemoryPointerSlot)
-
- // Retrieve value at 0x80; it will also be replaced afterwards.
- let slot0x80 := mload(Slot0x80)
-
- // Place typehash, name hash, and version hash at start of memory.
- mstore(0, typehash)
- mstore(EIP712_domainData_nameHash_offset, nameHash)
- mstore(EIP712_domainData_versionHash_offset, versionHash)
-
- // Place chainId in the next memory location.
- mstore(EIP712_domainData_chainId_offset, chainid())
-
- // Place the address of this contract in the next memory location.
- mstore(EIP712_domainData_verifyingContract_offset, address())
-
- // Hash relevant region of memory to derive the domain separator.
- domainSeparator := keccak256(0, EIP712_domainData_size)
-
- // Restore the free memory pointer.
- mstore(FreeMemoryPointerSlot, freeMemoryPointer)
-
- // Restore the zero slot to zero.
- mstore(ZeroSlot, 0)
-
- // Restore the value at 0x80.
- mstore(Slot0x80, slot0x80)
- }
- }
-
- /**
- * @dev Internal pure function to retrieve the default name of this
- * contract and return.
- *
- * @return The name of this contract.
- */
- function _name() internal pure virtual returns (string memory) {
- // Return the name of the contract.
- assembly {
- // First element is the offset for the returned string. Offset the
- // value in memory by one word so that the free memory pointer will
- // be overwritten by the next write.
- mstore(OneWord, OneWord)
-
- // Name is right padded, so it touches the length which is left
- // padded. This enables writing both values at once. The free memory
- // pointer will be overwritten in the process.
- mstore(NameLengthPtr, NameWithLength)
-
- // Standard ABI encoding pads returned data to the nearest word. Use
- // the already empty zero slot memory region for this purpose and
- // return the final name string, offset by the original single word.
- return(OneWord, ThreeWords)
- }
- }
-
- /**
- * @dev Internal pure function to retrieve the default name of this contract
- * as a string that can be used internally.
- *
- * @return The name of this contract.
- */
- function _nameString() internal pure virtual returns (string memory) {
- // Return the name of the contract.
- return "Consideration";
- }
-
- /**
- * @dev Internal pure function to derive required EIP-712 typehashes and
- * other hashes during contract creation.
- *
- * @return nameHash The hash of the name of the contract.
- * @return versionHash The hash of the version string of the
- * contract.
- * @return eip712DomainTypehash The primary EIP-712 domain typehash.
- * @return offerItemTypehash The EIP-712 typehash for OfferItem
- * types.
- * @return considerationItemTypehash The EIP-712 typehash for
- * ConsiderationItem types.
- * @return orderTypehash The EIP-712 typehash for Order types.
- */
- function _deriveTypehashes()
- internal
- pure
- returns (
- bytes32 nameHash,
- bytes32 versionHash,
- bytes32 eip712DomainTypehash,
- bytes32 offerItemTypehash,
- bytes32 considerationItemTypehash,
- bytes32 orderTypehash
- )
- {
- // Derive hash of the name of the contract.
- nameHash = keccak256(bytes(_nameString()));
-
- // Derive hash of the version string of the contract.
- versionHash = keccak256(bytes("1.5"));
-
- // Construct the OfferItem type string.
- bytes memory offerItemTypeString = bytes(
- "OfferItem("
- "uint8 itemType,"
- "address token,"
- "uint256 identifierOrCriteria,"
- "uint256 startAmount,"
- "uint256 endAmount"
- ")"
- );
-
- // Construct the ConsiderationItem type string.
- bytes memory considerationItemTypeString = bytes(
- "ConsiderationItem("
- "uint8 itemType,"
- "address token,"
- "uint256 identifierOrCriteria,"
- "uint256 startAmount,"
- "uint256 endAmount,"
- "address recipient"
- ")"
- );
-
- // Construct the OrderComponents type string, not including the above.
- bytes memory orderComponentsPartialTypeString = bytes(
- "OrderComponents("
- "address offerer,"
- "address zone,"
- "OfferItem[] offer,"
- "ConsiderationItem[] consideration,"
- "uint8 orderType,"
- "uint256 startTime,"
- "uint256 endTime,"
- "bytes32 zoneHash,"
- "uint256 salt,"
- "bytes32 conduitKey,"
- "uint256 counter"
- ")"
- );
-
- // Construct the primary EIP-712 domain type string.
- eip712DomainTypehash = keccak256(
- bytes(
- "EIP712Domain("
- "string name,"
- "string version,"
- "uint256 chainId,"
- "address verifyingContract"
- ")"
- )
- );
-
- // Derive the OfferItem type hash using the corresponding type string.
- offerItemTypehash = keccak256(offerItemTypeString);
-
- // Derive ConsiderationItem type hash using corresponding type string.
- considerationItemTypehash = keccak256(considerationItemTypeString);
-
- bytes memory orderTypeString = bytes.concat(
- orderComponentsPartialTypeString,
- considerationItemTypeString,
- offerItemTypeString
- );
-
- // Derive OrderItem type hash via combination of relevant type strings.
- orderTypehash = keccak256(orderTypeString);
- }
-
- /**
- * @dev Internal pure function to look up one of twenty-four potential bulk
- * order typehash constants based on the height of the bulk order tree.
- * Note that values between one and twenty-four are supported, which is
- * enforced by _isValidBulkOrderSize.
- *
- * @param _treeHeight The height of the bulk order tree. The value must be
- * between one and twenty-four.
- *
- * @return _typeHash The EIP-712 typehash for the bulk order type with the
- * given height.
- */
- function _lookupBulkOrderTypehash(
- uint256 _treeHeight
- ) internal pure returns (bytes32 _typeHash) {
- // Utilize assembly to efficiently retrieve correct bulk order typehash.
- assembly {
- // Use a Yul function to enable use of the `leave` keyword
- // to stop searching once the appropriate type hash is found.
- function lookupTypeHash(treeHeight) -> typeHash {
- // Handle tree heights one through eight.
- if lt(treeHeight, 9) {
- // Handle tree heights one through four.
- if lt(treeHeight, 5) {
- // Handle tree heights one and two.
- if lt(treeHeight, 3) {
- // Utilize branchless logic to determine typehash.
- typeHash := ternary(
- eq(treeHeight, 1),
- BulkOrder_Typehash_Height_One,
- BulkOrder_Typehash_Height_Two
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle height three and four via branchless logic.
- typeHash := ternary(
- eq(treeHeight, 3),
- BulkOrder_Typehash_Height_Three,
- BulkOrder_Typehash_Height_Four
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle tree height five and six.
- if lt(treeHeight, 7) {
- // Utilize branchless logic to determine typehash.
- typeHash := ternary(
- eq(treeHeight, 5),
- BulkOrder_Typehash_Height_Five,
- BulkOrder_Typehash_Height_Six
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle height seven and eight via branchless logic.
- typeHash := ternary(
- eq(treeHeight, 7),
- BulkOrder_Typehash_Height_Seven,
- BulkOrder_Typehash_Height_Eight
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle tree height nine through sixteen.
- if lt(treeHeight, 17) {
- // Handle tree height nine through twelve.
- if lt(treeHeight, 13) {
- // Handle tree height nine and ten.
- if lt(treeHeight, 11) {
- // Utilize branchless logic to determine typehash.
- typeHash := ternary(
- eq(treeHeight, 9),
- BulkOrder_Typehash_Height_Nine,
- BulkOrder_Typehash_Height_Ten
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle height eleven and twelve via branchless logic.
- typeHash := ternary(
- eq(treeHeight, 11),
- BulkOrder_Typehash_Height_Eleven,
- BulkOrder_Typehash_Height_Twelve
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle tree height thirteen and fourteen.
- if lt(treeHeight, 15) {
- // Utilize branchless logic to determine typehash.
- typeHash := ternary(
- eq(treeHeight, 13),
- BulkOrder_Typehash_Height_Thirteen,
- BulkOrder_Typehash_Height_Fourteen
- )
-
- // Exit the function once typehash has been located.
- leave
- }
- // Handle height fifteen and sixteen via branchless logic.
- typeHash := ternary(
- eq(treeHeight, 15),
- BulkOrder_Typehash_Height_Fifteen,
- BulkOrder_Typehash_Height_Sixteen
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle tree height seventeen through twenty.
- if lt(treeHeight, 21) {
- // Handle tree height seventeen and eighteen.
- if lt(treeHeight, 19) {
- // Utilize branchless logic to determine typehash.
- typeHash := ternary(
- eq(treeHeight, 17),
- BulkOrder_Typehash_Height_Seventeen,
- BulkOrder_Typehash_Height_Eighteen
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle height nineteen and twenty via branchless logic.
- typeHash := ternary(
- eq(treeHeight, 19),
- BulkOrder_Typehash_Height_Nineteen,
- BulkOrder_Typehash_Height_Twenty
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle tree height twenty-one and twenty-two.
- if lt(treeHeight, 23) {
- // Utilize branchless logic to determine typehash.
- typeHash := ternary(
- eq(treeHeight, 21),
- BulkOrder_Typehash_Height_TwentyOne,
- BulkOrder_Typehash_Height_TwentyTwo
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Handle height twenty-three & twenty-four w/ branchless logic.
- typeHash := ternary(
- eq(treeHeight, 23),
- BulkOrder_Typehash_Height_TwentyThree,
- BulkOrder_Typehash_Height_TwentyFour
- )
-
- // Exit the function once typehash has been located.
- leave
- }
-
- // Implement ternary conditional using branchless logic.
- function ternary(cond, ifTrue, ifFalse) -> c {
- c := xor(ifFalse, mul(cond, xor(ifFalse, ifTrue)))
- }
-
- // Look up the typehash using the supplied tree height.
- _typeHash := lookupTypeHash(_treeHeight)
- }
- }
-}
diff --git a/contracts/lib/ConsiderationConstants.sol b/contracts/lib/ConsiderationConstants.sol
deleted file mode 100644
index e0b127685..000000000
--- a/contracts/lib/ConsiderationConstants.sol
+++ /dev/null
@@ -1,585 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/*
- * -------------------------- Disambiguation & Other Notes ---------------------
- * - The term "head" is used as it is in the documentation for ABI encoding,
- * but only in reference to dynamic types, i.e. it always refers to the
- * offset or pointer to the body of a dynamic type. In calldata, the head
- * is always an offset (relative to the parent object), while in memory,
- * the head is always the pointer to the body. More information found here:
- * https://docs.soliditylang.org/en/v0.8.17/abi-spec.html#argument-encoding
- * - Note that the length of an array is separate from and precedes the
- * head of the array.
- *
- * - The term "body" is used in place of the term "head" used in the ABI
- * documentation. It refers to the start of the data for a dynamic type,
- * e.g. the first word of a struct or the first word of the first element
- * in an array.
- *
- * - The term "pointer" is used to describe the absolute position of a value
- * and never an offset relative to another value.
- * - The suffix "_ptr" refers to a memory pointer.
- * - The suffix "_cdPtr" refers to a calldata pointer.
- *
- * - The term "offset" is used to describe the position of a value relative
- * to some parent value. For example, OrderParameters_conduit_offset is the
- * offset to the "conduit" value in the OrderParameters struct relative to
- * the start of the body.
- * - Note: Offsets are used to derive pointers.
- *
- * - Some structs have pointers defined for all of their fields in this file.
- * Lines which are commented out are fields that are not used in the
- * codebase but have been left in for readability.
- */
-
-// Declare constants for name, version, and reentrancy sentinel values.
-
-// Name is right padded, so it touches the length which is left padded. This
-// enables writing both values at once. Length goes at byte 95 in memory, and
-// name fills bytes 96-109, so both values can be written left-padded to 77.
-uint256 constant NameLengthPtr = 0x4D;
-uint256 constant NameWithLength = 0x0d436F6E73696465726174696F6E;
-
-uint256 constant information_version_offset = 0;
-uint256 constant information_version_cd_offset = 0x60;
-uint256 constant information_domainSeparator_offset = 0x20;
-uint256 constant information_conduitController_offset = 0x40;
-uint256 constant information_versionLengthPtr = 0x63;
-uint256 constant information_versionWithLength = 0x03312e35; // 1.5
-uint256 constant information_length = 0xa0;
-
-uint256 constant _NOT_ENTERED = 1;
-uint256 constant _ENTERED = 2;
-uint256 constant _ENTERED_AND_ACCEPTING_NATIVE_TOKENS = 3;
-
-uint256 constant Offset_fulfillAdvancedOrder_criteriaResolvers = 0x20;
-uint256 constant Offset_fulfillAvailableOrders_offerFulfillments = 0x20;
-uint256 constant Offset_fulfillAvailableOrders_considerationFulfillments = 0x40;
-uint256 constant Offset_fulfillAvailableAdvancedOrders_criteriaResolvers = 0x20;
-uint256 constant Offset_fulfillAvailableAdvancedOrders_offerFulfillments = 0x40;
-uint256 constant Offset_fulfillAvailableAdvancedOrders_cnsdrationFlflmnts = (
- 0x60
-);
-
-uint256 constant Offset_matchOrders_fulfillments = 0x20;
-
-uint256 constant Offset_matchAdvancedOrders_criteriaResolvers = 0x20;
-uint256 constant Offset_matchAdvancedOrders_fulfillments = 0x40;
-
-// Common Offsets
-// Offsets for identically positioned fields shared by:
-// OfferItem, ConsiderationItem, SpentItem, ReceivedItem
-
-uint256 constant Selector_length = 0x4;
-
-uint256 constant Common_token_offset = 0x20;
-uint256 constant Common_identifier_offset = 0x40;
-uint256 constant Common_amount_offset = 0x60;
-uint256 constant Common_endAmount_offset = 0x80;
-
-uint256 constant SpentItem_size = 0x80;
-uint256 constant SpentItem_size_shift = 0x7;
-
-uint256 constant OfferItem_size = 0xa0;
-uint256 constant OfferItem_size_with_length = 0xc0;
-
-uint256 constant ReceivedItem_size_excluding_recipient = 0x80;
-uint256 constant ReceivedItem_size = 0xa0;
-uint256 constant ReceivedItem_amount_offset = 0x60;
-uint256 constant ReceivedItem_recipient_offset = 0x80;
-
-uint256 constant ReceivedItem_CommonParams_size = 0x60;
-
-uint256 constant ConsiderationItem_size = 0xc0;
-uint256 constant ConsiderationItem_size_with_length = 0xe0;
-
-uint256 constant ConsiderationItem_recipient_offset = 0xa0;
-// Store the same constant in an abbreviated format for a line length fix.
-uint256 constant ConsiderItem_recipient_offset = 0xa0;
-
-uint256 constant Execution_offerer_offset = 0x20;
-uint256 constant Execution_conduit_offset = 0x40;
-
-// uint256 constant OrderParameters_offerer_offset = 0x00;
-uint256 constant OrderParameters_zone_offset = 0x20;
-uint256 constant OrderParameters_offer_head_offset = 0x40;
-uint256 constant OrderParameters_consideration_head_offset = 0x60;
-// uint256 constant OrderParameters_orderType_offset = 0x80;
-uint256 constant OrderParameters_startTime_offset = 0xa0;
-uint256 constant OrderParameters_endTime_offset = 0xc0;
-uint256 constant OrderParameters_zoneHash_offset = 0xe0;
-// uint256 constant OrderParameters_salt_offset = 0x100;
-uint256 constant OrderParameters_conduit_offset = 0x120;
-uint256 constant OrderParameters_counter_offset = 0x140;
-
-uint256 constant Fulfillment_itemIndex_offset = 0x20;
-
-uint256 constant AdvancedOrder_head_size = 0xa0;
-uint256 constant AdvancedOrder_numerator_offset = 0x20;
-uint256 constant AdvancedOrder_denominator_offset = 0x40;
-uint256 constant AdvancedOrder_signature_offset = 0x60;
-uint256 constant AdvancedOrder_extraData_offset = 0x80;
-
-uint256 constant OrderStatus_ValidatedAndNotCancelled = 1;
-uint256 constant OrderStatus_filledNumerator_offset = 0x10;
-uint256 constant OrderStatus_filledDenominator_offset = 0x88;
-
-uint256 constant ThirtyOneBytes = 0x1f;
-uint256 constant OneWord = 0x20;
-uint256 constant TwoWords = 0x40;
-uint256 constant ThreeWords = 0x60;
-uint256 constant FourWords = 0x80;
-uint256 constant FiveWords = 0xa0;
-
-uint256 constant OneWordShift = 0x5;
-uint256 constant TwoWordsShift = 0x6;
-
-uint256 constant SixtyThreeBytes = 0x3f;
-uint256 constant OnlyFullWordMask = 0xffffffe0;
-
-uint256 constant FreeMemoryPointerSlot = 0x40;
-uint256 constant ZeroSlot = 0x60;
-uint256 constant DefaultFreeMemoryPointer = 0x80;
-
-uint256 constant Slot0x80 = 0x80;
-uint256 constant Slot0xA0 = 0xa0;
-
-// uint256 constant BasicOrder_endAmount_cdPtr = 0x104;
-uint256 constant BasicOrder_common_params_size = 0xa0;
-uint256 constant BasicOrder_considerationHashesArray_ptr = 0x160;
-uint256 constant BasicOrder_receivedItemByteMap = (
- 0x0000010102030000000000000000000000000000000000000000000000000000
-);
-uint256 constant BasicOrder_offeredItemByteMap = (
- 0x0203020301010000000000000000000000000000000000000000000000000000
-);
-
-bytes32 constant OrdersMatchedTopic0 = (
- 0x4b9f2d36e1b4c93de62cc077b00b1a91d84b6c31b4a14e012718dcca230689e7
-);
-
-uint256 constant EIP712_Order_size = 0x180;
-uint256 constant EIP712_OfferItem_size = 0xc0;
-uint256 constant EIP712_ConsiderationItem_size = 0xe0;
-uint256 constant AdditionalRecipient_size = 0x40;
-uint256 constant AdditionalRecipient_size_shift = 0x6;
-
-uint256 constant EIP712_DomainSeparator_offset = 0x02;
-uint256 constant EIP712_OrderHash_offset = 0x22;
-uint256 constant EIP712_DigestPayload_size = 0x42;
-
-uint256 constant EIP712_domainData_nameHash_offset = 0x20;
-uint256 constant EIP712_domainData_versionHash_offset = 0x40;
-uint256 constant EIP712_domainData_chainId_offset = 0x60;
-uint256 constant EIP712_domainData_verifyingContract_offset = 0x80;
-uint256 constant EIP712_domainData_size = 0xa0;
-
-// Minimum BulkOrder proof size: 64 bytes for signature + 3 for key + 32 for 1
-// sibling. Maximum BulkOrder proof size: 65 bytes for signature + 3 for key +
-// 768 for 24 siblings.
-
-uint256 constant BulkOrderProof_minSize = 0x63;
-uint256 constant BulkOrderProof_rangeSize = 0x2e2;
-uint256 constant BulkOrderProof_lengthAdjustmentBeforeMask = 0x1d;
-uint256 constant BulkOrderProof_lengthRangeAfterMask = 0x2;
-uint256 constant BulkOrderProof_keyShift = 0xe8;
-uint256 constant BulkOrderProof_keySize = 0x3;
-
-uint256 constant BulkOrder_Typehash_Height_One = (
- 0x3ca2711d29384747a8f61d60aad3c450405f7aaff5613541dee28df2d6986d32
-);
-uint256 constant BulkOrder_Typehash_Height_Two = (
- 0xbf8e29b89f29ed9b529c154a63038ffca562f8d7cd1e2545dda53a1b582dde30
-);
-uint256 constant BulkOrder_Typehash_Height_Three = (
- 0x53c6f6856e13104584dd0797ca2b2779202dc2597c6066a42e0d8fe990b0024d
-);
-uint256 constant BulkOrder_Typehash_Height_Four = (
- 0xa02eb7ff164c884e5e2c336dc85f81c6a93329d8e9adf214b32729b894de2af1
-);
-uint256 constant BulkOrder_Typehash_Height_Five = (
- 0x39c9d33c18e050dda0aeb9a8086fb16fc12d5d64536780e1da7405a800b0b9f6
-);
-uint256 constant BulkOrder_Typehash_Height_Six = (
- 0x1c19f71958cdd8f081b4c31f7caf5c010b29d12950be2fa1c95070dc47e30b55
-);
-uint256 constant BulkOrder_Typehash_Height_Seven = (
- 0xca74fab2fece9a1d58234a274220ad05ca096a92ef6a1ca1750b9d90c948955c
-);
-uint256 constant BulkOrder_Typehash_Height_Eight = (
- 0x7ff98d9d4e55d876c5cfac10b43c04039522f3ddfb0ea9bfe70c68cfb5c7cc14
-);
-uint256 constant BulkOrder_Typehash_Height_Nine = (
- 0xbed7be92d41c56f9e59ac7a6272185299b815ddfabc3f25deb51fe55fe2f9e8a
-);
-uint256 constant BulkOrder_Typehash_Height_Ten = (
- 0xd1d97d1ef5eaa37a4ee5fbf234e6f6d64eb511eb562221cd7edfbdde0848da05
-);
-uint256 constant BulkOrder_Typehash_Height_Eleven = (
- 0x896c3f349c4da741c19b37fec49ed2e44d738e775a21d9c9860a69d67a3dae53
-);
-uint256 constant BulkOrder_Typehash_Height_Twelve = (
- 0xbb98d87cc12922b83759626c5f07d72266da9702d19ffad6a514c73a89002f5f
-);
-uint256 constant BulkOrder_Typehash_Height_Thirteen = (
- 0xe6ae19322608dd1f8a8d56aab48ed9c28be489b689f4b6c91268563efc85f20e
-);
-uint256 constant BulkOrder_Typehash_Height_Fourteen = (
- 0x6b5b04cbae4fcb1a9d78e7b2dfc51a36933d023cf6e347e03d517b472a852590
-);
-uint256 constant BulkOrder_Typehash_Height_Fifteen = (
- 0xd1eb68309202b7106b891e109739dbbd334a1817fe5d6202c939e75cf5e35ca9
-);
-uint256 constant BulkOrder_Typehash_Height_Sixteen = (
- 0x1da3eed3ecef6ebaa6e5023c057ec2c75150693fd0dac5c90f4a142f9879fde8
-);
-uint256 constant BulkOrder_Typehash_Height_Seventeen = (
- 0xeee9a1392aa395c7002308119a58f2582777a75e54e0c1d5d5437bd2e8bf6222
-);
-uint256 constant BulkOrder_Typehash_Height_Eighteen = (
- 0xc3939feff011e53ab8c35ca3370aad54c5df1fc2938cd62543174fa6e7d85877
-);
-uint256 constant BulkOrder_Typehash_Height_Nineteen = (
- 0x0efca7572ac20f5ae84db0e2940674f7eca0a4726fa1060ffc2d18cef54b203d
-);
-uint256 constant BulkOrder_Typehash_Height_Twenty = (
- 0x5a4f867d3d458dabecad65f6201ceeaba0096df2d0c491cc32e6ea4e64350017
-);
-uint256 constant BulkOrder_Typehash_Height_TwentyOne = (
- 0x80987079d291feebf21c2230e69add0f283cee0b8be492ca8050b4185a2ff719
-);
-uint256 constant BulkOrder_Typehash_Height_TwentyTwo = (
- 0x3bd8cff538aba49a9c374c806d277181e9651624b3e31111bc0624574f8bca1d
-);
-uint256 constant BulkOrder_Typehash_Height_TwentyThree = (
- 0x5d6a3f098a0bc373f808c619b1bb4028208721b3c4f8d6bc8a874d659814eb76
-);
-uint256 constant BulkOrder_Typehash_Height_TwentyFour = (
- 0x1d51df90cba8de7637ca3e8fe1e3511d1dc2f23487d05dbdecb781860c21ac1c
-);
-
-uint256 constant receivedItemsHash_ptr = 0x60;
-
-/*
- * Memory layout in _prepareBasicFulfillmentFromCalldata of
- * data for OrderFulfilled
- *
- * event OrderFulfilled(
- * bytes32 orderHash,
- * address indexed offerer,
- * address indexed zone,
- * address fulfiller,
- * SpentItem[] offer,
- * > (itemType, token, id, amount)
- * ReceivedItem[] consideration
- * > (itemType, token, id, amount, recipient)
- * )
- *
- * - 0x00: orderHash
- * - 0x20: fulfiller
- * - 0x40: offer offset (0x80)
- * - 0x60: consideration offset (0x120)
- * - 0x80: offer.length (1)
- * - 0xa0: offerItemType
- * - 0xc0: offerToken
- * - 0xe0: offerIdentifier
- * - 0x100: offerAmount
- * - 0x120: consideration.length (1 + additionalRecipients.length)
- * - 0x140: considerationItemType
- * - 0x160: considerationToken
- * - 0x180: considerationIdentifier
- * - 0x1a0: considerationAmount
- * - 0x1c0: considerationRecipient
- * - ...
- */
-
-// Minimum length of the OrderFulfilled event data.
-// Must be added to the size of the ReceivedItem array for additionalRecipients
-// (0xa0 * additionalRecipients.length) to calculate full size of the buffer.
-uint256 constant OrderFulfilled_baseSize = 0x1e0;
-uint256 constant OrderFulfilled_selector = (
- 0x9d9af8e38d66c62e2c12f0225249fd9d721c54b83f48d9352c97c6cacdcb6f31
-);
-
-// Minimum offset in memory to OrderFulfilled event data.
-// Must be added to the size of the EIP712 hash array for additionalRecipients
-// (32 * additionalRecipients.length) to calculate the pointer to event data.
-uint256 constant OrderFulfilled_baseOffset = 0x180;
-uint256 constant OrderFulfilled_consideration_length_baseOffset = 0x2a0;
-uint256 constant OrderFulfilled_offer_length_baseOffset = 0x200;
-
-// Related constants used for restricted order checks on basic orders.
-uint256 constant OrderFulfilled_baseDataSize = 0x160;
-// uint256 constant ValidateOrder_offerDataOffset = 0x184;
-// uint256 constant RatifyOrder_offerDataOffset = 0xc4;
-
-// uint256 constant OrderFulfilled_orderHash_offset = 0x00;
-uint256 constant OrderFulfilled_fulfiller_offset = 0x20;
-uint256 constant OrderFulfilled_offer_head_offset = 0x40;
-uint256 constant OrderFulfilled_offer_body_offset = 0x80;
-uint256 constant OrderFulfilled_consideration_head_offset = 0x60;
-uint256 constant OrderFulfilled_consideration_body_offset = 0x120;
-
-// BasicOrderParameters
-uint256 constant BasicOrder_parameters_cdPtr = 0x04;
-uint256 constant BasicOrder_considerationToken_cdPtr = 0x24;
-uint256 constant BasicOrder_considerationIdentifier_cdPtr = 0x44;
-uint256 constant BasicOrder_considerationAmount_cdPtr = 0x64;
-uint256 constant BasicOrder_offerer_cdPtr = 0x84;
-uint256 constant BasicOrder_zone_cdPtr = 0xa4;
-uint256 constant BasicOrder_offerToken_cdPtr = 0xc4;
-uint256 constant BasicOrder_offerIdentifier_cdPtr = 0xe4;
-uint256 constant BasicOrder_offerAmount_cdPtr = 0x104;
-uint256 constant BasicOrder_basicOrderType_cdPtr = 0x124;
-uint256 constant BasicOrder_startTime_cdPtr = 0x144;
-uint256 constant BasicOrder_endTime_cdPtr = 0x164;
-// uint256 constant BasicOrder_zoneHash_cdPtr = 0x184;
-// uint256 constant BasicOrder_salt_cdPtr = 0x1a4;
-uint256 constant BasicOrder_offererConduit_cdPtr = 0x1c4;
-uint256 constant BasicOrder_fulfillerConduit_cdPtr = 0x1e4;
-uint256 constant BasicOrder_totalOriginalAdditionalRecipients_cdPtr = 0x204;
-uint256 constant BasicOrder_additionalRecipients_head_cdPtr = 0x224;
-uint256 constant BasicOrder_signature_cdPtr = 0x244;
-uint256 constant BasicOrder_additionalRecipients_length_cdPtr = 0x264;
-uint256 constant BasicOrder_additionalRecipients_data_cdPtr = 0x284;
-uint256 constant BasicOrder_parameters_ptr = 0x20;
-uint256 constant BasicOrder_basicOrderType_range = 0x18; // 24 values
-
-/*
- * Memory layout in _prepareBasicFulfillmentFromCalldata of
- * EIP712 data for ConsiderationItem
- * - 0x80: ConsiderationItem EIP-712 typehash (constant)
- * - 0xa0: itemType
- * - 0xc0: token
- * - 0xe0: identifier
- * - 0x100: startAmount
- * - 0x120: endAmount
- * - 0x140: recipient
- */
-uint256 constant BasicOrder_considerationItem_typeHash_ptr = 0x80; // memoryPtr
-uint256 constant BasicOrder_considerationItem_itemType_ptr = 0xa0;
-uint256 constant BasicOrder_considerationItem_token_ptr = 0xc0;
-uint256 constant BasicOrder_considerationItem_identifier_ptr = 0xe0;
-uint256 constant BasicOrder_considerationItem_startAmount_ptr = 0x100;
-uint256 constant BasicOrder_considerationItem_endAmount_ptr = 0x120;
-// uint256 constant BasicOrder_considerationItem_recipient_ptr = 0x140;
-
-/*
- * Memory layout in _prepareBasicFulfillmentFromCalldata of
- * EIP712 data for OfferItem
- * - 0x80: OfferItem EIP-712 typehash (constant)
- * - 0xa0: itemType
- * - 0xc0: token
- * - 0xe0: identifier (reused for offeredItemsHash)
- * - 0x100: startAmount
- * - 0x120: endAmount
- */
-uint256 constant BasicOrder_offerItem_typeHash_ptr = 0x80;
-uint256 constant BasicOrder_offerItem_itemType_ptr = 0xa0;
-uint256 constant BasicOrder_offerItem_token_ptr = 0xc0;
-// uint256 constant BasicOrder_offerItem_identifier_ptr = 0xe0;
-// uint256 constant BasicOrder_offerItem_startAmount_ptr = 0x100;
-uint256 constant BasicOrder_offerItem_endAmount_ptr = 0x120;
-
-/*
- * Memory layout in _prepareBasicFulfillmentFromCalldata of
- * EIP712 data for Order
- * - 0x80: Order EIP-712 typehash (constant)
- * - 0xa0: orderParameters.offerer
- * - 0xc0: orderParameters.zone
- * - 0xe0: keccak256(abi.encodePacked(offerHashes))
- * - 0x100: keccak256(abi.encodePacked(considerationHashes))
- * - 0x120: orderType
- * - 0x140: startTime
- * - 0x160: endTime
- * - 0x180: zoneHash
- * - 0x1a0: salt
- * - 0x1c0: conduit
- * - 0x1e0: _counters[orderParameters.offerer] (from storage)
- */
-uint256 constant BasicOrder_order_typeHash_ptr = 0x80;
-uint256 constant BasicOrder_order_offerer_ptr = 0xa0;
-// uint256 constant BasicOrder_order_zone_ptr = 0xc0;
-uint256 constant BasicOrder_order_offerHashes_ptr = 0xe0;
-uint256 constant BasicOrder_order_considerationHashes_ptr = 0x100;
-uint256 constant BasicOrder_order_orderType_ptr = 0x120;
-uint256 constant BasicOrder_order_startTime_ptr = 0x140;
-// uint256 constant BasicOrder_order_endTime_ptr = 0x160;
-// uint256 constant BasicOrder_order_zoneHash_ptr = 0x180;
-// uint256 constant BasicOrder_order_salt_ptr = 0x1a0;
-// uint256 constant BasicOrder_order_conduitKey_ptr = 0x1c0;
-uint256 constant BasicOrder_order_counter_ptr = 0x1e0;
-uint256 constant BasicOrder_additionalRecipients_head_ptr = 0x240;
-uint256 constant BasicOrder_signature_ptr = 0x260;
-uint256 constant BasicOrder_startTimeThroughZoneHash_size = 0x60;
-
-uint256 constant ContractOrder_orderHash_offerer_shift = 0x60;
-
-uint256 constant Counter_blockhash_shift = 0x80;
-
-// Signature-related
-bytes32 constant EIP2098_allButHighestBitMask = (
- 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
-);
-bytes32 constant ECDSA_twentySeventhAndTwentyEighthBytesSet = (
- 0x0000000000000000000000000000000000000000000000000000000101000000
-);
-uint256 constant ECDSA_MaxLength = 65;
-uint256 constant ECDSA_signature_s_offset = 0x40;
-uint256 constant ECDSA_signature_v_offset = 0x60;
-
-bytes32 constant EIP1271_isValidSignature_selector = (
- 0x1626ba7e00000000000000000000000000000000000000000000000000000000
-);
-uint256 constant EIP1271_isValidSignature_digest_negativeOffset = 0x40;
-uint256 constant EIP1271_isValidSignature_selector_negativeOffset = 0x44;
-uint256 constant EIP1271_isValidSignature_calldata_baseLength = 0x64;
-uint256 constant EIP1271_isValidSignature_signature_head_offset = 0x40;
-
-uint256 constant EIP_712_PREFIX = (
- 0x1901000000000000000000000000000000000000000000000000000000000000
-);
-
-uint256 constant ExtraGasBuffer = 0x20;
-uint256 constant CostPerWord = 0x3;
-uint256 constant MemoryExpansionCoefficientShift = 0x9;
-
-uint256 constant Create2AddressDerivation_ptr = 0x0b;
-uint256 constant Create2AddressDerivation_length = 0x55;
-
-uint256 constant MaskOverByteTwelve = (
- 0x0000000000000000000000ff0000000000000000000000000000000000000000
-);
-uint256 constant MaskOverLastTwentyBytes = (
- 0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff
-);
-uint256 constant AddressDirtyUpperBitThreshold = (
- 0x0000000000000000000000010000000000000000000000000000000000000000
-);
-uint256 constant MaskOverFirstFourBytes = (
- 0xffffffff00000000000000000000000000000000000000000000000000000000
-);
-
-uint256 constant Conduit_execute_signature = (
- 0x4ce34aa200000000000000000000000000000000000000000000000000000000
-);
-
-uint256 constant MaxUint8 = 0xff;
-uint256 constant MaxUint120 = 0xffffffffffffffffffffffffffffff;
-
-uint256 constant Conduit_execute_ConduitTransfer_ptr = 0x20;
-uint256 constant Conduit_execute_ConduitTransfer_length = 0x01;
-uint256 constant Conduit_execute_ConduitTransfer_offset_ptr = 0x04;
-uint256 constant Conduit_execute_ConduitTransfer_length_ptr = 0x24;
-uint256 constant Conduit_execute_transferItemType_ptr = 0x44;
-uint256 constant Conduit_execute_transferToken_ptr = 0x64;
-uint256 constant Conduit_execute_transferFrom_ptr = 0x84;
-uint256 constant Conduit_execute_transferTo_ptr = 0xa4;
-uint256 constant Conduit_execute_transferIdentifier_ptr = 0xc4;
-uint256 constant Conduit_execute_transferAmount_ptr = 0xe4;
-
-uint256 constant OneConduitExecute_size = 0x104;
-
-// Sentinel value to indicate that the conduit accumulator is not armed.
-uint256 constant AccumulatorDisarmed = 0x20;
-uint256 constant AccumulatorArmed = 0x40;
-uint256 constant Accumulator_conduitKey_ptr = 0x20;
-uint256 constant Accumulator_selector_ptr = 0x40;
-uint256 constant Accumulator_array_offset_ptr = 0x44;
-uint256 constant Accumulator_array_length_ptr = 0x64;
-uint256 constant Accumulator_itemSizeOffsetDifference = 0x3c;
-uint256 constant Accumulator_array_offset = 0x20;
-
-uint256 constant Conduit_transferItem_size = 0xc0;
-uint256 constant Conduit_transferItem_token_ptr = 0x20;
-uint256 constant Conduit_transferItem_from_ptr = 0x40;
-uint256 constant Conduit_transferItem_to_ptr = 0x60;
-uint256 constant Conduit_transferItem_identifier_ptr = 0x80;
-uint256 constant Conduit_transferItem_amount_ptr = 0xa0;
-
-uint256 constant Ecrecover_precompile = 0x1;
-uint256 constant Ecrecover_args_size = 0x80;
-uint256 constant Signature_lower_v = 27;
-
-// Bitmask that only gives a non-zero value if masked with a non-match selector.
-uint256 constant NonMatchSelector_MagicMask = (
- 0x4000000000000000000000000000000000000000000000000000000000
-);
-
-// First bit indicates that a NATIVE offer items has been used and the 231st bit
-// indicates that a non match selector has been called.
-uint256 constant NonMatchSelector_InvalidErrorValue = (
- 0x4000000000000000000000000000000000000000000000000000000001
-);
-
-/**
- * @dev Selector and offsets for generateOrder
- *
- * function generateOrder(
- * address fulfiller,
- * SpentItem[] calldata minimumReceived,
- * SpentItem[] calldata maximumSpent,
- * bytes calldata context
- * )
- */
-uint256 constant generateOrder_selector = 0x98919765;
-uint256 constant generateOrder_selector_offset = 0x1c;
-uint256 constant generateOrder_head_offset = 0x04;
-uint256 constant generateOrder_minimumReceived_head_offset = 0x20;
-uint256 constant generateOrder_maximumSpent_head_offset = 0x40;
-uint256 constant generateOrder_context_head_offset = 0x60;
-uint256 constant generateOrder_base_tail_offset = 0x80;
-uint256 constant generateOrder_maximum_returndatasize = 0xffff;
-
-uint256 constant ratifyOrder_selector = 0xf4dd92ce;
-uint256 constant ratifyOrder_selector_offset = 0x1c;
-uint256 constant ratifyOrder_head_offset = 0x04;
-// uint256 constant ratifyOrder_offer_head_offset = 0x00;
-uint256 constant ratifyOrder_consideration_head_offset = 0x20;
-uint256 constant ratifyOrder_context_head_offset = 0x40;
-uint256 constant ratifyOrder_orderHashes_head_offset = 0x60;
-uint256 constant ratifyOrder_contractNonce_offset = 0x80;
-uint256 constant ratifyOrder_base_tail_offset = 0xa0;
-
-uint256 constant validateOrder_selector = 0x17b1f942;
-uint256 constant validateOrder_selector_offset = 0x1c;
-uint256 constant validateOrder_head_offset = 0x04;
-uint256 constant validateOrder_zoneParameters_offset = 0x20;
-
-// uint256 constant ZoneParameters_orderHash_offset = 0x00;
-uint256 constant ZoneParameters_fulfiller_offset = 0x20;
-uint256 constant ZoneParameters_offerer_offset = 0x40;
-uint256 constant ZoneParameters_offer_head_offset = 0x60;
-uint256 constant ZoneParameters_consideration_head_offset = 0x80;
-uint256 constant ZoneParameters_extraData_head_offset = 0xa0;
-uint256 constant ZoneParameters_orderHashes_head_offset = 0xc0;
-uint256 constant ZoneParameters_startTime_offset = 0xe0;
-uint256 constant ZoneParameters_endTime_offset = 0x100;
-uint256 constant ZoneParameters_zoneHash_offset = 0x120;
-uint256 constant ZoneParameters_base_tail_offset = 0x140;
-uint256 constant ZoneParameters_selectorAndPointer_length = 0x24;
-uint256 constant ZoneParameters_basicOrderFixedElements_length = 0x64;
-
-// ConsiderationDecoder Constants
-uint256 constant OrderParameters_head_size = 0x0160;
-uint256 constant OrderParameters_totalOriginalConsiderationItems_offset = (
- 0x0140
-);
-uint256 constant AdvancedOrderPlusOrderParameters_head_size = 0x0200;
-
-uint256 constant Order_signature_offset = 0x20;
-uint256 constant Order_head_size = 0x40;
-
-uint256 constant AdvancedOrder_fixed_segment_0 = 0x40;
-
-uint256 constant CriteriaResolver_head_size = 0xa0;
-uint256 constant CriteriaResolver_fixed_segment_0 = 0x80;
-uint256 constant CriteriaResolver_criteriaProof_offset = 0x80;
-
-uint256 constant FulfillmentComponent_mem_tail_size = 0x40;
-uint256 constant FulfillmentComponent_mem_tail_size_shift = 0x6;
-uint256 constant Fulfillment_head_size = 0x40;
-uint256 constant Fulfillment_considerationComponents_offset = 0x20;
-
-uint256 constant OrderComponents_OrderParameters_common_head_size = 0x0140;
diff --git a/contracts/lib/ConsiderationDecoder.sol b/contracts/lib/ConsiderationDecoder.sol
deleted file mode 100644
index 76ac604c3..000000000
--- a/contracts/lib/ConsiderationDecoder.sol
+++ /dev/null
@@ -1,1358 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- AdvancedOrder,
- ConsiderationItem,
- CriteriaResolver,
- Fulfillment,
- FulfillmentComponent,
- OfferItem,
- Order,
- OrderParameters,
- ReceivedItem
-} from "./ConsiderationStructs.sol";
-
-import {
- AdvancedOrder_denominator_offset,
- AdvancedOrder_extraData_offset,
- AdvancedOrder_fixed_segment_0,
- AdvancedOrder_head_size,
- AdvancedOrder_numerator_offset,
- AdvancedOrder_signature_offset,
- AdvancedOrderPlusOrderParameters_head_size,
- Common_amount_offset,
- Common_endAmount_offset,
- ConsiderationItem_size_with_length,
- ConsiderationItem_size,
- CriteriaResolver_criteriaProof_offset,
- CriteriaResolver_fixed_segment_0,
- CriteriaResolver_head_size,
- FourWords,
- FreeMemoryPointerSlot,
- Fulfillment_considerationComponents_offset,
- Fulfillment_head_size,
- FulfillmentComponent_mem_tail_size_shift,
- FulfillmentComponent_mem_tail_size,
- generateOrder_maximum_returndatasize,
- OfferItem_size_with_length,
- OfferItem_size,
- OneWord,
- OneWordShift,
- OnlyFullWordMask,
- Order_head_size,
- Order_signature_offset,
- OrderComponents_OrderParameters_common_head_size,
- OrderParameters_consideration_head_offset,
- OrderParameters_head_size,
- OrderParameters_offer_head_offset,
- OrderParameters_totalOriginalConsiderationItems_offset,
- ReceivedItem_recipient_offset,
- ReceivedItem_size,
- ReceivedItem_size_excluding_recipient,
- SpentItem_size_shift,
- SpentItem_size,
- ThirtyOneBytes,
- TwoWords
-} from "./ConsiderationConstants.sol";
-
-import {
- CalldataPointer,
- malloc,
- MemoryPointer,
- OffsetOrLengthMask
-} from "../helpers/PointerLibraries.sol";
-
-contract ConsiderationDecoder {
- /**
- * @dev Takes a bytes array from calldata and copies it into memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the bytes array in
- * calldata which contains the length of the array.
- *
- * @return mPtrLength A memory pointer to the start of the bytes array in
- * memory which contains the length of the array.
- */
- function _decodeBytes(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- assembly {
- // Get the current free memory pointer.
- mPtrLength := mload(FreeMemoryPointerSlot)
-
- // Derive the size of the bytes array, rounding up to nearest word
- // and adding a word for the length field. Note: masking
- // `calldataload(cdPtrLength)` is redundant here.
- let size := add(
- and(
- add(calldataload(cdPtrLength), ThirtyOneBytes),
- OnlyFullWordMask
- ),
- OneWord
- )
-
- // Copy bytes from calldata into memory based on pointers and size.
- calldatacopy(mPtrLength, cdPtrLength, size)
-
- // Store the masked value in memory. Note: the value of `size` is at
- // least 32, meaning the calldatacopy above will at least write to
- // `[mPtrLength, mPtrLength + 32)`.
- mstore(
- mPtrLength,
- and(calldataload(cdPtrLength), OffsetOrLengthMask)
- )
-
- // Update free memory pointer based on the size of the bytes array.
- mstore(FreeMemoryPointerSlot, add(mPtrLength, size))
- }
- }
-
- /**
- * @dev Takes an offer array from calldata and copies it into memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the offer array
- * in calldata which contains the length of the array.
- *
- * @return mPtrLength A memory pointer to the start of the offer array in
- * memory which contains the length of the array.
- */
- function _decodeOffer(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- assembly {
- // Retrieve length of array, masking to prevent potential overflow.
- let arrLength := and(calldataload(cdPtrLength), OffsetOrLengthMask)
-
- // Get the current free memory pointer.
- mPtrLength := mload(FreeMemoryPointerSlot)
-
- // Write the array length to memory.
- mstore(mPtrLength, arrLength)
-
- // Derive the head by adding one word to the length pointer.
- let mPtrHead := add(mPtrLength, OneWord)
-
- // Derive the tail by adding one word per element (note that structs
- // are written to memory with an offset per struct element).
- let mPtrTail := add(mPtrHead, shl(OneWordShift, arrLength))
-
- // Track the next tail, beginning with the initial tail value.
- let mPtrTailNext := mPtrTail
-
- // Copy all offer array data into memory at the tail pointer.
- calldatacopy(
- mPtrTail,
- add(cdPtrLength, OneWord),
- mul(arrLength, OfferItem_size)
- )
-
- // Track the next head pointer, starting with initial head value.
- let mPtrHeadNext := mPtrHead
-
- // Iterate over each head pointer until it reaches the tail.
- for {
-
- } lt(mPtrHeadNext, mPtrTail) {
-
- } {
- // Write the next tail pointer to next head pointer in memory.
- mstore(mPtrHeadNext, mPtrTailNext)
-
- // Increment the next head pointer by one word.
- mPtrHeadNext := add(mPtrHeadNext, OneWord)
-
- // Increment the next tail pointer by the size of an offer item.
- mPtrTailNext := add(mPtrTailNext, OfferItem_size)
- }
-
- // Update free memory pointer to allocate memory up to end of tail.
- mstore(FreeMemoryPointerSlot, mPtrTailNext)
- }
- }
-
- /**
- * @dev Takes a consideration array from calldata and copies it into memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the consideration
- * array in calldata which contains the length of the
- * array.
- *
- * @return mPtrLength A memory pointer to the start of the consideration
- * array in memory which contains the length of the
- * array.
- */
- function _decodeConsideration(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- assembly {
- // Retrieve length of array, masking to prevent potential overflow.
- let arrLength := and(calldataload(cdPtrLength), OffsetOrLengthMask)
-
- // Get the current free memory pointer.
- mPtrLength := mload(FreeMemoryPointerSlot)
-
- // Write the array length to memory.
- mstore(mPtrLength, arrLength)
-
- // Derive the head by adding one word to the length pointer.
- let mPtrHead := add(mPtrLength, OneWord)
-
- // Derive the tail by adding one word per element (note that structs
- // are written to memory with an offset per struct element).
- let mPtrTail := add(mPtrHead, shl(OneWordShift, arrLength))
-
- // Track the next tail, beginning with the initial tail value.
- let mPtrTailNext := mPtrTail
-
- // Copy all consideration array data into memory at tail pointer.
- calldatacopy(
- mPtrTail,
- add(cdPtrLength, OneWord),
- mul(arrLength, ConsiderationItem_size)
- )
-
- // Track the next head pointer, starting with initial head value.
- let mPtrHeadNext := mPtrHead
-
- // Iterate over each head pointer until it reaches the tail.
- for {
-
- } lt(mPtrHeadNext, mPtrTail) {
-
- } {
- // Write the next tail pointer to next head pointer in memory.
- mstore(mPtrHeadNext, mPtrTailNext)
-
- // Increment the next head pointer by one word.
- mPtrHeadNext := add(mPtrHeadNext, OneWord)
-
- // Increment next tail pointer by size of a consideration item.
- mPtrTailNext := add(mPtrTailNext, ConsiderationItem_size)
- }
-
- // Update free memory pointer to allocate memory up to end of tail.
- mstore(FreeMemoryPointerSlot, mPtrTailNext)
- }
- }
-
- /**
- * @dev Takes a calldata pointer and memory pointer and copies a referenced
- * OrderParameters struct and associated offer and consideration data
- * to memory.
- *
- * @param cdPtr A calldata pointer for the OrderParameters struct.
- * @param mPtr A memory pointer to the OrderParameters struct head.
- */
- function _decodeOrderParametersTo(
- CalldataPointer cdPtr,
- MemoryPointer mPtr
- ) internal pure {
- // Copy the full OrderParameters head from calldata to memory.
- cdPtr.copy(mPtr, OrderParameters_head_size);
-
- // Resolve the offer calldata offset, use that to decode and copy offer
- // from calldata, and write resultant memory offset to head in memory.
- mPtr.offset(OrderParameters_offer_head_offset).write(
- _decodeOffer(cdPtr.pptr(OrderParameters_offer_head_offset))
- );
-
- // Resolve consideration calldata offset, use that to copy consideration
- // from calldata, and write resultant memory offset to head in memory.
- mPtr.offset(OrderParameters_consideration_head_offset).write(
- _decodeConsideration(
- cdPtr.pptr(OrderParameters_consideration_head_offset)
- )
- );
- }
-
- /**
- * @dev Takes a calldata pointer to an OrderParameters struct and copies the
- * decoded struct to memory.
- *
- * @param cdPtr A calldata pointer for the OrderParameters struct.
- *
- * @return mPtr A memory pointer to the OrderParameters struct head.
- */
- function _decodeOrderParameters(
- CalldataPointer cdPtr
- ) internal pure returns (MemoryPointer mPtr) {
- // Allocate required memory for the OrderParameters head (offer and
- // consideration are allocated independently).
- mPtr = malloc(OrderParameters_head_size);
-
- // Decode and copy the order parameters to the newly allocated memory.
- _decodeOrderParametersTo(cdPtr, mPtr);
- }
-
- /**
- * @dev Takes a calldata pointer to an Order struct and copies the decoded
- * struct to memory.
- *
- * @param cdPtr A calldata pointer for the Order struct.
- *
- * @return mPtr A memory pointer to the Order struct head.
- */
- function _decodeOrder(
- CalldataPointer cdPtr
- ) internal pure returns (MemoryPointer mPtr) {
- // Allocate required memory for the Order head (OrderParameters and
- // signature are allocated independently).
- mPtr = malloc(Order_head_size);
-
- // Resolve OrderParameters calldata offset, use it to decode and copy
- // from calldata, and write resultant memory offset to head in memory.
- mPtr.write(_decodeOrderParameters(cdPtr.pptr()));
-
- // Resolve signature calldata offset, use that to decode and copy from
- // calldata, and write resultant memory offset to head in memory.
- mPtr.offset(Order_signature_offset).write(
- _decodeBytes(cdPtr.pptr(Order_signature_offset))
- );
- }
-
- /**
- * @dev Takes a calldata pointer to an AdvancedOrder struct and copies the
- * decoded struct to memory.
- *
- * @param cdPtr A calldata pointer for the AdvancedOrder struct.
- *
- * @return mPtr A memory pointer to the AdvancedOrder struct head.
- */
- function _decodeAdvancedOrder(
- CalldataPointer cdPtr
- ) internal pure returns (MemoryPointer mPtr) {
- // Allocate memory for AdvancedOrder head and OrderParameters head.
- mPtr = malloc(AdvancedOrderPlusOrderParameters_head_size);
-
- // Use numerator + denominator calldata offset to decode and copy
- // from calldata and write resultant memory offset to head in memory.
- cdPtr.offset(AdvancedOrder_numerator_offset).copy(
- mPtr.offset(AdvancedOrder_numerator_offset),
- AdvancedOrder_fixed_segment_0
- );
-
- // Get pointer to memory immediately after advanced order.
- MemoryPointer mPtrParameters = mPtr.offset(AdvancedOrder_head_size);
-
- // Write pptr for advanced order parameters to memory.
- mPtr.write(mPtrParameters);
-
- // Resolve OrderParameters calldata pointer & write to allocated region.
- _decodeOrderParametersTo(cdPtr.pptr(), mPtrParameters);
-
- // Resolve signature calldata offset, use that to decode and copy from
- // calldata, and write resultant memory offset to head in memory.
- mPtr.offset(AdvancedOrder_signature_offset).write(
- _decodeBytes(cdPtr.pptr(AdvancedOrder_signature_offset))
- );
-
- // Resolve extraData calldata offset, use that to decode and copy from
- // calldata, and write resultant memory offset to head in memory.
- mPtr.offset(AdvancedOrder_extraData_offset).write(
- _decodeBytes(cdPtr.pptr(AdvancedOrder_extraData_offset))
- );
- }
-
- /**
- * @dev Allocates a single word of empty bytes in memory and returns the
- * pointer to that memory region.
- *
- * @return mPtr The memory pointer to the new empty word in memory.
- */
- function _getEmptyBytesOrArray()
- internal
- pure
- returns (MemoryPointer mPtr)
- {
- mPtr = malloc(OneWord);
- mPtr.write(0);
- }
-
- /**
- * @dev Takes a calldata pointer to an Order struct and copies the decoded
- * struct to memory as an AdvancedOrder.
- *
- * @param cdPtr A calldata pointer for the Order struct.
- *
- * @return mPtr A memory pointer to the AdvancedOrder struct head.
- */
- function _decodeOrderAsAdvancedOrder(
- CalldataPointer cdPtr
- ) internal pure returns (MemoryPointer mPtr) {
- // Allocate memory for AdvancedOrder head and OrderParameters head.
- mPtr = malloc(AdvancedOrderPlusOrderParameters_head_size);
-
- // Get pointer to memory immediately after advanced order.
- MemoryPointer mPtrParameters = mPtr.offset(AdvancedOrder_head_size);
-
- // Write pptr for advanced order parameters.
- mPtr.write(mPtrParameters);
-
- // Resolve OrderParameters calldata pointer & write to allocated region.
- _decodeOrderParametersTo(cdPtr.pptr(), mPtrParameters);
-
- // Write default Order numerator and denominator values (i.e. 1/1).
- mPtr.offset(AdvancedOrder_numerator_offset).write(1);
- mPtr.offset(AdvancedOrder_denominator_offset).write(1);
-
- // Resolve signature calldata offset, use that to decode and copy from
- // calldata, and write resultant memory offset to head in memory.
- mPtr.offset(AdvancedOrder_signature_offset).write(
- _decodeBytes(cdPtr.pptr(Order_signature_offset))
- );
-
- // Resolve extraData calldata offset, use that to decode and copy from
- // calldata, and write resultant memory offset to head in memory.
- mPtr.offset(AdvancedOrder_extraData_offset).write(
- _getEmptyBytesOrArray()
- );
- }
-
- /**
- * @dev Takes a calldata pointer to an array of Order structs and copies the
- * decoded array to memory as an array of AdvancedOrder structs.
- *
- * @param cdPtrLength A calldata pointer to the start of the orders array in
- * calldata which contains the length of the array.
- *
- * @return mPtrLength A memory pointer to the start of the array of advanced
- * orders in memory which contains length of the array.
- */
- function _decodeOrdersAsAdvancedOrders(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- // Retrieve length of array, masking to prevent potential overflow.
- uint256 arrLength = cdPtrLength.readMaskedUint256();
-
- unchecked {
- // Derive offset to the tail based on one word per array element.
- uint256 tailOffset = arrLength << OneWordShift;
-
- // Add one additional word for the length and allocate memory.
- mPtrLength = malloc(tailOffset + OneWord);
-
- // Write the length of the array to memory.
- mPtrLength.write(arrLength);
-
- // Advance to first memory & calldata pointers (e.g. after length).
- MemoryPointer mPtrHead = mPtrLength.next();
- CalldataPointer cdPtrHead = cdPtrLength.next();
-
- // Iterate over each pointer, word by word, until tail is reached.
- for (uint256 offset = 0; offset < tailOffset; offset += OneWord) {
- // Resolve Order calldata offset, use it to decode and copy from
- // calldata, and write resultant AdvancedOrder offset to memory.
- mPtrHead.offset(offset).write(
- _decodeOrderAsAdvancedOrder(cdPtrHead.pptr(offset))
- );
- }
- }
- }
-
- /**
- * @dev Takes a calldata pointer to a criteria proof, or an array bytes32
- * types, and copies the decoded proof to memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the criteria proof
- * in calldata which contains the length of the array.
- *
- * @return mPtrLength A memory pointer to the start of the criteria proof
- * in memory which contains length of the array.
- */
- function _decodeCriteriaProof(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- // Retrieve length of array, masking to prevent potential overflow.
- uint256 arrLength = cdPtrLength.readMaskedUint256();
-
- unchecked {
- // Derive array size based on one word per array element and length.
- uint256 arrSize = (arrLength + 1) << OneWordShift;
-
- // Allocate memory equal to the array size.
- mPtrLength = malloc(arrSize);
-
- // Copy the array from calldata into memory.
- cdPtrLength.copy(mPtrLength, arrSize);
- }
- }
-
- /**
- * @dev Takes a calldata pointer to a CriteriaResolver struct and copies the
- * decoded struct to memory.
- *
- * @param cdPtr A calldata pointer for the CriteriaResolver struct.
- *
- * @return mPtr A memory pointer to the CriteriaResolver struct head.
- */
- function _decodeCriteriaResolver(
- CalldataPointer cdPtr
- ) internal pure returns (MemoryPointer mPtr) {
- // Allocate required memory for the CriteriaResolver head (the criteria
- // proof bytes32 array is allocated independently).
- mPtr = malloc(CriteriaResolver_head_size);
-
- // Decode and copy order index, side, index, and identifier from
- // calldata and write resultant memory offset to head in memory.
- cdPtr.copy(mPtr, CriteriaResolver_fixed_segment_0);
-
- // Resolve criteria proof calldata offset, use it to decode and copy
- // from calldata, and write resultant memory offset to head in memory.
- mPtr.offset(CriteriaResolver_criteriaProof_offset).write(
- _decodeCriteriaProof(
- cdPtr.pptr(CriteriaResolver_criteriaProof_offset)
- )
- );
- }
-
- /**
- * @dev Takes an array of criteria resolvers from calldata and copies it
- * into memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the criteria
- * resolver array in calldata which contains the length
- * of the array.
- *
- * @return mPtrLength A memory pointer to the start of the criteria resolver
- * array in memory which contains the length of the
- * array.
- */
- function _decodeCriteriaResolvers(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- // Retrieve length of array, masking to prevent potential overflow.
- uint256 arrLength = cdPtrLength.readMaskedUint256();
-
- unchecked {
- // Derive offset to the tail based on one word per array element.
- uint256 tailOffset = arrLength << OneWordShift;
-
- // Add one additional word for the length and allocate memory.
- mPtrLength = malloc(tailOffset + OneWord);
-
- // Write the length of the array to memory.
- mPtrLength.write(arrLength);
-
- // Advance to first memory & calldata pointers (e.g. after length).
- MemoryPointer mPtrHead = mPtrLength.next();
- CalldataPointer cdPtrHead = cdPtrLength.next();
-
- // Iterate over each pointer, word by word, until tail is reached.
- for (uint256 offset = 0; offset < tailOffset; offset += OneWord) {
- // Resolve CriteriaResolver calldata offset, use it to decode
- // and copy from calldata, and write resultant memory offset.
- mPtrHead.offset(offset).write(
- _decodeCriteriaResolver(cdPtrHead.pptr(offset))
- );
- }
- }
- }
-
- /**
- * @dev Takes an array of orders from calldata and copies it into memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the orders array in
- * calldata which contains the length of the array.
- *
- * @return mPtrLength A memory pointer to the start of the orders array
- * in memory which contains the length of the array.
- */
- function _decodeOrders(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- // Retrieve length of array, masking to prevent potential overflow.
- uint256 arrLength = cdPtrLength.readMaskedUint256();
-
- unchecked {
- // Derive offset to the tail based on one word per array element.
- uint256 tailOffset = arrLength << OneWordShift;
-
- // Add one additional word for the length and allocate memory.
- mPtrLength = malloc(tailOffset + OneWord);
-
- // Write the length of the array to memory.
- mPtrLength.write(arrLength);
-
- // Advance to first memory & calldata pointers (e.g. after length).
- MemoryPointer mPtrHead = mPtrLength.next();
- CalldataPointer cdPtrHead = cdPtrLength.next();
-
- // Iterate over each pointer, word by word, until tail is reached.
- for (uint256 offset = 0; offset < tailOffset; offset += OneWord) {
- // Resolve Order calldata offset, use it to decode and copy
- // from calldata, and write resultant memory offset.
- mPtrHead.offset(offset).write(
- _decodeOrder(cdPtrHead.pptr(offset))
- );
- }
- }
- }
-
- /**
- * @dev Takes an array of fulfillment components from calldata and copies it
- * into memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the fulfillment
- * components array in calldata which contains the length
- * of the array.
- *
- * @return mPtrLength A memory pointer to the start of the fulfillment
- * components array in memory which contains the length
- * of the array.
- */
- function _decodeFulfillmentComponents(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- assembly {
- let arrLength := and(calldataload(cdPtrLength), OffsetOrLengthMask)
-
- // Get the current free memory pointer.
- mPtrLength := mload(FreeMemoryPointerSlot)
-
- mstore(mPtrLength, arrLength)
- let mPtrHead := add(mPtrLength, OneWord)
- let mPtrTail := add(mPtrHead, shl(OneWordShift, arrLength))
- let mPtrTailNext := mPtrTail
- calldatacopy(
- mPtrTail,
- add(cdPtrLength, OneWord),
- shl(FulfillmentComponent_mem_tail_size_shift, arrLength)
- )
- let mPtrHeadNext := mPtrHead
- for {
-
- } lt(mPtrHeadNext, mPtrTail) {
-
- } {
- mstore(mPtrHeadNext, mPtrTailNext)
- mPtrHeadNext := add(mPtrHeadNext, OneWord)
- mPtrTailNext := add(
- mPtrTailNext,
- FulfillmentComponent_mem_tail_size
- )
- }
-
- // Update the free memory pointer.
- mstore(FreeMemoryPointerSlot, mPtrTailNext)
- }
- }
-
- /**
- * @dev Takes a nested array of fulfillment components from calldata and
- * copies it into memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the nested
- * fulfillment components array in calldata which
- * contains the length of the array.
- *
- * @return mPtrLength A memory pointer to the start of the nested
- * fulfillment components array in memory which
- * contains the length of the array.
- */
- function _decodeNestedFulfillmentComponents(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- // Retrieve length of array, masking to prevent potential overflow.
- uint256 arrLength = cdPtrLength.readMaskedUint256();
-
- unchecked {
- // Derive offset to the tail based on one word per array element.
- uint256 tailOffset = arrLength << OneWordShift;
-
- // Add one additional word for the length and allocate memory.
- mPtrLength = malloc(tailOffset + OneWord);
-
- // Write the length of the array to memory.
- mPtrLength.write(arrLength);
-
- // Advance to first memory & calldata pointers (e.g. after length).
- MemoryPointer mPtrHead = mPtrLength.next();
- CalldataPointer cdPtrHead = cdPtrLength.next();
-
- // Iterate over each pointer, word by word, until tail is reached.
- for (uint256 offset = 0; offset < tailOffset; offset += OneWord) {
- // Resolve FulfillmentComponents array calldata offset, use it
- // to decode and copy from calldata, and write memory offset.
- mPtrHead.offset(offset).write(
- _decodeFulfillmentComponents(cdPtrHead.pptr(offset))
- );
- }
- }
- }
-
- /**
- * @dev Takes an array of advanced orders from calldata and copies it into
- * memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the advanced orders
- * array in calldata which contains the length of the
- * array.
- *
- * @return mPtrLength A memory pointer to the start of the advanced orders
- * array in memory which contains the length of the
- * array.
- */
- function _decodeAdvancedOrders(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- // Retrieve length of array, masking to prevent potential overflow.
- uint256 arrLength = cdPtrLength.readMaskedUint256();
-
- unchecked {
- // Derive offset to the tail based on one word per array element.
- uint256 tailOffset = arrLength << OneWordShift;
-
- // Add one additional word for the length and allocate memory.
- mPtrLength = malloc(tailOffset + OneWord);
-
- // Write the length of the array to memory.
- mPtrLength.write(arrLength);
-
- // Advance to first memory & calldata pointers (e.g. after length).
- MemoryPointer mPtrHead = mPtrLength.next();
- CalldataPointer cdPtrHead = cdPtrLength.next();
-
- // Iterate over each pointer, word by word, until tail is reached.
- for (uint256 offset = 0; offset < tailOffset; offset += OneWord) {
- // Resolve AdvancedOrder calldata offset, use it to decode and
- // copy from calldata, and write resultant memory offset.
- mPtrHead.offset(offset).write(
- _decodeAdvancedOrder(cdPtrHead.pptr(offset))
- );
- }
- }
- }
-
- /**
- * @dev Takes a calldata pointer to a Fulfillment struct and copies the
- * decoded struct to memory.
- *
- * @param cdPtr A calldata pointer for the Fulfillment struct.
- *
- * @return mPtr A memory pointer to the Fulfillment struct head.
- */
- function _decodeFulfillment(
- CalldataPointer cdPtr
- ) internal pure returns (MemoryPointer mPtr) {
- // Allocate required memory for the Fulfillment head (the fulfillment
- // components arrays are allocated independently).
- mPtr = malloc(Fulfillment_head_size);
-
- // Resolve offerComponents calldata offset, use it to decode and copy
- // from calldata, and write resultant memory offset to head in memory.
- mPtr.write(_decodeFulfillmentComponents(cdPtr.pptr()));
-
- // Resolve considerationComponents calldata offset, use it to decode and
- // copy from calldata, and write resultant memory offset to memory head.
- mPtr.offset(Fulfillment_considerationComponents_offset).write(
- _decodeFulfillmentComponents(
- cdPtr.pptr(Fulfillment_considerationComponents_offset)
- )
- );
- }
-
- /**
- * @dev Takes an array of fulfillments from calldata and copies it into
- * memory.
- *
- * @param cdPtrLength A calldata pointer to the start of the fulfillments
- * array in calldata which contains the length of the
- * array.
- *
- * @return mPtrLength A memory pointer to the start of the fulfillments
- * array in memory which contains the length of the
- * array.
- */
- function _decodeFulfillments(
- CalldataPointer cdPtrLength
- ) internal pure returns (MemoryPointer mPtrLength) {
- // Retrieve length of array, masking to prevent potential overflow.
- uint256 arrLength = cdPtrLength.readMaskedUint256();
-
- unchecked {
- // Derive offset to the tail based on one word per array element.
- uint256 tailOffset = arrLength << OneWordShift;
-
- // Add one additional word for the length and allocate memory.
- mPtrLength = malloc(tailOffset + OneWord);
-
- // Write the length of the array to memory.
- mPtrLength.write(arrLength);
-
- // Advance to first memory & calldata pointers (e.g. after length).
- MemoryPointer mPtrHead = mPtrLength.next();
- CalldataPointer cdPtrHead = cdPtrLength.next();
-
- // Iterate over each pointer, word by word, until tail is reached.
- for (uint256 offset = 0; offset < tailOffset; offset += OneWord) {
- // Resolve Fulfillment calldata offset, use it to decode and
- // copy from calldata, and write resultant memory offset.
- mPtrHead.offset(offset).write(
- _decodeFulfillment(cdPtrHead.pptr(offset))
- );
- }
- }
- }
-
- /**
- * @dev Takes a calldata pointer to an OrderComponents struct and copies the
- * decoded struct to memory as an OrderParameters struct (with the
- * totalOriginalConsiderationItems value set equal to the length of the
- * supplied consideration array).
- *
- * @param cdPtr A calldata pointer for the OrderComponents struct.
- *
- * @return mPtr A memory pointer to the OrderParameters struct head.
- */
- function _decodeOrderComponentsAsOrderParameters(
- CalldataPointer cdPtr
- ) internal pure returns (MemoryPointer mPtr) {
- // Allocate memory for the OrderParameters head.
- mPtr = malloc(OrderParameters_head_size);
-
- // Copy the full OrderComponents head from calldata to memory.
- cdPtr.copy(mPtr, OrderComponents_OrderParameters_common_head_size);
-
- // Resolve the offer calldata offset, use that to decode and copy offer
- // from calldata, and write resultant memory offset to head in memory.
- mPtr.offset(OrderParameters_offer_head_offset).write(
- _decodeOffer(cdPtr.pptr(OrderParameters_offer_head_offset))
- );
-
- // Resolve consideration calldata offset, use that to copy consideration
- // from calldata, and write resultant memory offset to head in memory.
- MemoryPointer consideration = _decodeConsideration(
- cdPtr.pptr(OrderParameters_consideration_head_offset)
- );
- mPtr.offset(OrderParameters_consideration_head_offset).write(
- consideration
- );
-
- // Write masked consideration length to totalOriginalConsiderationItems.
- mPtr
- .offset(OrderParameters_totalOriginalConsiderationItems_offset)
- .write(consideration.readUint256());
- }
-
- /**
- * @dev Decodes the returndata from a call to generateOrder, or returns
- * empty arrays and a boolean signifying that the returndata does not
- * adhere to a valid encoding scheme if it cannot be decoded.
- *
- * @return invalidEncoding A boolean signifying whether the returndata has
- * an invalid encoding.
- * @return offer The decoded offer array.
- * @return consideration The decoded consideration array.
- */
- function _decodeGenerateOrderReturndata()
- internal
- pure
- returns (
- uint256 invalidEncoding,
- MemoryPointer offer,
- MemoryPointer consideration
- )
- {
- assembly {
- // Check that returndatasize is at least four words: offerOffset,
- // considerationOffset, offerLength, & considerationLength
- invalidEncoding := lt(returndatasize(), FourWords)
-
- let offsetOffer
- let offsetConsideration
- let offerLength
- let considerationLength
-
- // Proceed if enough returndata is present to continue evaluation.
- if iszero(invalidEncoding) {
- // Copy first two words of returndata (the offsets to offer and
- // consideration array lengths) to scratch space.
- returndatacopy(0, 0, TwoWords)
- offsetOffer := mload(0)
- offsetConsideration := mload(OneWord)
-
- // If valid length, check that offsets are within returndata.
- let invalidOfferOffset := gt(offsetOffer, returndatasize())
- let invalidConsiderationOffset := gt(
- offsetConsideration,
- returndatasize()
- )
-
- // Only proceed if length (and thus encoding) is valid so far.
- invalidEncoding := or(
- invalidOfferOffset,
- invalidConsiderationOffset
- )
- if iszero(invalidEncoding) {
- // Copy length of offer array to scratch space.
- returndatacopy(0, offsetOffer, OneWord)
- offerLength := mload(0)
-
- // Copy length of consideration array to scratch space.
- returndatacopy(OneWord, offsetConsideration, OneWord)
- considerationLength := mload(OneWord)
-
- {
- // Calculate total size of offer & consideration arrays.
- let totalOfferSize := shl(
- SpentItem_size_shift,
- offerLength
- )
- let totalConsiderationSize := mul(
- ReceivedItem_size,
- considerationLength
- )
-
- // Add 4 words to total size to cover the offset and
- // length fields of the two arrays.
- let totalSize := add(
- FourWords,
- add(totalOfferSize, totalConsiderationSize)
- )
- // Don't continue if returndatasize exceeds 65535 bytes
- // or is greater than the calculated size.
- invalidEncoding := or(
- gt(
- or(offerLength, considerationLength),
- generateOrder_maximum_returndatasize
- ),
- gt(totalSize, returndatasize())
- )
-
- // Set first word of scratch space to 0 so length of
- // offer/consideration are set to 0 on invalid encoding.
- mstore(0, 0)
- }
- }
- }
-
- if iszero(invalidEncoding) {
- offer := copySpentItemsAsOfferItems(
- add(offsetOffer, OneWord),
- offerLength
- )
-
- consideration := copyReceivedItemsAsConsiderationItems(
- add(offsetConsideration, OneWord),
- considerationLength
- )
- }
-
- function copySpentItemsAsOfferItems(rdPtrHead, length)
- -> mPtrLength
- {
- // Retrieve the current free memory pointer.
- mPtrLength := mload(FreeMemoryPointerSlot)
-
- // Allocate memory for the array.
- mstore(
- FreeMemoryPointerSlot,
- add(
- mPtrLength,
- add(OneWord, mul(length, OfferItem_size_with_length))
- )
- )
-
- // Write the length of the array to the start of free memory.
- mstore(mPtrLength, length)
-
- // Use offset from length to minimize stack depth.
- let headOffsetFromLength := OneWord
- let headSizeWithLength := shl(OneWordShift, add(1, length))
- let mPtrTailNext := add(mPtrLength, headSizeWithLength)
-
- // Iterate over each element.
- for {
-
- } lt(headOffsetFromLength, headSizeWithLength) {
-
- } {
- // Write the memory pointer to the accompanying head offset.
- mstore(add(mPtrLength, headOffsetFromLength), mPtrTailNext)
-
- // Copy itemType, token, identifier and amount.
- returndatacopy(mPtrTailNext, rdPtrHead, SpentItem_size)
-
- // Copy amount to endAmount.
- mstore(
- add(mPtrTailNext, Common_endAmount_offset),
- mload(add(mPtrTailNext, Common_amount_offset))
- )
-
- // Update read pointer, next tail pointer, and head offset.
- rdPtrHead := add(rdPtrHead, SpentItem_size)
- mPtrTailNext := add(mPtrTailNext, OfferItem_size)
- headOffsetFromLength := add(headOffsetFromLength, OneWord)
- }
- }
-
- function copyReceivedItemsAsConsiderationItems(rdPtrHead, length)
- -> mPtrLength
- {
- // Retrieve the current free memory pointer.
- mPtrLength := mload(FreeMemoryPointerSlot)
-
- // Allocate memory for the array.
- mstore(
- FreeMemoryPointerSlot,
- add(
- mPtrLength,
- add(
- OneWord,
- mul(length, ConsiderationItem_size_with_length)
- )
- )
- )
-
- // Write the length of the array to the start of free memory.
- mstore(mPtrLength, length)
-
- // Use offset from length to minimize stack depth.
- let headOffsetFromLength := OneWord
- let headSizeWithLength := shl(OneWordShift, add(1, length))
- let mPtrTailNext := add(mPtrLength, headSizeWithLength)
-
- // Iterate over each element.
- for {
-
- } lt(headOffsetFromLength, headSizeWithLength) {
-
- } {
- // Write the memory pointer to the accompanying head offset.
- mstore(add(mPtrLength, headOffsetFromLength), mPtrTailNext)
-
- // Copy itemType, token, identifier and amount.
- returndatacopy(
- mPtrTailNext,
- rdPtrHead,
- ReceivedItem_size_excluding_recipient
- )
-
- // Copy amount and recipient.
- returndatacopy(
- add(mPtrTailNext, Common_endAmount_offset),
- add(rdPtrHead, Common_amount_offset),
- TwoWords
- )
-
- // Update read pointer, next tail pointer, and head offset.
- rdPtrHead := add(rdPtrHead, ReceivedItem_size)
- mPtrTailNext := add(mPtrTailNext, ConsiderationItem_size)
- headOffsetFromLength := add(headOffsetFromLength, OneWord)
- }
- }
- }
- }
-
- /**
- * @dev Converts a function returning _decodeGenerateOrderReturndata types
- * into a function returning offer and consideration types.
- *
- * @param inFn The input function, taking no arguments and returning an
- * error buffer, spent item array, and received item array.
- *
- * @return outFn The output function, taking no arguments and returning an
- * error buffer, offer array, and consideration array.
- */
- function _convertGetGeneratedOrderResult(
- function()
- internal
- pure
- returns (uint256, MemoryPointer, MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function()
- internal
- pure
- returns (
- uint256,
- OfferItem[] memory,
- ConsiderationItem[] memory
- ) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking ReceivedItem, address, bytes32, and bytes
- * types (e.g. the _transfer function) into a function taking
- * OfferItem, address, bytes32, and bytes types.
- *
- * @param inFn The input function, taking ReceivedItem, address, bytes32,
- * and bytes types (e.g. the _transfer function).
- *
- * @return outFn The output function, taking OfferItem, address, bytes32,
- * and bytes types.
- */
- function _toOfferItemInput(
- function(ReceivedItem memory, address, bytes32, bytes memory)
- internal inFn
- )
- internal
- pure
- returns (
- function(OfferItem memory, address, bytes32, bytes memory)
- internal outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking ReceivedItem, address, bytes32, and bytes
- * types (e.g. the _transfer function) into a function taking
- * ConsiderationItem, address, bytes32, and bytes types.
- *
- * @param inFn The input function, taking ReceivedItem, address, bytes32,
- * and bytes types (e.g. the _transfer function).
- *
- * @return outFn The output function, taking ConsiderationItem, address,
- * bytes32, and bytes types.
- */
- function _toConsiderationItemInput(
- function(ReceivedItem memory, address, bytes32, bytes memory)
- internal inFn
- )
- internal
- pure
- returns (
- function(ConsiderationItem memory, address, bytes32, bytes memory)
- internal outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking a calldata pointer and returning a memory
- * pointer into a function taking that calldata pointer and returning
- * an OrderParameters type.
- *
- * @param inFn The input function, taking an arbitrary calldata pointer and
- * returning an arbitrary memory pointer.
- *
- * @return outFn The output function, taking an arbitrary calldata pointer
- * and returning an OrderParameters type.
- */
- function _toOrderParametersReturnType(
- function(CalldataPointer) internal pure returns (MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function(CalldataPointer)
- internal
- pure
- returns (OrderParameters memory) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking a calldata pointer and returning a memory
- * pointer into a function taking that calldata pointer and returning
- * an AdvancedOrder type.
- *
- * @param inFn The input function, taking an arbitrary calldata pointer and
- * returning an arbitrary memory pointer.
- *
- * @return outFn The output function, taking an arbitrary calldata pointer
- * and returning an AdvancedOrder type.
- */
- function _toAdvancedOrderReturnType(
- function(CalldataPointer) internal pure returns (MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function(CalldataPointer)
- internal
- pure
- returns (AdvancedOrder memory) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking a calldata pointer and returning a memory
- * pointer into a function taking that calldata pointer and returning
- * a dynamic array of CriteriaResolver types.
- *
- * @param inFn The input function, taking an arbitrary calldata pointer and
- * returning an arbitrary memory pointer.
- *
- * @return outFn The output function, taking an arbitrary calldata pointer
- * and returning a dynamic array of CriteriaResolver types.
- */
- function _toCriteriaResolversReturnType(
- function(CalldataPointer) internal pure returns (MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function(CalldataPointer)
- internal
- pure
- returns (CriteriaResolver[] memory) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking a calldata pointer and returning a memory
- * pointer into a function taking that calldata pointer and returning
- * a dynamic array of Order types.
- *
- * @param inFn The input function, taking an arbitrary calldata pointer and
- * returning an arbitrary memory pointer.
- *
- * @return outFn The output function, taking an arbitrary calldata pointer
- * and returning a dynamic array of Order types.
- */
- function _toOrdersReturnType(
- function(CalldataPointer) internal pure returns (MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function(CalldataPointer)
- internal
- pure
- returns (Order[] memory) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking a calldata pointer and returning a memory
- * pointer into a function taking that calldata pointer and returning
- * a nested dynamic array of dynamic arrays of FulfillmentComponent
- * types.
- *
- * @param inFn The input function, taking an arbitrary calldata pointer and
- * returning an arbitrary memory pointer.
- *
- * @return outFn The output function, taking an arbitrary calldata pointer
- * and returning a nested dynamic array of dynamic arrays of
- * FulfillmentComponent types.
- */
- function _toNestedFulfillmentComponentsReturnType(
- function(CalldataPointer) internal pure returns (MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function(CalldataPointer)
- internal
- pure
- returns (FulfillmentComponent[][] memory) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking a calldata pointer and returning a memory
- * pointer into a function taking that calldata pointer and returning
- * a dynamic array of AdvancedOrder types.
- *
- * @param inFn The input function, taking an arbitrary calldata pointer and
- * returning an arbitrary memory pointer.
- *
- * @return outFn The output function, taking an arbitrary calldata pointer
- * and returning a dynamic array of AdvancedOrder types.
- */
- function _toAdvancedOrdersReturnType(
- function(CalldataPointer) internal pure returns (MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function(CalldataPointer)
- internal
- pure
- returns (AdvancedOrder[] memory) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Converts a function taking a calldata pointer and returning a memory
- * pointer into a function taking that calldata pointer and returning
- * a dynamic array of Fulfillment types.
- *
- * @param inFn The input function, taking an arbitrary calldata pointer and
- * returning an arbitrary memory pointer.
- *
- * @return outFn The output function, taking an arbitrary calldata pointer
- * and returning a dynamic array of Fulfillment types.
- */
- function _toFulfillmentsReturnType(
- function(CalldataPointer) internal pure returns (MemoryPointer) inFn
- )
- internal
- pure
- returns (
- function(CalldataPointer)
- internal
- pure
- returns (Fulfillment[] memory) outFn
- )
- {
- assembly {
- outFn := inFn
- }
- }
-
- /**
- * @dev Caches the endAmount in an offer item and replaces it with
- * a given recipient so that its memory may be reused as a temporary
- * ReceivedItem.
- *
- * @param offerItem The offer item.
- * @param recipient The recipient.
- *
- * @return originalEndAmount The original end amount.
- */
- function _replaceEndAmountWithRecipient(
- OfferItem memory offerItem,
- address recipient
- ) internal pure returns (uint256 originalEndAmount) {
- assembly {
- // Derive the pointer to the end amount on the offer item.
- let endAmountPtr := add(offerItem, ReceivedItem_recipient_offset)
-
- // Retrieve the value of the end amount on the offer item.
- originalEndAmount := mload(endAmountPtr)
-
- // Write recipient to received item at the offer end amount pointer.
- mstore(endAmountPtr, recipient)
- }
- }
-}
diff --git a/contracts/lib/ConsiderationEncoder.sol b/contracts/lib/ConsiderationEncoder.sol
deleted file mode 100644
index cf74ed796..000000000
--- a/contracts/lib/ConsiderationEncoder.sol
+++ /dev/null
@@ -1,746 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- BasicOrder_additionalRecipients_length_cdPtr,
- BasicOrder_common_params_size,
- BasicOrder_startTime_cdPtr,
- BasicOrder_startTimeThroughZoneHash_size,
- Common_amount_offset,
- Common_identifier_offset,
- Common_token_offset,
- generateOrder_base_tail_offset,
- generateOrder_context_head_offset,
- generateOrder_head_offset,
- generateOrder_maximumSpent_head_offset,
- generateOrder_minimumReceived_head_offset,
- generateOrder_selector_offset,
- generateOrder_selector,
- OneWord,
- OneWordShift,
- OnlyFullWordMask,
- OrderFulfilled_baseDataSize,
- OrderFulfilled_offer_length_baseOffset,
- OrderParameters_consideration_head_offset,
- OrderParameters_endTime_offset,
- OrderParameters_offer_head_offset,
- OrderParameters_startTime_offset,
- OrderParameters_zoneHash_offset,
- ratifyOrder_base_tail_offset,
- ratifyOrder_consideration_head_offset,
- ratifyOrder_context_head_offset,
- ratifyOrder_contractNonce_offset,
- ratifyOrder_head_offset,
- ratifyOrder_orderHashes_head_offset,
- ratifyOrder_selector_offset,
- ratifyOrder_selector,
- ReceivedItem_size,
- Selector_length,
- SixtyThreeBytes,
- SpentItem_size_shift,
- SpentItem_size,
- validateOrder_head_offset,
- validateOrder_selector_offset,
- validateOrder_selector,
- validateOrder_zoneParameters_offset,
- ZoneParameters_base_tail_offset,
- ZoneParameters_basicOrderFixedElements_length,
- ZoneParameters_consideration_head_offset,
- ZoneParameters_endTime_offset,
- ZoneParameters_extraData_head_offset,
- ZoneParameters_fulfiller_offset,
- ZoneParameters_offer_head_offset,
- ZoneParameters_offerer_offset,
- ZoneParameters_orderHashes_head_offset,
- ZoneParameters_selectorAndPointer_length,
- ZoneParameters_startTime_offset,
- ZoneParameters_zoneHash_offset
-} from "./ConsiderationConstants.sol";
-
-import {
- BasicOrderParameters,
- OrderParameters
-} from "./ConsiderationStructs.sol";
-
-import {
- CalldataPointer,
- getFreeMemoryPointer,
- MemoryPointer
-} from "../helpers/PointerLibraries.sol";
-
-contract ConsiderationEncoder {
- /**
- * @dev Takes a bytes array and casts it to a memory pointer.
- *
- * @param obj A bytes array in memory.
- *
- * @return ptr A memory pointer to the start of the bytes array in memory.
- */
- function toMemoryPointer(
- bytes memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Takes an array of bytes32 types and casts it to a memory pointer.
- *
- * @param obj An array of bytes32 types in memory.
- *
- * @return ptr A memory pointer to the start of the array of bytes32 types
- * in memory.
- */
- function toMemoryPointer(
- bytes32[] memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Takes a bytes array in memory and copies it to a new location in
- * memory.
- *
- * @param src A memory pointer referencing the bytes array to be copied (and
- * pointing to the length of the bytes array).
- * @param src A memory pointer referencing the location in memory to copy
- * the bytes array to (and pointing to the length of the copied
- * bytes array).
- *
- * @return size The size of the bytes array.
- */
- function _encodeBytes(
- MemoryPointer src,
- MemoryPointer dst
- ) internal view returns (uint256 size) {
- unchecked {
- // Mask the length of the bytes array to protect against overflow
- // and round up to the nearest word.
- // Note: `size` also includes the 1 word that stores the length.
- size = (src.readUint256() + SixtyThreeBytes) & OnlyFullWordMask;
-
- // Copy the bytes array to the new memory location.
- src.copy(dst, size);
- }
- }
-
- /**
- * @dev Takes an OrderParameters struct and a context bytes array in memory
- * and encodes it as `generateOrder` calldata.
- *
- * @param orderParameters The OrderParameters struct used to construct the
- * encoded `generateOrder` calldata.
- * @param context The context bytes array used to construct the
- * encoded `generateOrder` calldata.
- *
- * @return dst A memory pointer referencing the encoded `generateOrder`
- * calldata.
- * @return size The size of the bytes array.
- */
- function _encodeGenerateOrder(
- OrderParameters memory orderParameters,
- bytes memory context
- ) internal view returns (MemoryPointer dst, uint256 size) {
- // Get the memory pointer for the OrderParameters struct.
- MemoryPointer src = orderParameters.toMemoryPointer();
-
- // Get free memory pointer to write calldata to.
- dst = getFreeMemoryPointer();
-
- // Write generateOrder selector and get pointer to start of calldata.
- dst.write(generateOrder_selector);
- dst = dst.offset(generateOrder_selector_offset);
-
- // Get pointer to the beginning of the encoded data.
- MemoryPointer dstHead = dst.offset(generateOrder_head_offset);
-
- // Write `fulfiller` to calldata.
- dstHead.write(msg.sender);
-
- // Initialize tail offset, used to populate the minimumReceived array.
- uint256 tailOffset = generateOrder_base_tail_offset;
-
- // Write offset to minimumReceived.
- dstHead.offset(generateOrder_minimumReceived_head_offset).write(
- tailOffset
- );
-
- // Get memory pointer to `orderParameters.offer.length`.
- MemoryPointer srcOfferPointer = src
- .offset(OrderParameters_offer_head_offset)
- .readMemoryPointer();
-
- // Encode the offer array as a `SpentItem[]`.
- uint256 minimumReceivedSize = _encodeSpentItems(
- srcOfferPointer,
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate maximumSpent array.
- tailOffset += minimumReceivedSize;
- }
-
- // Write offset to maximumSpent.
- dstHead.offset(generateOrder_maximumSpent_head_offset).write(
- tailOffset
- );
-
- // Get memory pointer to `orderParameters.consideration.length`.
- MemoryPointer srcConsiderationPointer = src
- .offset(OrderParameters_consideration_head_offset)
- .readMemoryPointer();
-
- // Encode the consideration array as a `SpentItem[]`.
- uint256 maximumSpentSize = _encodeSpentItems(
- srcConsiderationPointer,
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate context array.
- tailOffset += maximumSpentSize;
- }
-
- // Write offset to context.
- dstHead.offset(generateOrder_context_head_offset).write(tailOffset);
-
- // Get memory pointer to context.
- MemoryPointer srcContext = toMemoryPointer(context);
-
- // Encode context as a bytes array.
- uint256 contextSize = _encodeBytes(
- srcContext,
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment the tail offset, now used to determine final size.
- tailOffset += contextSize;
-
- // Derive the final size by including the selector.
- size = Selector_length + tailOffset;
- }
- }
-
- /**
- * @dev Takes an order hash (e.g. offerer shifted 96 bits to the left XOR'd
- * with the contract nonce in the case of contract orders), an
- * OrderParameters struct, context bytes array, and an array of order
- * hashes for each order included as part of the current fulfillment
- * and encodes it as `ratifyOrder` calldata.
- *
- * @param orderHash The order hash (e.g. shl(0x60, offerer) ^ nonce).
- * @param orderParameters The OrderParameters struct used to construct the
- * encoded `ratifyOrder` calldata.
- * @param context The context bytes array used to construct the
- * encoded `ratifyOrder` calldata.
- * @param orderHashes An array of bytes32 values representing the order
- * hashes of all orders included as part of the
- * current fulfillment.
- * @param shiftedOfferer The offerer for the order, shifted 96 bits to the
- * left.
- *
- * @return dst A memory pointer referencing the encoded `ratifyOrder`
- * calldata.
- * @return size The size of the bytes array.
- */
- function _encodeRatifyOrder(
- bytes32 orderHash, // e.g. shl(0x60, offerer) ^ contract nonce
- OrderParameters memory orderParameters,
- bytes memory context, // encoded based on the schemaID
- bytes32[] memory orderHashes,
- uint256 shiftedOfferer
- ) internal view returns (MemoryPointer dst, uint256 size) {
- // Get free memory pointer to write calldata to. This isn't allocated as
- // it is only used for a single function call.
- dst = getFreeMemoryPointer();
-
- // Write ratifyOrder selector and get pointer to start of calldata.
- dst.write(ratifyOrder_selector);
- dst = dst.offset(ratifyOrder_selector_offset);
-
- // Get pointer to the beginning of the encoded data.
- MemoryPointer dstHead = dst.offset(ratifyOrder_head_offset);
-
- // Write contractNonce to calldata via xor(orderHash, shiftedOfferer).
- dstHead.offset(ratifyOrder_contractNonce_offset).write(
- uint256(orderHash) ^ shiftedOfferer
- );
-
- // Initialize tail offset, used to populate the offer array.
- uint256 tailOffset = ratifyOrder_base_tail_offset;
- MemoryPointer src = orderParameters.toMemoryPointer();
-
- // Write offset to `offer`.
- dstHead.write(tailOffset);
-
- // Get memory pointer to `orderParameters.offer.length`.
- MemoryPointer srcOfferPointer = src
- .offset(OrderParameters_offer_head_offset)
- .readMemoryPointer();
-
- // Encode the offer array as a `SpentItem[]`.
- uint256 offerSize = _encodeSpentItems(
- srcOfferPointer,
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate consideration array.
- tailOffset += offerSize;
- }
-
- // Write offset to consideration.
- dstHead.offset(ratifyOrder_consideration_head_offset).write(tailOffset);
-
- // Get pointer to `orderParameters.consideration.length`.
- MemoryPointer srcConsiderationPointer = src
- .offset(OrderParameters_consideration_head_offset)
- .readMemoryPointer();
-
- // Encode the consideration array as a `ReceivedItem[]`.
- uint256 considerationSize = _encodeConsiderationAsReceivedItems(
- srcConsiderationPointer,
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate context array.
- tailOffset += considerationSize;
- }
-
- // Write offset to context.
- dstHead.offset(ratifyOrder_context_head_offset).write(tailOffset);
-
- // Encode context.
- uint256 contextSize = _encodeBytes(
- toMemoryPointer(context),
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate orderHashes array.
- tailOffset += contextSize;
- }
-
- // Write offset to orderHashes.
- dstHead.offset(ratifyOrder_orderHashes_head_offset).write(tailOffset);
-
- // Encode orderHashes.
- uint256 orderHashesSize = _encodeOrderHashes(
- toMemoryPointer(orderHashes),
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment the tail offset, now used to determine final size.
- tailOffset += orderHashesSize;
-
- // Derive the final size by including the selector.
- size = Selector_length + tailOffset;
- }
- }
-
- /**
- * @dev Takes an order hash, OrderParameters struct, extraData bytes array,
- * and array of order hashes for each order included as part of the
- * current fulfillment and encodes it as `validateOrder` calldata.
- * Note that future, new versions of this contract may end up writing
- * to a memory region that might have been potentially dirtied by the
- * accumulator. Since the book-keeping for the accumulator does not
- * update the free memory pointer, it will be necessary to ensure that
- * all bytes in the memory in the range [dst, dst+size) are fully
- * updated/written to in this function.
- *
- * @param orderHash The order hash.
- * @param orderParameters The OrderParameters struct used to construct the
- * encoded `validateOrder` calldata.
- * @param extraData The extraData bytes array used to construct the
- * encoded `validateOrder` calldata.
- * @param orderHashes An array of bytes32 values representing the order
- * hashes of all orders included as part of the
- * current fulfillment.
- *
- * @return dst A memory pointer referencing the encoded `validateOrder`
- * calldata.
- * @return size The size of the bytes array.
- */
- function _encodeValidateOrder(
- bytes32 orderHash,
- OrderParameters memory orderParameters,
- bytes memory extraData,
- bytes32[] memory orderHashes
- ) internal view returns (MemoryPointer dst, uint256 size) {
- // Get free memory pointer to write calldata to. This isn't allocated as
- // it is only used for a single function call.
- dst = getFreeMemoryPointer();
-
- // Write validateOrder selector and get pointer to start of calldata.
- dst.write(validateOrder_selector);
- dst = dst.offset(validateOrder_selector_offset);
-
- // Get pointer to the beginning of the encoded data.
- MemoryPointer dstHead = dst.offset(validateOrder_head_offset);
-
- // Write offset to zoneParameters to start of calldata.
- dstHead.write(validateOrder_zoneParameters_offset);
-
- // Reuse `dstHead` as pointer to zoneParameters.
- dstHead = dstHead.offset(validateOrder_zoneParameters_offset);
-
- // Write orderHash and fulfiller to zoneParameters.
- dstHead.writeBytes32(orderHash);
- dstHead.offset(ZoneParameters_fulfiller_offset).write(msg.sender);
-
- // Get the memory pointer to the order parameters struct.
- MemoryPointer src = orderParameters.toMemoryPointer();
-
- // Copy offerer, startTime, endTime and zoneHash to zoneParameters.
- dstHead.offset(ZoneParameters_offerer_offset).write(src.readUint256());
- dstHead.offset(ZoneParameters_startTime_offset).write(
- src.offset(OrderParameters_startTime_offset).readUint256()
- );
- dstHead.offset(ZoneParameters_endTime_offset).write(
- src.offset(OrderParameters_endTime_offset).readUint256()
- );
- dstHead.offset(ZoneParameters_zoneHash_offset).write(
- src.offset(OrderParameters_zoneHash_offset).readUint256()
- );
-
- // Initialize tail offset, used to populate the offer array.
- uint256 tailOffset = ZoneParameters_base_tail_offset;
-
- // Write offset to `offer`.
- dstHead.offset(ZoneParameters_offer_head_offset).write(tailOffset);
-
- // Get pointer to `orderParameters.offer.length`.
- MemoryPointer srcOfferPointer = src
- .offset(OrderParameters_offer_head_offset)
- .readMemoryPointer();
-
- // Encode the offer array as a `SpentItem[]`.
- uint256 offerSize = _encodeSpentItems(
- srcOfferPointer,
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate consideration array.
- tailOffset += offerSize;
- }
-
- // Write offset to consideration.
- dstHead.offset(ZoneParameters_consideration_head_offset).write(
- tailOffset
- );
-
- // Get pointer to `orderParameters.consideration.length`.
- MemoryPointer srcConsiderationPointer = src
- .offset(OrderParameters_consideration_head_offset)
- .readMemoryPointer();
-
- // Encode the consideration array as a `ReceivedItem[]`.
- uint256 considerationSize = _encodeConsiderationAsReceivedItems(
- srcConsiderationPointer,
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate extraData array.
- tailOffset += considerationSize;
- }
-
- // Write offset to extraData.
- dstHead.offset(ZoneParameters_extraData_head_offset).write(tailOffset);
- // Copy extraData.
- uint256 extraDataSize = _encodeBytes(
- toMemoryPointer(extraData),
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment tail offset, now used to populate orderHashes array.
- tailOffset += extraDataSize;
- }
-
- // Write offset to orderHashes.
- dstHead.offset(ZoneParameters_orderHashes_head_offset).write(
- tailOffset
- );
-
- // Encode the order hashes array.
- uint256 orderHashesSize = _encodeOrderHashes(
- toMemoryPointer(orderHashes),
- dstHead.offset(tailOffset)
- );
-
- unchecked {
- // Increment the tail offset, now used to determine final size.
- tailOffset += orderHashesSize;
-
- // Derive final size including selector and ZoneParameters pointer.
- size = ZoneParameters_selectorAndPointer_length + tailOffset;
- }
- }
-
- /**
- * @dev Takes an order hash and BasicOrderParameters struct (from calldata)
- * and encodes it as `validateOrder` calldata.
- *
- * @param orderHash The order hash.
- * @param parameters The BasicOrderParameters struct used to construct the
- * encoded `validateOrder` calldata.
- *
- * @return dst A memory pointer referencing the encoded `validateOrder`
- * calldata.
- * @return size The size of the bytes array.
- */
- function _encodeValidateBasicOrder(
- bytes32 orderHash,
- BasicOrderParameters calldata parameters
- ) internal view returns (MemoryPointer dst, uint256 size) {
- // Get free memory pointer to write calldata to. This isn't allocated as
- // it is only used for a single function call.
- dst = getFreeMemoryPointer();
-
- // Write validateOrder selector and get pointer to start of calldata.
- dst.write(validateOrder_selector);
- dst = dst.offset(validateOrder_selector_offset);
-
- // Get pointer to the beginning of the encoded data.
- MemoryPointer dstHead = dst.offset(validateOrder_head_offset);
-
- // Write offset to zoneParameters to start of calldata.
- dstHead.write(validateOrder_zoneParameters_offset);
-
- // Reuse `dstHead` as pointer to zoneParameters.
- dstHead = dstHead.offset(validateOrder_zoneParameters_offset);
-
- // Write offerer, orderHash and fulfiller to zoneParameters.
- dstHead.writeBytes32(orderHash);
- dstHead.offset(ZoneParameters_fulfiller_offset).write(msg.sender);
- dstHead.offset(ZoneParameters_offerer_offset).write(parameters.offerer);
-
- // Copy startTime, endTime and zoneHash to zoneParameters.
- CalldataPointer.wrap(BasicOrder_startTime_cdPtr).copy(
- dstHead.offset(ZoneParameters_startTime_offset),
- BasicOrder_startTimeThroughZoneHash_size
- );
-
- // Initialize tail offset, used for the offer + consideration arrays.
- uint256 tailOffset = ZoneParameters_base_tail_offset;
-
- // Write offset to offer from event data into target calldata.
- dstHead.offset(ZoneParameters_offer_head_offset).write(tailOffset);
-
- unchecked {
- // Write consideration offset next (located 5 words after offer).
- dstHead.offset(ZoneParameters_consideration_head_offset).write(
- tailOffset + BasicOrder_common_params_size
- );
-
- // Retrieve the offset to the length of additional recipients.
- uint256 additionalRecipientsLength = CalldataPointer
- .wrap(BasicOrder_additionalRecipients_length_cdPtr)
- .readUint256();
-
- // Derive offset to event data using base offset & total recipients.
- uint256 offerDataOffset = OrderFulfilled_offer_length_baseOffset +
- additionalRecipientsLength *
- OneWord;
-
- // Derive size of offer and consideration data.
- // 2 words (lengths) + 4 (offer data) + 5 (consideration 1) + 5 * ar
- uint256 offerAndConsiderationSize = OrderFulfilled_baseDataSize +
- (additionalRecipientsLength * ReceivedItem_size);
-
- // Copy offer and consideration data from event data to calldata.
- MemoryPointer.wrap(offerDataOffset).copy(
- dstHead.offset(tailOffset),
- offerAndConsiderationSize
- );
-
- // Increment tail offset, now used to populate extraData array.
- tailOffset += offerAndConsiderationSize;
- }
-
- // Write empty bytes for extraData.
- dstHead.offset(ZoneParameters_extraData_head_offset).write(tailOffset);
- dstHead.offset(tailOffset).write(0);
-
- unchecked {
- // Increment tail offset, now used to populate orderHashes array.
- tailOffset += OneWord;
- }
-
- // Write offset to orderHashes.
- dstHead.offset(ZoneParameters_orderHashes_head_offset).write(
- tailOffset
- );
-
- // Write length = 1 to the orderHashes array.
- dstHead.offset(tailOffset).write(1);
-
- unchecked {
- // Write the single order hash to the orderHashes array.
- dstHead.offset(tailOffset + OneWord).writeBytes32(orderHash);
-
- // Final size: selector, ZoneParameters pointer, orderHashes & tail.
- size = ZoneParameters_basicOrderFixedElements_length + tailOffset;
- }
- }
-
- /**
- * @dev Takes a memory pointer to an array of bytes32 values representing
- * the order hashes included as part of the fulfillment and a memory
- * pointer to a location to copy it to, and copies the source data to
- * the destination in memory.
- *
- * @param srcLength A memory pointer referencing the order hashes array to
- * be copied (and pointing to the length of the array).
- * @param dstLength A memory pointer referencing the location in memory to
- * copy the orderHashes array to (and pointing to the
- * length of the copied array).
- *
- * @return size The size of the order hashes array (including the length).
- */
- function _encodeOrderHashes(
- MemoryPointer srcLength,
- MemoryPointer dstLength
- ) internal view returns (uint256 size) {
- // Read length of the array from source and write to destination.
- uint256 length = srcLength.readUint256();
- dstLength.write(length);
-
- unchecked {
- // Determine head & tail size as one word per element in the array.
- uint256 headAndTailSize = length << OneWordShift;
-
- // Copy the tail starting from the next element of the source to the
- // next element of the destination.
- srcLength.next().copy(dstLength.next(), headAndTailSize);
-
- // Set size to the length of the tail plus one word for length.
- size = headAndTailSize + OneWord;
- }
- }
-
- /**
- * @dev Takes a memory pointer to an offer or consideration array and a
- * memory pointer to a location to copy it to, and copies the source
- * data to the destination in memory as a SpentItem array.
- *
- * @param srcLength A memory pointer referencing the offer or consideration
- * array to be copied as a SpentItem array (and pointing to
- * the length of the original array).
- * @param dstLength A memory pointer referencing the location in memory to
- * copy the offer array to (and pointing to the length of
- * the copied array).
- *
- * @return size The size of the SpentItem array (including the length).
- */
- function _encodeSpentItems(
- MemoryPointer srcLength,
- MemoryPointer dstLength
- ) internal pure returns (uint256 size) {
- assembly {
- // Read length of the array from source and write to destination.
- let length := mload(srcLength)
- mstore(dstLength, length)
-
- // Get pointer to first item's head position in the array,
- // containing the item's pointer in memory. The head pointer will be
- // incremented until it reaches the tail position (start of the
- // array data).
- let mPtrHead := add(srcLength, OneWord)
-
- // Position in memory to write next item for calldata. Since
- // SpentItem has a fixed length, the array elements do not contain
- // head elements in calldata, they are concatenated together after
- // the array length.
- let cdPtrData := add(dstLength, OneWord)
-
- // Pointer to end of array head in memory.
- let mPtrHeadEnd := add(mPtrHead, shl(OneWordShift, length))
-
- for {
-
- } lt(mPtrHead, mPtrHeadEnd) {
-
- } {
- // Read pointer to data for array element from head position.
- let mPtrTail := mload(mPtrHead)
-
- // Copy itemType, token, identifier, amount to calldata.
- mstore(cdPtrData, mload(mPtrTail))
- mstore(
- add(cdPtrData, Common_token_offset),
- mload(add(mPtrTail, Common_token_offset))
- )
- mstore(
- add(cdPtrData, Common_identifier_offset),
- mload(add(mPtrTail, Common_identifier_offset))
- )
- mstore(
- add(cdPtrData, Common_amount_offset),
- mload(add(mPtrTail, Common_amount_offset))
- )
-
- mPtrHead := add(mPtrHead, OneWord)
- cdPtrData := add(cdPtrData, SpentItem_size)
- }
-
- size := add(OneWord, shl(SpentItem_size_shift, length))
- }
- }
-
- /**
- * @dev Takes a memory pointer to an consideration array and a memory
- * pointer to a location to copy it to, and copies the source data to
- * the destination in memory as a ReceivedItem array.
- *
- * @param srcLength A memory pointer referencing the consideration array to
- * be copied as a ReceivedItem array (and pointing to the
- * length of the original array).
- * @param dstLength A memory pointer referencing the location in memory to
- * copy the consideration array to as a ReceivedItem array
- * (and pointing to the length of the new array).
- *
- * @return size The size of the ReceivedItem array (including the length).
- */
- function _encodeConsiderationAsReceivedItems(
- MemoryPointer srcLength,
- MemoryPointer dstLength
- ) internal view returns (uint256 size) {
- unchecked {
- // Read length of the array from source and write to destination.
- uint256 length = srcLength.readUint256();
- dstLength.write(length);
-
- // Get pointer to first item's head position in the array,
- // containing the item's pointer in memory. The head pointer will be
- // incremented until it reaches the tail position (start of the
- // array data).
- MemoryPointer srcHead = srcLength.next();
- MemoryPointer srcHeadEnd = srcHead.offset(length << OneWordShift);
-
- // Position in memory to write next item for calldata. Since
- // ReceivedItem has a fixed length, the array elements do not
- // contain offsets in calldata, they are concatenated together after
- // the array length.
- MemoryPointer dstHead = dstLength.next();
- while (srcHead.lt(srcHeadEnd)) {
- MemoryPointer srcTail = srcHead.pptr();
- srcTail.copy(dstHead, ReceivedItem_size);
- srcHead = srcHead.next();
- dstHead = dstHead.offset(ReceivedItem_size);
- }
-
- size = OneWord + (length * ReceivedItem_size);
- }
- }
-}
diff --git a/contracts/lib/ConsiderationEnums.sol b/contracts/lib/ConsiderationEnums.sol
deleted file mode 100644
index 261ae6b3c..000000000
--- a/contracts/lib/ConsiderationEnums.sol
+++ /dev/null
@@ -1,141 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-enum OrderType {
- // 0: no partial fills, anyone can execute
- FULL_OPEN,
-
- // 1: partial fills supported, anyone can execute
- PARTIAL_OPEN,
-
- // 2: no partial fills, only offerer or zone can execute
- FULL_RESTRICTED,
-
- // 3: partial fills supported, only offerer or zone can execute
- PARTIAL_RESTRICTED,
-
- // 4: contract order type
- CONTRACT
-}
-
-enum BasicOrderType {
- // 0: no partial fills, anyone can execute
- ETH_TO_ERC721_FULL_OPEN,
-
- // 1: partial fills supported, anyone can execute
- ETH_TO_ERC721_PARTIAL_OPEN,
-
- // 2: no partial fills, only offerer or zone can execute
- ETH_TO_ERC721_FULL_RESTRICTED,
-
- // 3: partial fills supported, only offerer or zone can execute
- ETH_TO_ERC721_PARTIAL_RESTRICTED,
-
- // 4: no partial fills, anyone can execute
- ETH_TO_ERC1155_FULL_OPEN,
-
- // 5: partial fills supported, anyone can execute
- ETH_TO_ERC1155_PARTIAL_OPEN,
-
- // 6: no partial fills, only offerer or zone can execute
- ETH_TO_ERC1155_FULL_RESTRICTED,
-
- // 7: partial fills supported, only offerer or zone can execute
- ETH_TO_ERC1155_PARTIAL_RESTRICTED,
-
- // 8: no partial fills, anyone can execute
- ERC20_TO_ERC721_FULL_OPEN,
-
- // 9: partial fills supported, anyone can execute
- ERC20_TO_ERC721_PARTIAL_OPEN,
-
- // 10: no partial fills, only offerer or zone can execute
- ERC20_TO_ERC721_FULL_RESTRICTED,
-
- // 11: partial fills supported, only offerer or zone can execute
- ERC20_TO_ERC721_PARTIAL_RESTRICTED,
-
- // 12: no partial fills, anyone can execute
- ERC20_TO_ERC1155_FULL_OPEN,
-
- // 13: partial fills supported, anyone can execute
- ERC20_TO_ERC1155_PARTIAL_OPEN,
-
- // 14: no partial fills, only offerer or zone can execute
- ERC20_TO_ERC1155_FULL_RESTRICTED,
-
- // 15: partial fills supported, only offerer or zone can execute
- ERC20_TO_ERC1155_PARTIAL_RESTRICTED,
-
- // 16: no partial fills, anyone can execute
- ERC721_TO_ERC20_FULL_OPEN,
-
- // 17: partial fills supported, anyone can execute
- ERC721_TO_ERC20_PARTIAL_OPEN,
-
- // 18: no partial fills, only offerer or zone can execute
- ERC721_TO_ERC20_FULL_RESTRICTED,
-
- // 19: partial fills supported, only offerer or zone can execute
- ERC721_TO_ERC20_PARTIAL_RESTRICTED,
-
- // 20: no partial fills, anyone can execute
- ERC1155_TO_ERC20_FULL_OPEN,
-
- // 21: partial fills supported, anyone can execute
- ERC1155_TO_ERC20_PARTIAL_OPEN,
-
- // 22: no partial fills, only offerer or zone can execute
- ERC1155_TO_ERC20_FULL_RESTRICTED,
-
- // 23: partial fills supported, only offerer or zone can execute
- ERC1155_TO_ERC20_PARTIAL_RESTRICTED
-}
-
-enum BasicOrderRouteType {
- // 0: provide Ether (or other native token) to receive offered ERC721 item.
- ETH_TO_ERC721,
-
- // 1: provide Ether (or other native token) to receive offered ERC1155 item.
- ETH_TO_ERC1155,
-
- // 2: provide ERC20 item to receive offered ERC721 item.
- ERC20_TO_ERC721,
-
- // 3: provide ERC20 item to receive offered ERC1155 item.
- ERC20_TO_ERC1155,
-
- // 4: provide ERC721 item to receive offered ERC20 item.
- ERC721_TO_ERC20,
-
- // 5: provide ERC1155 item to receive offered ERC20 item.
- ERC1155_TO_ERC20
-}
-
-enum ItemType {
- // 0: ETH on mainnet, MATIC on polygon, etc.
- NATIVE,
-
- // 1: ERC20 items (ERC777 and ERC20 analogues could also technically work)
- ERC20,
-
- // 2: ERC721 items
- ERC721,
-
- // 3: ERC1155 items
- ERC1155,
-
- // 4: ERC721 items where a number of tokenIds are supported
- ERC721_WITH_CRITERIA,
-
- // 5: ERC1155 items where a number of ids are supported
- ERC1155_WITH_CRITERIA
-}
-
-enum Side {
- // 0: Items that can be spent
- OFFER,
-
- // 1: Items that must be received
- CONSIDERATION
-}
diff --git a/contracts/lib/ConsiderationErrorConstants.sol b/contracts/lib/ConsiderationErrorConstants.sol
deleted file mode 100644
index 62615a635..000000000
--- a/contracts/lib/ConsiderationErrorConstants.sol
+++ /dev/null
@@ -1,493 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-uint256 constant Error_selector_offset = 0x1c;
-
-/*
- * error MissingFulfillmentComponentOnAggregation(uint8 side)
- * - Defined in FulfillmentApplicationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: side
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant MissingFulfillmentComponentOnAggregation_error_selector = (
- 0x375c24c1
-);
-uint256 constant MissingFulfillmentComponentOnAggregation_error_side_ptr = 0x20;
-uint256 constant MissingFulfillmentComponentOnAggregation_error_length = 0x24;
-
-/*
- * error OfferAndConsiderationRequiredOnFulfillment()
- * - Defined in FulfillmentApplicationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant OfferAndConsiderationRequiredOnFulfillment_error_selector = (
- 0x98e9db6e
-);
-uint256 constant OfferAndConsiderationRequiredOnFulfillment_error_length = 0x04;
-
-/*
- * error MismatchedFulfillmentOfferAndConsiderationComponents(
- * uint256 fulfillmentIndex
- * )
- * - Defined in FulfillmentApplicationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: fulfillmentIndex
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant MismatchedOfferAndConsiderationComponents_error_selector = (
- 0xbced929d
-);
-uint256 constant MismatchedOfferAndConsiderationComponents_error_idx_ptr = 0x20;
-uint256 constant MismatchedOfferAndConsiderationComponents_error_length = 0x24;
-
-/*
- * error InvalidFulfillmentComponentData()
- * - Defined in FulfillmentApplicationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InvalidFulfillmentComponentData_error_selector = 0x7fda7279;
-uint256 constant InvalidFulfillmentComponentData_error_length = 0x04;
-
-/*
- * error InexactFraction()
- * - Defined in AmountDerivationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InexactFraction_error_selector = 0xc63cf089;
-uint256 constant InexactFraction_error_length = 0x04;
-
-/*
- * error OrderCriteriaResolverOutOfRange(uint8 side)
- * - Defined in CriteriaResolutionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: side
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant OrderCriteriaResolverOutOfRange_error_selector = 0x133c37c6;
-uint256 constant OrderCriteriaResolverOutOfRange_error_side_ptr = 0x20;
-uint256 constant OrderCriteriaResolverOutOfRange_error_length = 0x24;
-
-/*
- * error UnresolvedOfferCriteria(uint256 orderIndex, uint256 offerIndex)
- * - Defined in CriteriaResolutionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderIndex
- * - 0x40: offerIndex
- * Revert buffer is memory[0x1c:0x60]
- */
-uint256 constant UnresolvedOfferCriteria_error_selector = 0xd6929332;
-uint256 constant UnresolvedOfferCriteria_error_orderIndex_ptr = 0x20;
-uint256 constant UnresolvedOfferCriteria_error_offerIndex_ptr = 0x40;
-uint256 constant UnresolvedOfferCriteria_error_length = 0x44;
-
-/*
- * error UnresolvedConsiderationCriteria(
- * uint256 orderIndex,
- * uint256 considerationIndex
- * )
- * - Defined in CriteriaResolutionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderIndex
- * - 0x40: considerationIndex
- * Revert buffer is memory[0x1c:0x60]
- */
-uint256 constant UnresolvedConsiderationCriteria_error_selector = 0xa8930e9a;
-uint256 constant UnresolvedConsiderationCriteria_error_orderIndex_ptr = 0x20;
-uint256 constant UnresolvedConsiderationCriteria_error_considerationIdx_ptr = (
- 0x40
-);
-uint256 constant UnresolvedConsiderationCriteria_error_length = 0x44;
-
-/*
- * error OfferCriteriaResolverOutOfRange()
- * - Defined in CriteriaResolutionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant OfferCriteriaResolverOutOfRange_error_selector = 0xbfb3f8ce;
-// uint256 constant OfferCriteriaResolverOutOfRange_error_length = 0x04;
-
-/*
- * error ConsiderationCriteriaResolverOutOfRange()
- * - Defined in CriteriaResolutionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant ConsiderationCriteriaResolverOutOfRange_error_selector = (
- 0x6088d7de
-);
-uint256 constant ConsiderationCriteriaResolverOutOfRange_err_selector = (
- 0x6088d7de
-);
-// uint256 constant ConsiderationCriteriaResolverOutOfRange_error_length = 0x04;
-
-/*
- * error CriteriaNotEnabledForItem()
- * - Defined in CriteriaResolutionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant CriteriaNotEnabledForItem_error_selector = 0x94eb6af6;
-uint256 constant CriteriaNotEnabledForItem_error_length = 0x04;
-
-/*
- * error InvalidProof()
- * - Defined in CriteriaResolutionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InvalidProof_error_selector = 0x09bde339;
-uint256 constant InvalidProof_error_length = 0x04;
-
-/*
- * error InvalidRestrictedOrder(bytes32 orderHash)
- * - Defined in ZoneInteractionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderHash
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant InvalidRestrictedOrder_error_selector = 0xfb5014fc;
-uint256 constant InvalidRestrictedOrder_error_orderHash_ptr = 0x20;
-uint256 constant InvalidRestrictedOrder_error_length = 0x24;
-
-/*
- * error InvalidContractOrder(bytes32 orderHash)
- * - Defined in ZoneInteractionErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderHash
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant InvalidContractOrder_error_selector = 0x93979285;
-uint256 constant InvalidContractOrder_error_orderHash_ptr = 0x20;
-uint256 constant InvalidContractOrder_error_length = 0x24;
-
-/*
- * error BadSignatureV(uint8 v)
- * - Defined in SignatureVerificationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: v
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant BadSignatureV_error_selector = 0x1f003d0a;
-uint256 constant BadSignatureV_error_v_ptr = 0x20;
-uint256 constant BadSignatureV_error_length = 0x24;
-
-/*
- * error InvalidSigner()
- * - Defined in SignatureVerificationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InvalidSigner_error_selector = 0x815e1d64;
-uint256 constant InvalidSigner_error_length = 0x04;
-
-/*
- * error InvalidSignature()
- * - Defined in SignatureVerificationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InvalidSignature_error_selector = 0x8baa579f;
-uint256 constant InvalidSignature_error_length = 0x04;
-
-/*
- * error BadContractSignature()
- * - Defined in SignatureVerificationErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant BadContractSignature_error_selector = 0x4f7fb80d;
-uint256 constant BadContractSignature_error_length = 0x04;
-
-/*
- * error InvalidERC721TransferAmount(uint256 amount)
- * - Defined in TokenTransferrerErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: amount
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant InvalidERC721TransferAmount_error_selector = 0x69f95827;
-uint256 constant InvalidERC721TransferAmount_error_amount_ptr = 0x20;
-uint256 constant InvalidERC721TransferAmount_error_length = 0x24;
-
-/*
- * error MissingItemAmount()
- * - Defined in TokenTransferrerErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant MissingItemAmount_error_selector = 0x91b3e514;
-uint256 constant MissingItemAmount_error_length = 0x04;
-
-/*
- * error UnusedItemParameters()
- * - Defined in TokenTransferrerErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant UnusedItemParameters_error_selector = 0x6ab37ce7;
-uint256 constant UnusedItemParameters_error_length = 0x04;
-
-/*
- * error NoReentrantCalls()
- * - Defined in ReentrancyErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant NoReentrantCalls_error_selector = 0x7fa8a987;
-uint256 constant NoReentrantCalls_error_length = 0x04;
-
-/*
- * error OrderAlreadyFilled(bytes32 orderHash)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderHash
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant OrderAlreadyFilled_error_selector = 0x10fda3e1;
-uint256 constant OrderAlreadyFilled_error_orderHash_ptr = 0x20;
-uint256 constant OrderAlreadyFilled_error_length = 0x24;
-
-/*
- * error InvalidTime(uint256 startTime, uint256 endTime)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: startTime
- * - 0x40: endTime
- * Revert buffer is memory[0x1c:0x60]
- */
-uint256 constant InvalidTime_error_selector = 0x21ccfeb7;
-uint256 constant InvalidTime_error_startTime_ptr = 0x20;
-uint256 constant InvalidTime_error_endTime_ptr = 0x40;
-uint256 constant InvalidTime_error_length = 0x44;
-
-/*
- * error InvalidConduit(bytes32 conduitKey, address conduit)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: conduitKey
- * - 0x40: conduit
- * Revert buffer is memory[0x1c:0x60]
- */
-uint256 constant InvalidConduit_error_selector = 0x1cf99b26;
-uint256 constant InvalidConduit_error_conduitKey_ptr = 0x20;
-uint256 constant InvalidConduit_error_conduit_ptr = 0x40;
-uint256 constant InvalidConduit_error_length = 0x44;
-
-/*
- * error MissingOriginalConsiderationItems()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant MissingOriginalConsiderationItems_error_selector = 0x466aa616;
-uint256 constant MissingOriginalConsiderationItems_error_length = 0x04;
-
-/*
- * error InvalidCallToConduit(address conduit)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: conduit
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant InvalidCallToConduit_error_selector = 0xd13d53d4;
-uint256 constant InvalidCallToConduit_error_conduit_ptr = 0x20;
-uint256 constant InvalidCallToConduit_error_length = 0x24;
-
-/*
- * error ConsiderationNotMet(
- * uint256 orderIndex,
- * uint256 considerationIndex,
- * uint256 shortfallAmount
- * )
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderIndex
- * - 0x40: considerationIndex
- * - 0x60: shortfallAmount
- * Revert buffer is memory[0x1c:0x80]
- */
-uint256 constant ConsiderationNotMet_error_selector = 0xa5f54208;
-uint256 constant ConsiderationNotMet_error_orderIndex_ptr = 0x20;
-uint256 constant ConsiderationNotMet_error_considerationIndex_ptr = 0x40;
-uint256 constant ConsiderationNotMet_error_shortfallAmount_ptr = 0x60;
-uint256 constant ConsiderationNotMet_error_length = 0x64;
-
-/*
- * error InsufficientNativeTokensSupplied()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InsufficientNativeTokensSupplied_error_selector = 0x8ffff980;
-uint256 constant InsufficientNativeTokensSupplied_error_length = 0x04;
-
-/*
- * error NativeTokenTransferGenericFailure(address account, uint256 amount)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: account
- * - 0x40: amount
- * Revert buffer is memory[0x1c:0x60]
- */
-uint256 constant NativeTokenTransferGenericFailure_error_selector = 0xbc806b96;
-uint256 constant NativeTokenTransferGenericFailure_error_account_ptr = 0x20;
-uint256 constant NativeTokenTransferGenericFailure_error_amount_ptr = 0x40;
-uint256 constant NativeTokenTransferGenericFailure_error_length = 0x44;
-
-/*
- * error PartialFillsNotEnabledForOrder()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant PartialFillsNotEnabledForOrder_error_selector = 0xa11b63ff;
-uint256 constant PartialFillsNotEnabledForOrder_error_length = 0x04;
-
-/*
- * error OrderIsCancelled(bytes32 orderHash)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderHash
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant OrderIsCancelled_error_selector = 0x1a515574;
-uint256 constant OrderIsCancelled_error_orderHash_ptr = 0x20;
-uint256 constant OrderIsCancelled_error_length = 0x24;
-
-/*
- * error OrderPartiallyFilled(bytes32 orderHash)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: orderHash
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant OrderPartiallyFilled_error_selector = 0xee9e0e63;
-uint256 constant OrderPartiallyFilled_error_orderHash_ptr = 0x20;
-uint256 constant OrderPartiallyFilled_error_length = 0x24;
-
-/*
- * error CannotCancelOrder()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant CannotCancelOrder_error_selector = 0xfed398fc;
-uint256 constant CannotCancelOrder_error_length = 0x04;
-
-/*
- * error BadFraction()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant BadFraction_error_selector = 0x5a052b32;
-uint256 constant BadFraction_error_length = 0x04;
-
-/*
- * error InvalidMsgValue(uint256 value)
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: value
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant InvalidMsgValue_error_selector = 0xa61be9f0;
-uint256 constant InvalidMsgValue_error_value_ptr = 0x20;
-uint256 constant InvalidMsgValue_error_length = 0x24;
-
-/*
- * error InvalidBasicOrderParameterEncoding()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InvalidBasicOrderParameterEncoding_error_selector = 0x39f3e3fd;
-uint256 constant InvalidBasicOrderParameterEncoding_error_length = 0x04;
-
-/*
- * error NoSpecifiedOrdersAvailable()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant NoSpecifiedOrdersAvailable_error_selector = 0xd5da9a1b;
-uint256 constant NoSpecifiedOrdersAvailable_error_length = 0x04;
-
-/*
- * error InvalidNativeOfferItem()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant InvalidNativeOfferItem_error_selector = 0x12d3f5a3;
-uint256 constant InvalidNativeOfferItem_error_length = 0x04;
-
-/*
- * error ConsiderationLengthNotEqualToTotalOriginal()
- * - Defined in ConsiderationEventsAndErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * Revert buffer is memory[0x1c:0x20]
- */
-uint256 constant ConsiderationLengthNotEqualToTotalOriginal_error_selector = (
- 0x2165628a
-);
-uint256 constant ConsiderationLengthNotEqualToTotalOriginal_error_length = 0x04;
-
-/*
- * error Panic(uint256 code)
- * - Built-in Solidity error
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: code
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant Panic_error_selector = 0x4e487b71;
-uint256 constant Panic_error_code_ptr = 0x20;
-uint256 constant Panic_error_length = 0x24;
-
-uint256 constant Panic_arithmetic = 0x11;
-// uint256 constant Panic_resource = 0x41;
diff --git a/contracts/lib/ConsiderationErrors.sol b/contracts/lib/ConsiderationErrors.sol
deleted file mode 100644
index f5f7f1d42..000000000
--- a/contracts/lib/ConsiderationErrors.sol
+++ /dev/null
@@ -1,712 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { Side } from "./ConsiderationEnums.sol";
-
-import {
- BadFraction_error_length,
- BadFraction_error_selector,
- CannotCancelOrder_error_length,
- CannotCancelOrder_error_selector,
- ConsiderationLengthNotEqualToTotalOriginal_error_length,
- ConsiderationLengthNotEqualToTotalOriginal_error_selector,
- ConsiderationNotMet_error_considerationIndex_ptr,
- ConsiderationNotMet_error_length,
- ConsiderationNotMet_error_orderIndex_ptr,
- ConsiderationNotMet_error_selector,
- ConsiderationNotMet_error_shortfallAmount_ptr,
- CriteriaNotEnabledForItem_error_length,
- CriteriaNotEnabledForItem_error_selector,
- Error_selector_offset,
- InsufficientNativeTokensSupplied_error_length,
- InsufficientNativeTokensSupplied_error_selector,
- InvalidBasicOrderParameterEncoding_error_length,
- InvalidBasicOrderParameterEncoding_error_selector,
- InvalidCallToConduit_error_conduit_ptr,
- InvalidCallToConduit_error_length,
- InvalidCallToConduit_error_selector,
- InvalidConduit_error_conduit_ptr,
- InvalidConduit_error_conduitKey_ptr,
- InvalidConduit_error_length,
- InvalidConduit_error_selector,
- InvalidContractOrder_error_length,
- InvalidContractOrder_error_orderHash_ptr,
- InvalidContractOrder_error_selector,
- InvalidERC721TransferAmount_error_amount_ptr,
- InvalidERC721TransferAmount_error_length,
- InvalidERC721TransferAmount_error_selector,
- InvalidMsgValue_error_length,
- InvalidMsgValue_error_selector,
- InvalidMsgValue_error_value_ptr,
- InvalidNativeOfferItem_error_length,
- InvalidNativeOfferItem_error_selector,
- InvalidProof_error_length,
- InvalidProof_error_selector,
- InvalidTime_error_endTime_ptr,
- InvalidTime_error_length,
- InvalidTime_error_selector,
- InvalidTime_error_startTime_ptr,
- MismatchedOfferAndConsiderationComponents_error_idx_ptr,
- MismatchedOfferAndConsiderationComponents_error_length,
- MismatchedOfferAndConsiderationComponents_error_selector,
- MissingFulfillmentComponentOnAggregation_error_length,
- MissingFulfillmentComponentOnAggregation_error_selector,
- MissingFulfillmentComponentOnAggregation_error_side_ptr,
- MissingOriginalConsiderationItems_error_length,
- MissingOriginalConsiderationItems_error_selector,
- NoReentrantCalls_error_length,
- NoReentrantCalls_error_selector,
- NoSpecifiedOrdersAvailable_error_length,
- NoSpecifiedOrdersAvailable_error_selector,
- OfferAndConsiderationRequiredOnFulfillment_error_length,
- OfferAndConsiderationRequiredOnFulfillment_error_selector,
- OrderAlreadyFilled_error_length,
- OrderAlreadyFilled_error_orderHash_ptr,
- OrderAlreadyFilled_error_selector,
- OrderCriteriaResolverOutOfRange_error_length,
- OrderCriteriaResolverOutOfRange_error_selector,
- OrderCriteriaResolverOutOfRange_error_side_ptr,
- OrderIsCancelled_error_length,
- OrderIsCancelled_error_orderHash_ptr,
- OrderIsCancelled_error_selector,
- OrderPartiallyFilled_error_length,
- OrderPartiallyFilled_error_orderHash_ptr,
- OrderPartiallyFilled_error_selector,
- PartialFillsNotEnabledForOrder_error_length,
- PartialFillsNotEnabledForOrder_error_selector,
- UnresolvedConsiderationCriteria_error_considerationIdx_ptr,
- UnresolvedConsiderationCriteria_error_length,
- UnresolvedConsiderationCriteria_error_orderIndex_ptr,
- UnresolvedConsiderationCriteria_error_selector,
- UnresolvedOfferCriteria_error_length,
- UnresolvedOfferCriteria_error_offerIndex_ptr,
- UnresolvedOfferCriteria_error_orderIndex_ptr,
- UnresolvedOfferCriteria_error_selector,
- UnusedItemParameters_error_length,
- UnusedItemParameters_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @dev Reverts the current transaction with a "BadFraction" error message.
- */
-function _revertBadFraction() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, BadFraction_error_selector)
-
- // revert(abi.encodeWithSignature("BadFraction()"))
- revert(Error_selector_offset, BadFraction_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with a "ConsiderationNotMet" error
- * message, including the provided order index, consideration index, and
- * shortfall amount.
- *
- * @param orderIndex The index of the order that did not meet the
- * consideration criteria.
- * @param considerationIndex The index of the consideration item that did not
- * meet its criteria.
- * @param shortfallAmount The amount by which the consideration criteria were
- * not met.
- */
-function _revertConsiderationNotMet(
- uint256 orderIndex,
- uint256 considerationIndex,
- uint256 shortfallAmount
-) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, ConsiderationNotMet_error_selector)
-
- // Store arguments.
- mstore(ConsiderationNotMet_error_orderIndex_ptr, orderIndex)
- mstore(
- ConsiderationNotMet_error_considerationIndex_ptr,
- considerationIndex
- )
- mstore(ConsiderationNotMet_error_shortfallAmount_ptr, shortfallAmount)
-
- // revert(abi.encodeWithSignature(
- // "ConsiderationNotMet(uint256,uint256,uint256)",
- // orderIndex,
- // considerationIndex,
- // shortfallAmount
- // ))
- revert(Error_selector_offset, ConsiderationNotMet_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with a "CriteriaNotEnabledForItem" error
- * message.
- */
-function _revertCriteriaNotEnabledForItem() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, CriteriaNotEnabledForItem_error_selector)
-
- // revert(abi.encodeWithSignature("CriteriaNotEnabledForItem()"))
- revert(Error_selector_offset, CriteriaNotEnabledForItem_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an
- * "InsufficientNativeTokensSupplied" error message.
- */
-function _revertInsufficientNativeTokensSupplied() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InsufficientNativeTokensSupplied_error_selector)
-
- // revert(abi.encodeWithSignature("InsufficientNativeTokensSupplied()"))
- revert(
- Error_selector_offset,
- InsufficientNativeTokensSupplied_error_length
- )
- }
-}
-
-/**
- * @dev Reverts the current transaction with an
- * "InvalidBasicOrderParameterEncoding" error message.
- */
-function _revertInvalidBasicOrderParameterEncoding() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidBasicOrderParameterEncoding_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "InvalidBasicOrderParameterEncoding()"
- // ))
- revert(
- Error_selector_offset,
- InvalidBasicOrderParameterEncoding_error_length
- )
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidCallToConduit" error
- * message, including the provided address of the conduit that was called
- * improperly.
- *
- * @param conduit The address of the conduit that was called improperly.
- */
-function _revertInvalidCallToConduit(address conduit) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidCallToConduit_error_selector)
-
- // Store argument.
- mstore(InvalidCallToConduit_error_conduit_ptr, conduit)
-
- // revert(abi.encodeWithSignature(
- // "InvalidCallToConduit(address)",
- // conduit
- // ))
- revert(Error_selector_offset, InvalidCallToConduit_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "CannotCancelOrder" error
- * message.
- */
-function _revertCannotCancelOrder() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, CannotCancelOrder_error_selector)
-
- // revert(abi.encodeWithSignature("CannotCancelOrder()"))
- revert(Error_selector_offset, CannotCancelOrder_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidConduit" error message,
- * including the provided key and address of the invalid conduit.
- *
- * @param conduitKey The key of the invalid conduit.
- * @param conduit The address of the invalid conduit.
- */
-function _revertInvalidConduit(bytes32 conduitKey, address conduit) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidConduit_error_selector)
-
- // Store arguments.
- mstore(InvalidConduit_error_conduitKey_ptr, conduitKey)
- mstore(InvalidConduit_error_conduit_ptr, conduit)
-
- // revert(abi.encodeWithSignature(
- // "InvalidConduit(bytes32,address)",
- // conduitKey,
- // conduit
- // ))
- revert(Error_selector_offset, InvalidConduit_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidERC721TransferAmount"
- * error message.
- *
- * @param amount The invalid amount.
- */
-function _revertInvalidERC721TransferAmount(uint256 amount) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidERC721TransferAmount_error_selector)
-
- // Store argument.
- mstore(InvalidERC721TransferAmount_error_amount_ptr, amount)
-
- // revert(abi.encodeWithSignature(
- // "InvalidERC721TransferAmount(uint256)",
- // amount
- // ))
- revert(Error_selector_offset, InvalidERC721TransferAmount_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidMsgValue" error message,
- * including the invalid value that was sent in the transaction's
- * `msg.value` field.
- *
- * @param value The invalid value that was sent in the transaction's `msg.value`
- * field.
- */
-function _revertInvalidMsgValue(uint256 value) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidMsgValue_error_selector)
-
- // Store argument.
- mstore(InvalidMsgValue_error_value_ptr, value)
-
- // revert(abi.encodeWithSignature("InvalidMsgValue(uint256)", value))
- revert(Error_selector_offset, InvalidMsgValue_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidNativeOfferItem" error
- * message.
- */
-function _revertInvalidNativeOfferItem() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidNativeOfferItem_error_selector)
-
- // revert(abi.encodeWithSignature("InvalidNativeOfferItem()"))
- revert(Error_selector_offset, InvalidNativeOfferItem_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidProof" error message.
- */
-function _revertInvalidProof() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidProof_error_selector)
-
- // revert(abi.encodeWithSignature("InvalidProof()"))
- revert(Error_selector_offset, InvalidProof_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidContractOrder" error
- * message.
- *
- * @param orderHash The hash of the contract order that caused the error.
- */
-function _revertInvalidContractOrder(bytes32 orderHash) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidContractOrder_error_selector)
-
- // Store arguments.
- mstore(InvalidContractOrder_error_orderHash_ptr, orderHash)
-
- // revert(abi.encodeWithSignature(
- // "InvalidContractOrder(bytes32)",
- // orderHash
- // ))
- revert(Error_selector_offset, InvalidContractOrder_error_length)
- }
-}
-
-/**
- * @dev Reverts the current transaction with an "InvalidTime" error message.
- *
- * @param startTime The time at which the order becomes active.
- * @param endTime The time at which the order becomes inactive.
- */
-function _revertInvalidTime(uint256 startTime, uint256 endTime) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, InvalidTime_error_selector)
-
- // Store arguments.
- mstore(InvalidTime_error_startTime_ptr, startTime)
- mstore(InvalidTime_error_endTime_ptr, endTime)
-
- // revert(abi.encodeWithSignature(
- // "InvalidTime(uint256,uint256)",
- // startTime,
- // endTime
- // ))
- revert(Error_selector_offset, InvalidTime_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with a
- * "MismatchedFulfillmentOfferAndConsiderationComponents" error message.
- *
- * @param fulfillmentIndex The index of the fulfillment that caused the
- * error.
- */
-function _revertMismatchedFulfillmentOfferAndConsiderationComponents(
- uint256 fulfillmentIndex
-) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, MismatchedOfferAndConsiderationComponents_error_selector)
-
- // Store fulfillment index argument.
- mstore(
- MismatchedOfferAndConsiderationComponents_error_idx_ptr,
- fulfillmentIndex
- )
-
- // revert(abi.encodeWithSignature(
- // "MismatchedFulfillmentOfferAndConsiderationComponents(uint256)",
- // fulfillmentIndex
- // ))
- revert(
- Error_selector_offset,
- MismatchedOfferAndConsiderationComponents_error_length
- )
- }
-}
-
-/**
- * @dev Reverts execution with a "MissingFulfillmentComponentOnAggregation"
- * error message.
- *
- * @param side The side of the fulfillment component that is missing (0 for
- * offer, 1 for consideration).
- *
- */
-function _revertMissingFulfillmentComponentOnAggregation(Side side) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, MissingFulfillmentComponentOnAggregation_error_selector)
-
- // Store argument.
- mstore(MissingFulfillmentComponentOnAggregation_error_side_ptr, side)
-
- // revert(abi.encodeWithSignature(
- // "MissingFulfillmentComponentOnAggregation(uint8)",
- // side
- // ))
- revert(
- Error_selector_offset,
- MissingFulfillmentComponentOnAggregation_error_length
- )
- }
-}
-
-/**
- * @dev Reverts execution with a "MissingOriginalConsiderationItems" error
- * message.
- */
-function _revertMissingOriginalConsiderationItems() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, MissingOriginalConsiderationItems_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "MissingOriginalConsiderationItems()"
- // ))
- revert(
- Error_selector_offset,
- MissingOriginalConsiderationItems_error_length
- )
- }
-}
-
-/**
- * @dev Reverts execution with a "NoReentrantCalls" error message.
- */
-function _revertNoReentrantCalls() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, NoReentrantCalls_error_selector)
-
- // revert(abi.encodeWithSignature("NoReentrantCalls()"))
- revert(Error_selector_offset, NoReentrantCalls_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with a "NoSpecifiedOrdersAvailable" error message.
- */
-function _revertNoSpecifiedOrdersAvailable() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, NoSpecifiedOrdersAvailable_error_selector)
-
- // revert(abi.encodeWithSignature("NoSpecifiedOrdersAvailable()"))
- revert(Error_selector_offset, NoSpecifiedOrdersAvailable_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with a "OfferAndConsiderationRequiredOnFulfillment"
- * error message.
- */
-function _revertOfferAndConsiderationRequiredOnFulfillment() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, OfferAndConsiderationRequiredOnFulfillment_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "OfferAndConsiderationRequiredOnFulfillment()"
- // ))
- revert(
- Error_selector_offset,
- OfferAndConsiderationRequiredOnFulfillment_error_length
- )
- }
-}
-
-/**
- * @dev Reverts execution with an "OrderAlreadyFilled" error message.
- *
- * @param orderHash The hash of the order that has already been filled.
- */
-function _revertOrderAlreadyFilled(bytes32 orderHash) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, OrderAlreadyFilled_error_selector)
-
- // Store argument.
- mstore(OrderAlreadyFilled_error_orderHash_ptr, orderHash)
-
- // revert(abi.encodeWithSignature(
- // "OrderAlreadyFilled(bytes32)",
- // orderHash
- // ))
- revert(Error_selector_offset, OrderAlreadyFilled_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with an "OrderCriteriaResolverOutOfRange" error
- * message.
- *
- * @param side The side of the criteria that is missing (0 for offer, 1 for
- * consideration).
- *
- */
-function _revertOrderCriteriaResolverOutOfRange(Side side) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, OrderCriteriaResolverOutOfRange_error_selector)
-
- // Store argument.
- mstore(OrderCriteriaResolverOutOfRange_error_side_ptr, side)
-
- // revert(abi.encodeWithSignature(
- // "OrderCriteriaResolverOutOfRange(uint8)",
- // side
- // ))
- revert(
- Error_selector_offset,
- OrderCriteriaResolverOutOfRange_error_length
- )
- }
-}
-
-/**
- * @dev Reverts execution with an "OrderIsCancelled" error message.
- *
- * @param orderHash The hash of the order that has already been cancelled.
- */
-function _revertOrderIsCancelled(bytes32 orderHash) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, OrderIsCancelled_error_selector)
-
- // Store argument.
- mstore(OrderIsCancelled_error_orderHash_ptr, orderHash)
-
- // revert(abi.encodeWithSignature(
- // "OrderIsCancelled(bytes32)",
- // orderHash
- // ))
- revert(Error_selector_offset, OrderIsCancelled_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with an "OrderPartiallyFilled" error message.
- *
- * @param orderHash The hash of the order that has already been partially
- * filled.
- */
-function _revertOrderPartiallyFilled(bytes32 orderHash) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, OrderPartiallyFilled_error_selector)
-
- // Store argument.
- mstore(OrderPartiallyFilled_error_orderHash_ptr, orderHash)
-
- // revert(abi.encodeWithSignature(
- // "OrderPartiallyFilled(bytes32)",
- // orderHash
- // ))
- revert(Error_selector_offset, OrderPartiallyFilled_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with a "PartialFillsNotEnabledForOrder" error message.
- */
-function _revertPartialFillsNotEnabledForOrder() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, PartialFillsNotEnabledForOrder_error_selector)
-
- // revert(abi.encodeWithSignature("PartialFillsNotEnabledForOrder()"))
- revert(
- Error_selector_offset,
- PartialFillsNotEnabledForOrder_error_length
- )
- }
-}
-
-/**
- * @dev Reverts execution with an "UnresolvedConsiderationCriteria" error
- * message.
- */
-function _revertUnresolvedConsiderationCriteria(
- uint256 orderIndex,
- uint256 considerationIndex
-) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, UnresolvedConsiderationCriteria_error_selector)
-
- // Store orderIndex and considerationIndex arguments.
- mstore(UnresolvedConsiderationCriteria_error_orderIndex_ptr, orderIndex)
- mstore(
- UnresolvedConsiderationCriteria_error_considerationIdx_ptr,
- considerationIndex
- )
-
- // revert(abi.encodeWithSignature(
- // "UnresolvedConsiderationCriteria(uint256, uint256)",
- // orderIndex,
- // considerationIndex
- // ))
- revert(
- Error_selector_offset,
- UnresolvedConsiderationCriteria_error_length
- )
- }
-}
-
-/**
- * @dev Reverts execution with an "UnresolvedOfferCriteria" error message.
- */
-function _revertUnresolvedOfferCriteria(
- uint256 orderIndex,
- uint256 offerIndex
-) pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, UnresolvedOfferCriteria_error_selector)
-
- // Store arguments.
- mstore(UnresolvedOfferCriteria_error_orderIndex_ptr, orderIndex)
- mstore(UnresolvedOfferCriteria_error_offerIndex_ptr, offerIndex)
-
- // revert(abi.encodeWithSignature(
- // "UnresolvedOfferCriteria(uint256, uint256)",
- // orderIndex,
- // offerIndex
- // ))
- revert(Error_selector_offset, UnresolvedOfferCriteria_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with an "UnusedItemParameters" error message.
- */
-function _revertUnusedItemParameters() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, UnusedItemParameters_error_selector)
-
- // revert(abi.encodeWithSignature("UnusedItemParameters()"))
- revert(Error_selector_offset, UnusedItemParameters_error_length)
- }
-}
-
-/**
- * @dev Reverts execution with a "ConsiderationLengthNotEqualToTotalOriginal"
- * error message.
- */
-function _revertConsiderationLengthNotEqualToTotalOriginal() pure {
- assembly {
- // Store left-padded selector with push4 (reduces bytecode),
- // mem[28:32] = selector
- mstore(0, ConsiderationLengthNotEqualToTotalOriginal_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "ConsiderationLengthNotEqualToTotalOriginal()"
- // ))
- revert(
- Error_selector_offset,
- ConsiderationLengthNotEqualToTotalOriginal_error_length
- )
- }
-}
diff --git a/contracts/lib/ConsiderationStructs.sol b/contracts/lib/ConsiderationStructs.sol
deleted file mode 100644
index 04cd4aaf0..000000000
--- a/contracts/lib/ConsiderationStructs.sol
+++ /dev/null
@@ -1,779 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- BasicOrderType,
- ItemType,
- OrderType,
- Side
-} from "./ConsiderationEnums.sol";
-
-import {
- CalldataPointer,
- MemoryPointer
-} from "../helpers/PointerLibraries.sol";
-
-/**
- * @dev An order contains eleven components: an offerer, a zone (or account that
- * can cancel the order or restrict who can fulfill the order depending on
- * the type), the order type (specifying partial fill support as well as
- * restricted order status), the start and end time, a hash that will be
- * provided to the zone when validating restricted orders, a salt, a key
- * corresponding to a given conduit, a counter, and an arbitrary number of
- * offer items that can be spent along with consideration items that must
- * be received by their respective recipient.
- */
-struct OrderComponents {
- address offerer;
- address zone;
- OfferItem[] offer;
- ConsiderationItem[] consideration;
- OrderType orderType;
- uint256 startTime;
- uint256 endTime;
- bytes32 zoneHash;
- uint256 salt;
- bytes32 conduitKey;
- uint256 counter;
-}
-
-/**
- * @dev An offer item has five components: an item type (ETH or other native
- * tokens, ERC20, ERC721, and ERC1155, as well as criteria-based ERC721 and
- * ERC1155), a token address, a dual-purpose "identifierOrCriteria"
- * component that will either represent a tokenId or a merkle root
- * depending on the item type, and a start and end amount that support
- * increasing or decreasing amounts over the duration of the respective
- * order.
- */
-struct OfferItem {
- ItemType itemType;
- address token;
- uint256 identifierOrCriteria;
- uint256 startAmount;
- uint256 endAmount;
-}
-
-/**
- * @dev A consideration item has the same five components as an offer item and
- * an additional sixth component designating the required recipient of the
- * item.
- */
-struct ConsiderationItem {
- ItemType itemType;
- address token;
- uint256 identifierOrCriteria;
- uint256 startAmount;
- uint256 endAmount;
- address payable recipient;
-}
-
-/**
- * @dev A spent item is translated from a utilized offer item and has four
- * components: an item type (ETH or other native tokens, ERC20, ERC721, and
- * ERC1155), a token address, a tokenId, and an amount.
- */
-struct SpentItem {
- ItemType itemType;
- address token;
- uint256 identifier;
- uint256 amount;
-}
-
-/**
- * @dev A received item is translated from a utilized consideration item and has
- * the same four components as a spent item, as well as an additional fifth
- * component designating the required recipient of the item.
- */
-struct ReceivedItem {
- ItemType itemType;
- address token;
- uint256 identifier;
- uint256 amount;
- address payable recipient;
-}
-
-/**
- * @dev For basic orders involving ETH / native / ERC20 <=> ERC721 / ERC1155
- * matching, a group of six functions may be called that only requires a
- * subset of the usual order arguments. Note the use of a "basicOrderType"
- * enum; this represents both the usual order type as well as the "route"
- * of the basic order (a simple derivation function for the basic order
- * type is `basicOrderType = orderType + (4 * basicOrderRoute)`.)
- */
-struct BasicOrderParameters {
- // calldata offset
- address considerationToken; // 0x24
- uint256 considerationIdentifier; // 0x44
- uint256 considerationAmount; // 0x64
- address payable offerer; // 0x84
- address zone; // 0xa4
- address offerToken; // 0xc4
- uint256 offerIdentifier; // 0xe4
- uint256 offerAmount; // 0x104
- BasicOrderType basicOrderType; // 0x124
- uint256 startTime; // 0x144
- uint256 endTime; // 0x164
- bytes32 zoneHash; // 0x184
- uint256 salt; // 0x1a4
- bytes32 offererConduitKey; // 0x1c4
- bytes32 fulfillerConduitKey; // 0x1e4
- uint256 totalOriginalAdditionalRecipients; // 0x204
- AdditionalRecipient[] additionalRecipients; // 0x224
- bytes signature; // 0x244
- // Total length, excluding dynamic array data: 0x264 (580)
-}
-
-/**
- * @dev Basic orders can supply any number of additional recipients, with the
- * implied assumption that they are supplied from the offered ETH (or other
- * native token) or ERC20 token for the order.
- */
-struct AdditionalRecipient {
- uint256 amount;
- address payable recipient;
-}
-
-/**
- * @dev The full set of order components, with the exception of the counter,
- * must be supplied when fulfilling more sophisticated orders or groups of
- * orders. The total number of original consideration items must also be
- * supplied, as the caller may specify additional consideration items.
- */
-struct OrderParameters {
- address offerer; // 0x00
- address zone; // 0x20
- OfferItem[] offer; // 0x40
- ConsiderationItem[] consideration; // 0x60
- OrderType orderType; // 0x80
- uint256 startTime; // 0xa0
- uint256 endTime; // 0xc0
- bytes32 zoneHash; // 0xe0
- uint256 salt; // 0x100
- bytes32 conduitKey; // 0x120
- uint256 totalOriginalConsiderationItems; // 0x140
- // offer.length // 0x160
-}
-
-/**
- * @dev Orders require a signature in addition to the other order parameters.
- */
-struct Order {
- OrderParameters parameters;
- bytes signature;
-}
-
-/**
- * @dev Advanced orders include a numerator (i.e. a fraction to attempt to fill)
- * and a denominator (the total size of the order) in addition to the
- * signature and other order parameters. It also supports an optional field
- * for supplying extra data; this data will be provided to the zone if the
- * order type is restricted and the zone is not the caller, or will be
- * provided to the offerer as context for contract order types.
- */
-struct AdvancedOrder {
- OrderParameters parameters;
- uint120 numerator;
- uint120 denominator;
- bytes signature;
- bytes extraData;
-}
-
-/**
- * @dev Orders can be validated (either explicitly via `validate`, or as a
- * consequence of a full or partial fill), specifically cancelled (they can
- * also be cancelled in bulk via incrementing a per-zone counter), and
- * partially or fully filled (with the fraction filled represented by a
- * numerator and denominator).
- */
-struct OrderStatus {
- bool isValidated;
- bool isCancelled;
- uint120 numerator;
- uint120 denominator;
-}
-
-/**
- * @dev A criteria resolver specifies an order, side (offer vs. consideration),
- * and item index. It then provides a chosen identifier (i.e. tokenId)
- * alongside a merkle proof demonstrating the identifier meets the required
- * criteria.
- */
-struct CriteriaResolver {
- uint256 orderIndex;
- Side side;
- uint256 index;
- uint256 identifier;
- bytes32[] criteriaProof;
-}
-
-/**
- * @dev A fulfillment is applied to a group of orders. It decrements a series of
- * offer and consideration items, then generates a single execution
- * element. A given fulfillment can be applied to as many offer and
- * consideration items as desired, but must contain at least one offer and
- * at least one consideration that match. The fulfillment must also remain
- * consistent on all key parameters across all offer items (same offerer,
- * token, type, tokenId, and conduit preference) as well as across all
- * consideration items (token, type, tokenId, and recipient).
- */
-struct Fulfillment {
- FulfillmentComponent[] offerComponents;
- FulfillmentComponent[] considerationComponents;
-}
-
-/**
- * @dev Each fulfillment component contains one index referencing a specific
- * order and another referencing a specific offer or consideration item.
- */
-struct FulfillmentComponent {
- uint256 orderIndex;
- uint256 itemIndex;
-}
-
-/**
- * @dev An execution is triggered once all consideration items have been zeroed
- * out. It sends the item in question from the offerer to the item's
- * recipient, optionally sourcing approvals from either this contract
- * directly or from the offerer's chosen conduit if one is specified. An
- * execution is not provided as an argument, but rather is derived via
- * orders, criteria resolvers, and fulfillments (where the total number of
- * executions will be less than or equal to the total number of indicated
- * fulfillments) and returned as part of `matchOrders`.
- */
-struct Execution {
- ReceivedItem item;
- address offerer;
- bytes32 conduitKey;
-}
-
-/**
- * @dev Restricted orders are validated post-execution by calling validateOrder
- * on the zone. This struct provides context about the order fulfillment
- * and any supplied extraData, as well as all order hashes fulfilled in a
- * call to a match or fulfillAvailable method.
- */
-struct ZoneParameters {
- bytes32 orderHash;
- address fulfiller;
- address offerer;
- SpentItem[] offer;
- ReceivedItem[] consideration;
- bytes extraData;
- bytes32[] orderHashes;
- uint256 startTime;
- uint256 endTime;
- bytes32 zoneHash;
-}
-
-/**
- * @dev Zones and contract offerers can communicate which schemas they implement
- * along with any associated metadata related to each schema.
- */
-struct Schema {
- uint256 id;
- bytes metadata;
-}
-
-using StructPointers for OrderComponents global;
-using StructPointers for OfferItem global;
-using StructPointers for ConsiderationItem global;
-using StructPointers for SpentItem global;
-using StructPointers for ReceivedItem global;
-using StructPointers for BasicOrderParameters global;
-using StructPointers for AdditionalRecipient global;
-using StructPointers for OrderParameters global;
-using StructPointers for Order global;
-using StructPointers for AdvancedOrder global;
-using StructPointers for OrderStatus global;
-using StructPointers for CriteriaResolver global;
-using StructPointers for Fulfillment global;
-using StructPointers for FulfillmentComponent global;
-using StructPointers for Execution global;
-using StructPointers for ZoneParameters global;
-
-/**
- * @dev This library provides a set of functions for converting structs to
- * pointers.
- */
-library StructPointers {
- /**
- * @dev Get a MemoryPointer from OrderComponents.
- *
- * @param obj The OrderComponents object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- OrderComponents memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from OrderComponents.
- *
- * @param obj The OrderComponents object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- OrderComponents calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from OfferItem.
- *
- * @param obj The OfferItem object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- OfferItem memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from OfferItem.
- *
- * @param obj The OfferItem object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- OfferItem calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from ConsiderationItem.
- *
- * @param obj The ConsiderationItem object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- ConsiderationItem memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from ConsiderationItem.
- *
- * @param obj The ConsiderationItem object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- ConsiderationItem calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from SpentItem.
- *
- * @param obj The SpentItem object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- SpentItem memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from SpentItem.
- *
- * @param obj The SpentItem object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- SpentItem calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from ReceivedItem.
- *
- * @param obj The ReceivedItem object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- ReceivedItem memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from ReceivedItem.
- *
- * @param obj The ReceivedItem object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- ReceivedItem calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from BasicOrderParameters.
- *
- * @param obj The BasicOrderParameters object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- BasicOrderParameters memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from BasicOrderParameters.
- *
- * @param obj The BasicOrderParameters object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- BasicOrderParameters calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from AdditionalRecipient.
- *
- * @param obj The AdditionalRecipient object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- AdditionalRecipient memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from AdditionalRecipient.
- *
- * @param obj The AdditionalRecipient object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- AdditionalRecipient calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from OrderParameters.
- *
- * @param obj The OrderParameters object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- OrderParameters memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from OrderParameters.
- *
- * @param obj The OrderParameters object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- OrderParameters calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from Order.
- *
- * @param obj The Order object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- Order memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from Order.
- *
- * @param obj The Order object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- Order calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from AdvancedOrder.
- *
- * @param obj The AdvancedOrder object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- AdvancedOrder memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from AdvancedOrder.
- *
- * @param obj The AdvancedOrder object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- AdvancedOrder calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from OrderStatus.
- *
- * @param obj The OrderStatus object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- OrderStatus memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from OrderStatus.
- *
- * @param obj The OrderStatus object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- OrderStatus calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from CriteriaResolver.
- *
- * @param obj The CriteriaResolver object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- CriteriaResolver memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from CriteriaResolver.
- *
- * @param obj The CriteriaResolver object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- CriteriaResolver calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from Fulfillment.
- *
- * @param obj The Fulfillment object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- Fulfillment memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from Fulfillment.
- *
- * @param obj The Fulfillment object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- Fulfillment calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from FulfillmentComponent.
- *
- * @param obj The FulfillmentComponent object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- FulfillmentComponent memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from FulfillmentComponent.
- *
- * @param obj The FulfillmentComponent object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- FulfillmentComponent calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from Execution.
- *
- * @param obj The Execution object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- Execution memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from Execution.
- *
- * @param obj The Execution object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- Execution calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a MemoryPointer from ZoneParameters.
- *
- * @param obj The ZoneParameters object.
- *
- * @return ptr The MemoryPointer.
- */
- function toMemoryPointer(
- ZoneParameters memory obj
- ) internal pure returns (MemoryPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-
- /**
- * @dev Get a CalldataPointer from ZoneParameters.
- *
- * @param obj The ZoneParameters object.
- *
- * @return ptr The CalldataPointer.
- */
- function toCalldataPointer(
- ZoneParameters calldata obj
- ) internal pure returns (CalldataPointer ptr) {
- assembly {
- ptr := obj
- }
- }
-}
diff --git a/contracts/lib/CounterManager.sol b/contracts/lib/CounterManager.sol
deleted file mode 100644
index 710411a17..000000000
--- a/contracts/lib/CounterManager.sol
+++ /dev/null
@@ -1,84 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- ConsiderationEventsAndErrors
-} from "../interfaces/ConsiderationEventsAndErrors.sol";
-
-import { ReentrancyGuard } from "./ReentrancyGuard.sol";
-
-import {
- Counter_blockhash_shift,
- OneWord,
- TwoWords
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title CounterManager
- * @author 0age
- * @notice CounterManager contains a storage mapping and related functionality
- * for retrieving and incrementing a per-offerer counter.
- */
-contract CounterManager is ConsiderationEventsAndErrors, ReentrancyGuard {
- // Only orders signed using an offerer's current counter are fulfillable.
- mapping(address => uint256) private _counters;
-
- /**
- * @dev Internal function to cancel all orders from a given offerer in bulk
- * by incrementing a counter by a large, quasi-random interval. Note
- * that only the offerer may increment the counter. Note that the
- * counter is incremented by a large, quasi-random interval, which
- * makes it infeasible to "activate" signed orders by incrementing the
- * counter. This activation functionality can be achieved instead with
- * restricted orders or contract orders.
- *
- * @return newCounter The new counter.
- */
- function _incrementCounter() internal returns (uint256 newCounter) {
- // Ensure that the reentrancy guard is not currently set.
- _assertNonReentrant();
-
- // Utilize assembly to access counters storage mapping directly. Skip
- // overflow check as counter cannot be incremented that far.
- assembly {
- // Use second half of previous block hash as a quasi-random number.
- let quasiRandomNumber := shr(
- Counter_blockhash_shift,
- blockhash(sub(number(), 1))
- )
-
- // Write the caller to scratch space.
- mstore(0, caller())
-
- // Write the storage slot for _counters to scratch space.
- mstore(OneWord, _counters.slot)
-
- // Derive the storage pointer for the counter value.
- let storagePointer := keccak256(0, TwoWords)
-
- // Derive new counter value using random number and original value.
- newCounter := add(quasiRandomNumber, sload(storagePointer))
-
- // Store the updated counter value.
- sstore(storagePointer, newCounter)
- }
-
- // Emit an event containing the new counter.
- emit CounterIncremented(newCounter, msg.sender);
- }
-
- /**
- * @dev Internal view function to retrieve the current counter for a given
- * offerer.
- *
- * @param offerer The offerer in question.
- *
- * @return currentCounter The current counter.
- */
- function _getCounter(
- address offerer
- ) internal view returns (uint256 currentCounter) {
- // Return the counter for the supplied offerer.
- currentCounter = _counters[offerer];
- }
-}
diff --git a/contracts/lib/CriteriaResolution.sol b/contracts/lib/CriteriaResolution.sol
deleted file mode 100644
index 076c3852d..000000000
--- a/contracts/lib/CriteriaResolution.sol
+++ /dev/null
@@ -1,347 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { ItemType, Side } from "./ConsiderationEnums.sol";
-
-import {
- AdvancedOrder,
- CriteriaResolver,
- MemoryPointer,
- OfferItem,
- OrderParameters
-} from "./ConsiderationStructs.sol";
-
-import {
- _revertCriteriaNotEnabledForItem,
- _revertInvalidProof,
- _revertOrderCriteriaResolverOutOfRange,
- _revertUnresolvedConsiderationCriteria,
- _revertUnresolvedOfferCriteria
-} from "./ConsiderationErrors.sol";
-
-import {
- CriteriaResolutionErrors
-} from "../interfaces/CriteriaResolutionErrors.sol";
-
-import {
- OneWord,
- OneWordShift,
- OrderParameters_consideration_head_offset,
- Selector_length,
- TwoWords
-} from "./ConsiderationConstants.sol";
-
-import {
- ConsiderationCriteriaResolverOutOfRange_err_selector,
- Error_selector_offset,
- OfferCriteriaResolverOutOfRange_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @title CriteriaResolution
- * @author 0age
- * @notice CriteriaResolution contains a collection of pure functions related to
- * resolving criteria-based items.
- */
-contract CriteriaResolution is CriteriaResolutionErrors {
- /**
- * @dev Internal pure function to apply criteria resolvers containing
- * specific token identifiers and associated proofs to order items.
- *
- * @param advancedOrders The orders to apply criteria resolvers to.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific order as well as that
- * order's offer or consideration, a token
- * identifier, and a proof that the supplied token
- * identifier is contained in the order's merkle
- * root. Note that a root of zero indicates that
- * any transferable token identifier is valid and
- * that no proof needs to be supplied.
- */
- function _applyCriteriaResolvers(
- AdvancedOrder[] memory advancedOrders,
- CriteriaResolver[] memory criteriaResolvers
- ) internal pure {
- // Skip overflow checks as all for loops are indexed starting at zero.
- unchecked {
- // Retrieve length of criteria resolvers array and place on stack.
- uint256 totalCriteriaResolvers = criteriaResolvers.length;
-
- // Retrieve length of orders array and place on stack.
- uint256 totalAdvancedOrders = advancedOrders.length;
-
- // Iterate over each criteria resolver.
- for (uint256 i = 0; i < totalCriteriaResolvers; ++i) {
- // Retrieve the criteria resolver.
- CriteriaResolver memory criteriaResolver = (
- criteriaResolvers[i]
- );
-
- // Read the order index from memory and place it on the stack.
- uint256 orderIndex = criteriaResolver.orderIndex;
-
- // Ensure that the order index is in range.
- if (orderIndex >= totalAdvancedOrders) {
- _revertOrderCriteriaResolverOutOfRange(
- criteriaResolver.side
- );
- }
-
- // Retrieve the referenced advanced order.
- AdvancedOrder memory advancedOrder = advancedOrders[orderIndex];
-
- // Skip criteria resolution for order if not fulfilled.
- if (advancedOrder.numerator == 0) {
- continue;
- }
-
- // Retrieve the parameters for the order.
- OrderParameters memory orderParameters = (
- advancedOrder.parameters
- );
-
- {
- // Get a pointer to the list of items to give to
- // _updateCriteriaItem. If the resolver refers to a
- // consideration item, this array pointer will be replaced
- // with the consideration array.
- OfferItem[] memory items = orderParameters.offer;
-
- // Read component index from memory and place it on stack.
- uint256 componentIndex = criteriaResolver.index;
-
- // Get error selector for `OfferCriteriaResolverOutOfRange`.
- uint256 errorSelector = (
- OfferCriteriaResolverOutOfRange_error_selector
- );
-
- // If the resolver refers to a consideration item...
- if (criteriaResolver.side != Side.OFFER) {
- // Get the pointer to `orderParameters.consideration`
- // Using the array directly has a significant impact on
- // the optimized compiler output.
- MemoryPointer considerationPtr = orderParameters
- .toMemoryPointer()
- .pptr(OrderParameters_consideration_head_offset);
-
- // Replace the items pointer with a pointer to the
- // consideration array.
- assembly {
- items := considerationPtr
- }
-
- // Replace the error selector with the selector for
- // `ConsiderationCriteriaResolverOutOfRange`.
- errorSelector = (
- ConsiderationCriteriaResolverOutOfRange_err_selector
- );
- }
-
- // Ensure that the component index is in range.
- if (componentIndex >= items.length) {
- assembly {
- // Revert with either
- // `OfferCriteriaResolverOutOfRange()` or
- // `ConsiderationCriteriaResolverOutOfRange()`,
- // depending on whether the resolver refers to a
- // consideration item.
- mstore(0, errorSelector)
- // revert(abi.encodeWithSignature(
- // "OfferCriteriaResolverOutOfRange()"
- // ))
- // or
- // revert(abi.encodeWithSignature(
- // "ConsiderationCriteriaResolverOutOfRange()"
- // ))
- revert(Error_selector_offset, Selector_length)
- }
- }
-
- // Apply the criteria resolver to the item in question.
- _updateCriteriaItem(
- items,
- componentIndex,
- criteriaResolver
- );
- }
- }
-
- // Iterate over each advanced order.
- for (uint256 i = 0; i < totalAdvancedOrders; ++i) {
- // Retrieve the advanced order.
- AdvancedOrder memory advancedOrder = advancedOrders[i];
-
- // Skip criteria resolution for order if not fulfilled.
- if (advancedOrder.numerator == 0) {
- continue;
- }
-
- // Retrieve the parameters for the order.
- OrderParameters memory orderParameters = (
- advancedOrder.parameters
- );
-
- // Read consideration length from memory and place on stack.
- uint256 totalItems = orderParameters.consideration.length;
-
- // Iterate over each consideration item on the order.
- for (uint256 j = 0; j < totalItems; ++j) {
- // Ensure item type no longer indicates criteria usage.
- if (
- _isItemWithCriteria(
- orderParameters.consideration[j].itemType
- )
- ) {
- _revertUnresolvedConsiderationCriteria(i, j);
- }
- }
-
- // Read offer length from memory and place on stack.
- totalItems = orderParameters.offer.length;
-
- // Iterate over each offer item on the order.
- for (uint256 j = 0; j < totalItems; ++j) {
- // Ensure item type no longer indicates criteria usage.
- if (
- _isItemWithCriteria(orderParameters.offer[j].itemType)
- ) {
- _revertUnresolvedOfferCriteria(i, j);
- }
- }
- }
- }
- }
-
- /**
- * @dev Internal pure function to update a criteria item.
- *
- * @param offer The offer containing the item to update.
- * @param componentIndex The index of the item to update.
- * @param criteriaResolver The criteria resolver to use to update the item.
- */
- function _updateCriteriaItem(
- OfferItem[] memory offer,
- uint256 componentIndex,
- CriteriaResolver memory criteriaResolver
- ) internal pure {
- // Retrieve relevant item using the component index.
- OfferItem memory offerItem = offer[componentIndex];
-
- // Read item type and criteria from memory & place on stack.
- ItemType itemType = offerItem.itemType;
-
- // Ensure the specified item type indicates criteria usage.
- if (!_isItemWithCriteria(itemType)) {
- _revertCriteriaNotEnabledForItem();
- }
-
- uint256 identifierOrCriteria = offerItem.identifierOrCriteria;
-
- // If criteria is not 0 (i.e. a collection-wide criteria-based item)...
- if (identifierOrCriteria != uint256(0)) {
- // Verify identifier inclusion in criteria root using proof.
- _verifyProof(
- criteriaResolver.identifier,
- identifierOrCriteria,
- criteriaResolver.criteriaProof
- );
- } else if (criteriaResolver.criteriaProof.length != 0) {
- // Revert if non-empty proof is supplied for a collection-wide item.
- _revertInvalidProof();
- }
-
- // Update item type to remove criteria usage.
- // Use assembly to operate on ItemType enum as a number.
- ItemType newItemType;
- assembly {
- // Item type 4 becomes 2 and item type 5 becomes 3.
- newItemType := sub(3, eq(itemType, 4))
- }
- offerItem.itemType = newItemType;
-
- // Update identifier w/ supplied identifier.
- offerItem.identifierOrCriteria = criteriaResolver.identifier;
- }
-
- /**
- * @dev Internal pure function to check whether a given item type represents
- * a criteria-based ERC721 or ERC1155 item (e.g. an item that can be
- * resolved to one of a number of different identifiers at the time of
- * order fulfillment).
- *
- * @param itemType The item type in question.
- *
- * @return withCriteria A boolean indicating that the item type in question
- * represents a criteria-based item.
- */
- function _isItemWithCriteria(
- ItemType itemType
- ) internal pure returns (bool withCriteria) {
- // ERC721WithCriteria is ItemType 4. ERC1155WithCriteria is ItemType 5.
- assembly {
- withCriteria := gt(itemType, 3)
- }
- }
-
- /**
- * @dev Internal pure function to ensure that a given element is contained
- * in a merkle root via a supplied proof.
- *
- * @param leaf The element for which to prove inclusion.
- * @param root The merkle root that inclusion will be proved against.
- * @param proof The merkle proof.
- */
- function _verifyProof(
- uint256 leaf,
- uint256 root,
- bytes32[] memory proof
- ) internal pure {
- // Declare a variable that will be used to determine proof validity.
- bool isValid;
-
- // Utilize assembly to efficiently verify the proof against the root.
- assembly {
- // Store the leaf at the beginning of scratch space.
- mstore(0, leaf)
-
- // Derive the hash of the leaf to use as the initial proof element.
- let computedHash := keccak256(0, OneWord)
-
- // Get memory start location of the first element in proof array.
- let data := add(proof, OneWord)
-
- // Iterate over each proof element to compute the root hash.
- for {
- // Left shift by 5 is equivalent to multiplying by 0x20.
- let end := add(data, shl(OneWordShift, mload(proof)))
- } lt(data, end) {
- // Increment by one word at a time.
- data := add(data, OneWord)
- } {
- // Get the proof element.
- let loadedData := mload(data)
-
- // Sort proof elements and place them in scratch space.
- // Slot of `computedHash` in scratch space.
- // If the condition is true: 0x20, otherwise: 0x00.
- let scratch := shl(OneWordShift, gt(computedHash, loadedData))
-
- // Store elements to hash contiguously in scratch space. Scratch
- // space is 64 bytes (0x00 - 0x3f) & both elements are 32 bytes.
- mstore(scratch, computedHash)
- mstore(xor(scratch, OneWord), loadedData)
-
- // Derive the updated hash.
- computedHash := keccak256(0, TwoWords)
- }
-
- // Compare the final hash to the supplied root.
- isValid := eq(computedHash, root)
- }
-
- // Revert if computed hash does not equal supplied root.
- if (!isValid) {
- _revertInvalidProof();
- }
- }
-}
diff --git a/contracts/lib/Executor.sol b/contracts/lib/Executor.sol
deleted file mode 100644
index ae2803592..000000000
--- a/contracts/lib/Executor.sol
+++ /dev/null
@@ -1,583 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
-
-import { ConduitItemType } from "../conduit/lib/ConduitEnums.sol";
-
-import { ItemType } from "./ConsiderationEnums.sol";
-
-import { ReceivedItem } from "./ConsiderationStructs.sol";
-
-import { Verifiers } from "./Verifiers.sol";
-
-import { TokenTransferrer } from "./TokenTransferrer.sol";
-
-import {
- Accumulator_array_length_ptr,
- Accumulator_array_offset_ptr,
- Accumulator_array_offset,
- Accumulator_conduitKey_ptr,
- Accumulator_itemSizeOffsetDifference,
- Accumulator_selector_ptr,
- AccumulatorArmed,
- AccumulatorDisarmed,
- Conduit_transferItem_amount_ptr,
- Conduit_transferItem_from_ptr,
- Conduit_transferItem_identifier_ptr,
- Conduit_transferItem_size,
- Conduit_transferItem_to_ptr,
- Conduit_transferItem_token_ptr,
- FreeMemoryPointerSlot,
- OneWord,
- TwoWords
-} from "./ConsiderationConstants.sol";
-
-import {
- Error_selector_offset,
- NativeTokenTransferGenericFailure_error_account_ptr,
- NativeTokenTransferGenericFailure_error_amount_ptr,
- NativeTokenTransferGenericFailure_error_length,
- NativeTokenTransferGenericFailure_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-import {
- _revertInvalidCallToConduit,
- _revertInvalidConduit,
- _revertInvalidERC721TransferAmount,
- _revertUnusedItemParameters
-} from "./ConsiderationErrors.sol";
-
-/**
- * @title Executor
- * @author 0age
- * @notice Executor contains functions related to processing executions (i.e.
- * transferring items, either directly or via conduits).
- */
-contract Executor is Verifiers, TokenTransferrer {
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(address conduitController) Verifiers(conduitController) {}
-
- /**
- * @dev Internal function to transfer a given item, either directly or via
- * a corresponding conduit.
- *
- * @param item The item to transfer, including an amount and a
- * recipient.
- * @param from The account supplying the item.
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- */
- function _transfer(
- ReceivedItem memory item,
- address from,
- bytes32 conduitKey,
- bytes memory accumulator
- ) internal {
- // If the item type indicates Ether or a native token...
- if (item.itemType == ItemType.NATIVE) {
- // Ensure neither the token nor the identifier parameters are set.
- if ((uint160(item.token) | item.identifier) != 0) {
- _revertUnusedItemParameters();
- }
-
- // transfer the native tokens to the recipient.
- _transferNativeTokens(item.recipient, item.amount);
- } else if (item.itemType == ItemType.ERC20) {
- // Ensure that no identifier is supplied.
- if (item.identifier != 0) {
- _revertUnusedItemParameters();
- }
-
- // Transfer ERC20 tokens from the source to the recipient.
- _transferERC20(
- item.token,
- from,
- item.recipient,
- item.amount,
- conduitKey,
- accumulator
- );
- } else if (item.itemType == ItemType.ERC721) {
- // Transfer ERC721 token from the source to the recipient.
- _transferERC721(
- item.token,
- from,
- item.recipient,
- item.identifier,
- item.amount,
- conduitKey,
- accumulator
- );
- } else {
- // Transfer ERC1155 token from the source to the recipient.
- _transferERC1155(
- item.token,
- from,
- item.recipient,
- item.identifier,
- item.amount,
- conduitKey,
- accumulator
- );
- }
- }
-
- /**
- * @dev Internal function to transfer Ether or other native tokens to a
- * given recipient.
- *
- * @param to The recipient of the transfer.
- * @param amount The amount to transfer.
- */
- function _transferNativeTokens(
- address payable to,
- uint256 amount
- ) internal {
- // Ensure that the supplied amount is non-zero.
- _assertNonZeroAmount(amount);
-
- // Declare a variable indicating whether the call was successful or not.
- bool success;
-
- assembly {
- // Transfer the native token and store if it succeeded or not.
- success := call(gas(), to, amount, 0, 0, 0, 0)
- }
-
- // If the call fails...
- if (!success) {
- // Revert and pass the revert reason along if one was returned.
- _revertWithReasonIfOneIsReturned();
-
- // Otherwise, revert with a generic error message.
- assembly {
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, NativeTokenTransferGenericFailure_error_selector)
-
- // Write `to` and `amount` arguments.
- mstore(NativeTokenTransferGenericFailure_error_account_ptr, to)
- mstore(
- NativeTokenTransferGenericFailure_error_amount_ptr,
- amount
- )
-
- // revert(abi.encodeWithSignature(
- // "NativeTokenTransferGenericFailure(address,uint256)",
- // to,
- // amount
- // ))
- revert(
- Error_selector_offset,
- NativeTokenTransferGenericFailure_error_length
- )
- }
- }
- }
-
- /**
- * @dev Internal function to transfer ERC20 tokens from a given originator
- * to a given recipient using a given conduit if applicable. Sufficient
- * approvals must be set on this contract or on a respective conduit.
- *
- * @param token The ERC20 token to transfer.
- * @param from The originator of the transfer.
- * @param to The recipient of the transfer.
- * @param amount The amount to transfer.
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- */
- function _transferERC20(
- address token,
- address from,
- address to,
- uint256 amount,
- bytes32 conduitKey,
- bytes memory accumulator
- ) internal {
- // Ensure that the supplied amount is non-zero.
- _assertNonZeroAmount(amount);
-
- // Trigger accumulated transfers if the conduits differ.
- _triggerIfArmedAndNotAccumulatable(accumulator, conduitKey);
-
- // If no conduit has been specified...
- if (conduitKey == bytes32(0)) {
- // Perform the token transfer directly.
- _performERC20Transfer(token, from, to, amount);
- } else {
- // Insert the call to the conduit into the accumulator.
- _insert(
- conduitKey,
- accumulator,
- ConduitItemType.ERC20,
- token,
- from,
- to,
- uint256(0),
- amount
- );
- }
- }
-
- /**
- * @dev Internal function to transfer a single ERC721 token from a given
- * originator to a given recipient. Sufficient approvals must be set,
- * either on the respective conduit or on this contract itself.
- *
- * @param token The ERC721 token to transfer.
- * @param from The originator of the transfer.
- * @param to The recipient of the transfer.
- * @param identifier The tokenId to transfer.
- * @param amount The amount to transfer (must be 1 for ERC721).
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- */
- function _transferERC721(
- address token,
- address from,
- address to,
- uint256 identifier,
- uint256 amount,
- bytes32 conduitKey,
- bytes memory accumulator
- ) internal {
- // Trigger accumulated transfers if the conduits differ.
- _triggerIfArmedAndNotAccumulatable(accumulator, conduitKey);
-
- // If no conduit has been specified...
- if (conduitKey == bytes32(0)) {
- // Ensure that exactly one 721 item is being transferred.
- if (amount != 1) {
- _revertInvalidERC721TransferAmount(amount);
- }
-
- // Perform transfer via the token contract directly.
- _performERC721Transfer(token, from, to, identifier);
- } else {
- // Insert the call to the conduit into the accumulator.
- _insert(
- conduitKey,
- accumulator,
- ConduitItemType.ERC721,
- token,
- from,
- to,
- identifier,
- amount
- );
- }
- }
-
- /**
- * @dev Internal function to transfer ERC1155 tokens from a given originator
- * to a given recipient. Sufficient approvals must be set, either on
- * the respective conduit or on this contract itself.
- *
- * @param token The ERC1155 token to transfer.
- * @param from The originator of the transfer.
- * @param to The recipient of the transfer.
- * @param identifier The id to transfer.
- * @param amount The amount to transfer.
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- */
- function _transferERC1155(
- address token,
- address from,
- address to,
- uint256 identifier,
- uint256 amount,
- bytes32 conduitKey,
- bytes memory accumulator
- ) internal {
- // Ensure that the supplied amount is non-zero.
- _assertNonZeroAmount(amount);
-
- // Trigger accumulated transfers if the conduits differ.
- _triggerIfArmedAndNotAccumulatable(accumulator, conduitKey);
-
- // If no conduit has been specified...
- if (conduitKey == bytes32(0)) {
- // Perform transfer via the token contract directly.
- _performERC1155Transfer(token, from, to, identifier, amount);
- } else {
- // Insert the call to the conduit into the accumulator.
- _insert(
- conduitKey,
- accumulator,
- ConduitItemType.ERC1155,
- token,
- from,
- to,
- identifier,
- amount
- );
- }
- }
-
- /**
- * @dev Internal function to trigger a call to the conduit currently held by
- * the accumulator if the accumulator contains item transfers (i.e. it
- * is "armed") and the supplied conduit key does not match the key held
- * by the accumulator.
- *
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- */
- function _triggerIfArmedAndNotAccumulatable(
- bytes memory accumulator,
- bytes32 conduitKey
- ) internal {
- // Retrieve the current conduit key from the accumulator.
- bytes32 accumulatorConduitKey = _getAccumulatorConduitKey(accumulator);
-
- // Perform conduit call if the set key does not match the supplied key.
- if (accumulatorConduitKey != conduitKey) {
- _triggerIfArmed(accumulator);
- }
- }
-
- /**
- * @dev Internal function to trigger a call to the conduit currently held by
- * the accumulator if the accumulator contains item transfers (i.e. it
- * is "armed").
- *
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- */
- function _triggerIfArmed(bytes memory accumulator) internal {
- // Exit if the accumulator is not "armed".
- if (accumulator.length != AccumulatorArmed) {
- return;
- }
-
- // Retrieve the current conduit key from the accumulator.
- bytes32 accumulatorConduitKey = _getAccumulatorConduitKey(accumulator);
-
- // Perform conduit call.
- _trigger(accumulatorConduitKey, accumulator);
- }
-
- /**
- * @dev Internal function to trigger a call to the conduit corresponding to
- * a given conduit key, supplying all accumulated item transfers. The
- * accumulator will be "disarmed" and reset in the process.
- *
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- */
- function _trigger(bytes32 conduitKey, bytes memory accumulator) internal {
- // Declare variables for offset in memory & size of calldata to conduit.
- uint256 callDataOffset;
- uint256 callDataSize;
-
- // Call the conduit with all the accumulated transfers.
- assembly {
- // Call begins at third word; the first is length or "armed" status,
- // and the second is the current conduit key.
- callDataOffset := add(accumulator, TwoWords)
-
- // 68 + items * 192
- callDataSize := add(
- Accumulator_array_offset_ptr,
- mul(
- mload(add(accumulator, Accumulator_array_length_ptr)),
- Conduit_transferItem_size
- )
- )
- }
-
- // Call conduit derived from conduit key & supply accumulated transfers.
- _callConduitUsingOffsets(conduitKey, callDataOffset, callDataSize);
-
- // Reset accumulator length to signal that it is now "disarmed".
- assembly {
- mstore(accumulator, AccumulatorDisarmed)
- }
- }
-
- /**
- * @dev Internal function to perform a call to the conduit corresponding to
- * a given conduit key based on the offset and size of the calldata in
- * question in memory.
- *
- * @param conduitKey A bytes32 value indicating what corresponding
- * conduit, if any, to source token approvals from.
- * The zero hash signifies that no conduit should be
- * used, with direct approvals set on this contract.
- * @param callDataOffset The memory pointer where calldata is contained.
- * @param callDataSize The size of calldata in memory.
- */
- function _callConduitUsingOffsets(
- bytes32 conduitKey,
- uint256 callDataOffset,
- uint256 callDataSize
- ) internal {
- // Derive the address of the conduit using the conduit key.
- address conduit = _deriveConduit(conduitKey);
-
- bool success;
- bytes4 result;
-
- // call the conduit.
- assembly {
- // Ensure first word of scratch space is empty.
- mstore(0, 0)
-
- // Perform call, placing first word of return data in scratch space.
- success := call(
- gas(),
- conduit,
- 0,
- callDataOffset,
- callDataSize,
- 0,
- OneWord
- )
-
- // Take value from scratch space and place it on the stack.
- result := mload(0)
- }
-
- // If the call failed...
- if (!success) {
- // Pass along whatever revert reason was given by the conduit.
- _revertWithReasonIfOneIsReturned();
-
- // Otherwise, revert with a generic error.
- _revertInvalidCallToConduit(conduit);
- }
-
- // Ensure result was extracted and matches the Conduit executor magic
- // value.
- if (result != ConduitInterface.execute.selector) {
- _revertInvalidConduit(conduitKey, conduit);
- }
- }
-
- /**
- * @dev Internal pure function to retrieve the current conduit key set for
- * the accumulator.
- *
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- *
- * @return accumulatorConduitKey The conduit key currently set for the
- * accumulator.
- */
- function _getAccumulatorConduitKey(
- bytes memory accumulator
- ) internal pure returns (bytes32 accumulatorConduitKey) {
- // Retrieve the current conduit key from the accumulator.
- assembly {
- accumulatorConduitKey := mload(
- add(accumulator, Accumulator_conduitKey_ptr)
- )
- }
- }
-
- /**
- * @dev Internal pure function to place an item transfer into an accumulator
- * that collects a series of transfers to execute against a given
- * conduit in a single call.
- *
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. The zero hash
- * signifies that no conduit should be used, with direct
- * approvals set on this contract.
- * @param accumulator An open-ended array that collects transfers to execute
- * against a given conduit in a single call.
- * @param itemType The type of the item to transfer.
- * @param token The token to transfer.
- * @param from The originator of the transfer.
- * @param to The recipient of the transfer.
- * @param identifier The tokenId to transfer.
- * @param amount The amount to transfer.
- */
- function _insert(
- bytes32 conduitKey,
- bytes memory accumulator,
- ConduitItemType itemType,
- address token,
- address from,
- address to,
- uint256 identifier,
- uint256 amount
- ) internal pure {
- uint256 elements;
- // "Arm" and prime accumulator if it's not already armed. The sentinel
- // value is held in the length of the accumulator array.
- if (accumulator.length == AccumulatorDisarmed) {
- elements = 1;
- bytes4 selector = ConduitInterface.execute.selector;
- assembly {
- mstore(accumulator, AccumulatorArmed) // "arm" the accumulator.
- mstore(add(accumulator, Accumulator_conduitKey_ptr), conduitKey)
- mstore(add(accumulator, Accumulator_selector_ptr), selector)
- mstore(
- add(accumulator, Accumulator_array_offset_ptr),
- Accumulator_array_offset
- )
- mstore(add(accumulator, Accumulator_array_length_ptr), elements)
- }
- } else {
- // Otherwise, increase the number of elements by one.
- assembly {
- elements := add(
- mload(add(accumulator, Accumulator_array_length_ptr)),
- 1
- )
- mstore(add(accumulator, Accumulator_array_length_ptr), elements)
- }
- }
-
- // Insert the item.
- assembly {
- let itemPointer := sub(
- add(accumulator, mul(elements, Conduit_transferItem_size)),
- Accumulator_itemSizeOffsetDifference
- )
- mstore(itemPointer, itemType)
- mstore(add(itemPointer, Conduit_transferItem_token_ptr), token)
- mstore(add(itemPointer, Conduit_transferItem_from_ptr), from)
- mstore(add(itemPointer, Conduit_transferItem_to_ptr), to)
- mstore(
- add(itemPointer, Conduit_transferItem_identifier_ptr),
- identifier
- )
- mstore(add(itemPointer, Conduit_transferItem_amount_ptr), amount)
- }
- }
-}
diff --git a/contracts/lib/FulfillmentApplier.sol b/contracts/lib/FulfillmentApplier.sol
deleted file mode 100644
index 3ed34ccb9..000000000
--- a/contracts/lib/FulfillmentApplier.sol
+++ /dev/null
@@ -1,782 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { ItemType, Side } from "./ConsiderationEnums.sol";
-
-import {
- AdvancedOrder,
- Execution,
- FulfillmentComponent,
- ReceivedItem
-} from "./ConsiderationStructs.sol";
-
-import {
- _revertMismatchedFulfillmentOfferAndConsiderationComponents,
- _revertMissingFulfillmentComponentOnAggregation,
- _revertOfferAndConsiderationRequiredOnFulfillment
-} from "./ConsiderationErrors.sol";
-
-import {
- FulfillmentApplicationErrors
-} from "../interfaces/FulfillmentApplicationErrors.sol";
-
-import {
- AdvancedOrder_numerator_offset,
- Common_amount_offset,
- Common_identifier_offset,
- Common_token_offset,
- Execution_conduit_offset,
- Execution_offerer_offset,
- Fulfillment_itemIndex_offset,
- OneWord,
- OneWordShift,
- OrderParameters_conduit_offset,
- OrderParameters_consideration_head_offset,
- OrderParameters_offer_head_offset,
- ReceivedItem_CommonParams_size,
- ReceivedItem_recipient_offset,
- ReceivedItem_size
-} from "./ConsiderationConstants.sol";
-
-import {
- Error_selector_offset,
- InvalidFulfillmentComponentData_error_length,
- InvalidFulfillmentComponentData_error_selector,
- MissingItemAmount_error_length,
- MissingItemAmount_error_selector,
- Panic_arithmetic,
- Panic_error_code_ptr,
- Panic_error_length,
- Panic_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @title FulfillmentApplier
- * @author 0age
- * @notice FulfillmentApplier contains logic related to applying fulfillments,
- * both as part of order matching (where offer items are matched to
- * consideration items) as well as fulfilling available orders (where
- * order items and consideration items are independently aggregated).
- */
-contract FulfillmentApplier is FulfillmentApplicationErrors {
- /**
- * @dev Internal pure function to match offer items to consideration items
- * on a group of orders via a supplied fulfillment.
- *
- * @param advancedOrders The orders to match.
- * @param offerComponents An array designating offer components to
- * match to consideration components.
- * @param considerationComponents An array designating consideration
- * components to match to offer components.
- * Note that each consideration amount must
- * be zero in order for the match operation
- * to be valid.
- * @param fulfillmentIndex The index of the fulfillment being
- * applied.
- *
- * @return execution The transfer performed as a result of the fulfillment.
- */
- function _applyFulfillment(
- AdvancedOrder[] memory advancedOrders,
- FulfillmentComponent[] memory offerComponents,
- FulfillmentComponent[] memory considerationComponents,
- uint256 fulfillmentIndex
- ) internal pure returns (Execution memory execution) {
- // Ensure 1+ of both offer and consideration components are supplied.
- if (
- offerComponents.length == 0 || considerationComponents.length == 0
- ) {
- _revertOfferAndConsiderationRequiredOnFulfillment();
- }
-
- // Declare a new Execution struct.
- Execution memory considerationExecution;
-
- // Validate & aggregate consideration items to new Execution object.
- _aggregateValidFulfillmentConsiderationItems(
- advancedOrders,
- considerationComponents,
- considerationExecution
- );
-
- // Retrieve the consideration item from the execution struct.
- ReceivedItem memory considerationItem = considerationExecution.item;
-
- // Skip aggregating offer items if no consideration items are available.
- if (considerationItem.amount == 0) {
- // Set the offerer and recipient to null address and the item type
- // to a non-native item type if the execution amount is zero. This
- // will cause the execution item to be skipped.
- considerationExecution.offerer = address(0);
- considerationExecution.item.recipient = payable(0);
- considerationExecution.item.itemType = ItemType.ERC20;
- return considerationExecution;
- }
-
- // Recipient does not need to be specified because it will always be set
- // to that of the consideration.
- // Validate & aggregate offer items to Execution object.
- _aggregateValidFulfillmentOfferItems(
- advancedOrders,
- offerComponents,
- execution
- );
-
- // Ensure offer & consideration item types, tokens, & identifiers match.
- // (a != b || c != d || e != f) == (((a ^ b) | (c ^ d) | (e ^ f)) != 0),
- // but the second expression requires less gas to evaluate.
- if (
- ((uint8(execution.item.itemType) ^
- uint8(considerationItem.itemType)) |
- (uint160(execution.item.token) ^
- uint160(considerationItem.token)) |
- (execution.item.identifier ^ considerationItem.identifier)) != 0
- ) {
- _revertMismatchedFulfillmentOfferAndConsiderationComponents(
- fulfillmentIndex
- );
- }
-
- // If total consideration amount exceeds the offer amount...
- if (considerationItem.amount > execution.item.amount) {
- // Retrieve the first consideration component from the fulfillment.
- FulfillmentComponent memory targetComponent = (
- considerationComponents[0]
- );
-
- // Skip underflow check as the conditional being true implies that
- // considerationItem.amount > execution.item.amount.
- unchecked {
- // Add excess consideration item amount to original order array.
- advancedOrders[targetComponent.orderIndex]
- .parameters
- .consideration[targetComponent.itemIndex]
- .startAmount = (considerationItem.amount -
- execution.item.amount);
- }
- } else {
- // Retrieve the first offer component from the fulfillment.
- FulfillmentComponent memory targetComponent = offerComponents[0];
-
- // Skip underflow check as the conditional being false implies that
- // execution.item.amount >= considerationItem.amount.
- unchecked {
- // Add excess offer item amount to the original array of orders.
- advancedOrders[targetComponent.orderIndex]
- .parameters
- .offer[targetComponent.itemIndex]
- .startAmount = (execution.item.amount -
- considerationItem.amount);
- }
-
- // Reduce total offer amount to equal the consideration amount.
- execution.item.amount = considerationItem.amount;
- }
-
- // Reuse consideration recipient.
- execution.item.recipient = considerationItem.recipient;
-
- // Return the final execution that will be triggered for relevant items.
- return execution; // Execution(considerationItem, offerer, conduitKey);
- }
-
- /**
- * @dev Internal view function to aggregate offer or consideration items
- * from a group of orders into a single execution via a supplied array
- * of fulfillment components. Items that are not available to aggregate
- * will not be included in the aggregated execution.
- *
- * @param advancedOrders The orders to aggregate.
- * @param side The side (i.e. offer or consideration).
- * @param fulfillmentComponents An array designating item components to
- * aggregate if part of an available order.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token
- * approvals from. The zero hash signifies that
- * no conduit should be used, with approvals
- * set directly on this contract.
- * @param recipient The intended recipient for all received
- * items.
- *
- * @return execution The transfer performed as a result of the fulfillment.
- */
- function _aggregateAvailable(
- AdvancedOrder[] memory advancedOrders,
- Side side,
- FulfillmentComponent[] memory fulfillmentComponents,
- bytes32 fulfillerConduitKey,
- address recipient
- ) internal view returns (Execution memory execution) {
- // Skip overflow / underflow checks; conditions checked or unreachable.
- unchecked {
- // Retrieve fulfillment components array length and place on stack.
- // Ensure at least one fulfillment component has been supplied.
- if (fulfillmentComponents.length == 0) {
- _revertMissingFulfillmentComponentOnAggregation(side);
- }
-
- // Retrieve the received item on the execution being returned.
- ReceivedItem memory item = execution.item;
-
- // If the fulfillment components are offer components...
- if (side == Side.OFFER) {
- // Set the supplied recipient on the execution item.
- item.recipient = payable(recipient);
-
- // Return execution for aggregated items provided by offerer.
- _aggregateValidFulfillmentOfferItems(
- advancedOrders,
- fulfillmentComponents,
- execution
- );
- } else {
- // Otherwise, fulfillment components are consideration
- // components. Return execution for aggregated items provided by
- // the fulfiller.
- _aggregateValidFulfillmentConsiderationItems(
- advancedOrders,
- fulfillmentComponents,
- execution
- );
-
- // Set the caller as the offerer on the execution.
- execution.offerer = msg.sender;
-
- // Set fulfiller conduit key as the conduit key on execution.
- execution.conduitKey = fulfillerConduitKey;
- }
-
- // Set the offerer and recipient to null address and the item type
- // to a non-native item type if the execution amount is zero. This
- // will cause the execution item to be skipped.
- if (item.amount == 0) {
- execution.offerer = address(0);
- item.recipient = payable(0);
- item.itemType = ItemType.ERC20;
- }
- }
- }
-
- /**
- * @dev Internal pure function to aggregate a group of offer items using
- * supplied directives on which component items are candidates for
- * aggregation, skipping items on orders that are not available.
- *
- * @param advancedOrders The orders to aggregate offer items from.
- * @param offerComponents An array of FulfillmentComponent structs
- * indicating the order index and item index of each
- * candidate offer item for aggregation.
- * @param execution The execution to apply the aggregation to.
- */
- function _aggregateValidFulfillmentOfferItems(
- AdvancedOrder[] memory advancedOrders,
- FulfillmentComponent[] memory offerComponents,
- Execution memory execution
- ) internal pure {
- assembly {
- // Declare a variable for the final aggregated item amount.
- let amount
-
- // Declare a variable to track errors encountered with amount.
- let errorBuffer
-
- // Declare a variable for the hash of itemType, token, & identifier.
- let dataHash
-
- // Iterate over each offer component.
- for {
- // Create variable to track position in offerComponents head.
- let fulfillmentHeadPtr := offerComponents
-
- // Get position one word past last element in head of array.
- let endPtr := add(
- offerComponents,
- shl(OneWordShift, mload(offerComponents))
- )
- } lt(fulfillmentHeadPtr, endPtr) {
-
- } {
- // Increment position in considerationComponents head.
- fulfillmentHeadPtr := add(fulfillmentHeadPtr, OneWord)
-
- // Retrieve the order index using the fulfillment pointer.
- let orderIndex := mload(mload(fulfillmentHeadPtr))
-
- // Ensure that the order index is not out of range.
- if iszero(lt(orderIndex, mload(advancedOrders))) {
- throwInvalidFulfillmentComponentData()
- }
-
- // Read advancedOrders[orderIndex] pointer from its array head.
- let orderPtr := mload(
- // Calculate head position of advancedOrders[orderIndex].
- add(
- add(advancedOrders, OneWord),
- shl(OneWordShift, orderIndex)
- )
- )
-
- // Read the pointer to OrderParameters from the AdvancedOrder.
- let paramsPtr := mload(orderPtr)
-
- // Retrieve item index using an offset of fulfillment pointer.
- let itemIndex := mload(
- add(mload(fulfillmentHeadPtr), Fulfillment_itemIndex_offset)
- )
-
- let offerItemPtr
- {
- // Load the offer array pointer.
- let offerArrPtr := mload(
- add(paramsPtr, OrderParameters_offer_head_offset)
- )
-
- // If the offer item index is out of range or the numerator
- // is zero, skip this item.
- if or(
- iszero(lt(itemIndex, mload(offerArrPtr))),
- iszero(
- mload(add(orderPtr, AdvancedOrder_numerator_offset))
- )
- ) {
- continue
- }
-
- // Retrieve offer item pointer using the item index.
- offerItemPtr := mload(
- add(
- // Get pointer to beginning of receivedItem.
- add(offerArrPtr, OneWord),
- // Calculate offset to pointer for desired order.
- shl(OneWordShift, itemIndex)
- )
- )
- }
-
- // Declare a separate scope for the amount update.
- {
- // Retrieve amount pointer using consideration item pointer.
- let amountPtr := add(offerItemPtr, Common_amount_offset)
-
- // Add offer item amount to execution amount.
- let newAmount := add(amount, mload(amountPtr))
-
- // Update error buffer:
- // 1 = zero amount, 2 = overflow, 3 = both.
- errorBuffer := or(
- errorBuffer,
- or(
- shl(1, lt(newAmount, amount)),
- iszero(mload(amountPtr))
- )
- )
-
- // Update the amount to the new, summed amount.
- amount := newAmount
-
- // Zero out amount on original item to indicate it is spent.
- mstore(amountPtr, 0)
- }
-
- // Retrieve ReceivedItem pointer from Execution.
- let receivedItem := mload(execution)
-
- // Check if this is the first valid fulfillment item.
- switch iszero(dataHash)
- case 1 {
- // On first valid item, populate the received item in memory
- // for later comparison.
-
- // Set the item type on the received item.
- mstore(receivedItem, mload(offerItemPtr))
-
- // Set the token on the received item.
- mstore(
- add(receivedItem, Common_token_offset),
- mload(add(offerItemPtr, Common_token_offset))
- )
-
- // Set the identifier on the received item.
- mstore(
- add(receivedItem, Common_identifier_offset),
- mload(add(offerItemPtr, Common_identifier_offset))
- )
-
- // Set offerer on returned execution using order pointer.
- mstore(
- add(execution, Execution_offerer_offset),
- mload(paramsPtr)
- )
-
- // Set execution conduitKey via order pointer offset.
- mstore(
- add(execution, Execution_conduit_offset),
- mload(add(paramsPtr, OrderParameters_conduit_offset))
- )
-
- // Calculate the hash of (itemType, token, identifier).
- dataHash := keccak256(
- receivedItem,
- ReceivedItem_CommonParams_size
- )
-
- // If component index > 0, swap component pointer with
- // pointer to first component so that any remainder after
- // fulfillment can be added back to the first item.
- let firstFulfillmentHeadPtr := add(offerComponents, OneWord)
- if xor(firstFulfillmentHeadPtr, fulfillmentHeadPtr) {
- let firstFulfillmentPtr := mload(
- firstFulfillmentHeadPtr
- )
- let fulfillmentPtr := mload(fulfillmentHeadPtr)
- mstore(firstFulfillmentHeadPtr, fulfillmentPtr)
- }
- }
- default {
- // Compare every subsequent item to the first.
- if or(
- or(
- // The offerer must match on both items.
- xor(
- mload(paramsPtr),
- mload(add(execution, Execution_offerer_offset))
- ),
- // The conduit key must match on both items.
- xor(
- mload(
- add(
- paramsPtr,
- OrderParameters_conduit_offset
- )
- ),
- mload(add(execution, Execution_conduit_offset))
- )
- ),
- // The itemType, token, and identifier must match.
- xor(
- dataHash,
- keccak256(
- offerItemPtr,
- ReceivedItem_CommonParams_size
- )
- )
- ) {
- // Throw if any of the requirements are not met.
- throwInvalidFulfillmentComponentData()
- }
- }
- }
-
- // Write final amount to execution.
- mstore(add(mload(execution), Common_amount_offset), amount)
-
- // Determine whether the error buffer contains a nonzero error code.
- if errorBuffer {
- // If errorBuffer is 1, an item had an amount of zero.
- if eq(errorBuffer, 1) {
- // Store left-padded selector with push4 (reduces bytecode)
- // mem[28:32] = selector
- mstore(0, MissingItemAmount_error_selector)
-
- // revert(abi.encodeWithSignature("MissingItemAmount()"))
- revert(
- Error_selector_offset,
- MissingItemAmount_error_length
- )
- }
-
- // If errorBuffer is not 1 or 0, the sum overflowed.
- // Panic!
- throwOverflow()
- }
-
- // Declare function for reverts on invalid fulfillment data.
- function throwInvalidFulfillmentComponentData() {
- // Store left-padded selector (uses push4 and reduces code size)
- mstore(0, InvalidFulfillmentComponentData_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "InvalidFulfillmentComponentData()"
- // ))
- revert(
- Error_selector_offset,
- InvalidFulfillmentComponentData_error_length
- )
- }
-
- // Declare function for reverts due to arithmetic overflows.
- function throwOverflow() {
- // Store the Panic error signature.
- mstore(0, Panic_error_selector)
- // Store the arithmetic (0x11) panic code.
- mstore(Panic_error_code_ptr, Panic_arithmetic)
- // revert(abi.encodeWithSignature("Panic(uint256)", 0x11))
- revert(Error_selector_offset, Panic_error_length)
- }
- }
- }
-
- /**
- * @dev Internal pure function to aggregate a group of consideration items
- * using supplied directives on which component items are candidates
- * for aggregation, skipping items on orders that are not available.
- * Note that this function depends on memory layout affected by an
- * earlier call to _validateOrdersAndPrepareToFulfill. The memory for
- * the consideration arrays needs to be updated before calling
- * _aggregateValidFulfillmentConsiderationItems.
- * _validateOrdersAndPrepareToFulfill is called in _matchAdvancedOrders
- * and _fulfillAvailableAdvancedOrders in the current version.
- *
- * @param advancedOrders The orders to aggregate consideration
- * items from.
- * @param considerationComponents An array of FulfillmentComponent structs
- * indicating the order index and item index
- * of each candidate consideration item for
- * aggregation.
- * @param execution The execution to apply the aggregation to.
- */
- function _aggregateValidFulfillmentConsiderationItems(
- AdvancedOrder[] memory advancedOrders,
- FulfillmentComponent[] memory considerationComponents,
- Execution memory execution
- ) internal pure {
- // Utilize assembly in order to efficiently aggregate the items.
- assembly {
- // Declare a variable for the final aggregated item amount.
- let amount
-
- // Create variable to track errors encountered with amount.
- let errorBuffer
-
- // Declare variable for hash(itemType, token, identifier, recipient)
- let dataHash
-
- // Iterate over each consideration component.
- for {
- // Track position in considerationComponents head.
- let fulfillmentHeadPtr := considerationComponents
-
- // Get position one word past last element in head of array.
- let endPtr := add(
- considerationComponents,
- shl(OneWordShift, mload(considerationComponents))
- )
- } lt(fulfillmentHeadPtr, endPtr) {
-
- } {
- // Increment position in considerationComponents head.
- fulfillmentHeadPtr := add(fulfillmentHeadPtr, OneWord)
-
- // Retrieve the order index using the fulfillment pointer.
- let orderIndex := mload(mload(fulfillmentHeadPtr))
-
- // Ensure that the order index is not out of range.
- if iszero(lt(orderIndex, mload(advancedOrders))) {
- throwInvalidFulfillmentComponentData()
- }
-
- // Read advancedOrders[orderIndex] pointer from its array head.
- let orderPtr := mload(
- // Calculate head position of advancedOrders[orderIndex].
- add(
- add(advancedOrders, OneWord),
- shl(OneWordShift, orderIndex)
- )
- )
-
- // Retrieve item index using an offset of fulfillment pointer.
- let itemIndex := mload(
- add(mload(fulfillmentHeadPtr), Fulfillment_itemIndex_offset)
- )
-
- let considerationItemPtr
- {
- // Load consideration array pointer.
- let considerationArrPtr := mload(
- add(
- // Read OrderParameters pointer from AdvancedOrder.
- mload(orderPtr),
- OrderParameters_consideration_head_offset
- )
- )
-
- // If the consideration item index is out of range or the
- // numerator is zero, skip this item.
- if or(
- iszero(lt(itemIndex, mload(considerationArrPtr))),
- iszero(
- mload(add(orderPtr, AdvancedOrder_numerator_offset))
- )
- ) {
- continue
- }
-
- // Retrieve consideration item pointer using the item index.
- considerationItemPtr := mload(
- add(
- // Get pointer to beginning of receivedItem.
- add(considerationArrPtr, OneWord),
- // Calculate offset to pointer for desired order.
- shl(OneWordShift, itemIndex)
- )
- )
- }
-
- // Declare a separate scope for the amount update.
- {
- // Retrieve amount pointer using consideration item pointer.
- let amountPtr := add(
- considerationItemPtr,
- Common_amount_offset
- )
-
- // Add consideration item amount to execution amount.
- let newAmount := add(amount, mload(amountPtr))
-
- // Update error buffer:
- // 1 = zero amount, 2 = overflow, 3 = both.
- errorBuffer := or(
- errorBuffer,
- or(
- shl(1, lt(newAmount, amount)),
- iszero(mload(amountPtr))
- )
- )
-
- // Update the amount to the new, summed amount.
- amount := newAmount
-
- // Zero out original item amount to indicate it is credited.
- mstore(amountPtr, 0)
- }
-
- // Retrieve ReceivedItem pointer from Execution.
- let receivedItem := mload(execution)
-
- switch iszero(dataHash)
- case 1 {
- // On first valid item, populate the received item in
- // memory for later comparison.
-
- // Set the item type on the received item.
- mstore(receivedItem, mload(considerationItemPtr))
-
- // Set the token on the received item.
- mstore(
- add(receivedItem, Common_token_offset),
- mload(add(considerationItemPtr, Common_token_offset))
- )
-
- // Set the identifier on the received item.
- mstore(
- add(receivedItem, Common_identifier_offset),
- mload(
- add(considerationItemPtr, Common_identifier_offset)
- )
- )
-
- // Set the recipient on the received item. Note that this
- // depends on the memory layout established by the
- // _validateOrdersAndPrepareToFulfill function.
- mstore(
- add(receivedItem, ReceivedItem_recipient_offset),
- mload(
- add(
- considerationItemPtr,
- ReceivedItem_recipient_offset
- )
- )
- )
-
- // Calculate the hash of (itemType, token, identifier,
- // recipient). This is run after amount is set to zero, so
- // there will be one blank word after identifier included in
- // the hash buffer.
- dataHash := keccak256(
- considerationItemPtr,
- ReceivedItem_size
- )
-
- // If component index > 0, swap component pointer with
- // pointer to first component so that any remainder after
- // fulfillment can be added back to the first item.
- let firstFulfillmentHeadPtr := add(
- considerationComponents,
- OneWord
- )
- if xor(firstFulfillmentHeadPtr, fulfillmentHeadPtr) {
- let firstFulfillmentPtr := mload(
- firstFulfillmentHeadPtr
- )
- let fulfillmentPtr := mload(fulfillmentHeadPtr)
- mstore(firstFulfillmentHeadPtr, fulfillmentPtr)
- }
- }
- default {
- // Compare every subsequent item to the first; the item
- // type, token, identifier and recipient must match.
- if xor(
- dataHash,
- // Calculate the hash of (itemType, token, identifier,
- // recipient). This is run after amount is set to zero,
- // so there will be one blank word after identifier
- // included in the hash buffer.
- keccak256(considerationItemPtr, ReceivedItem_size)
- ) {
- // Throw if any of the requirements are not met.
- throwInvalidFulfillmentComponentData()
- }
- }
- }
-
- // Retrieve ReceivedItem pointer from Execution.
- let receivedItem := mload(execution)
-
- // Write final amount to execution.
- mstore(add(receivedItem, Common_amount_offset), amount)
-
- // Determine whether the error buffer contains a nonzero error code.
- if errorBuffer {
- // If errorBuffer is 1, an item had an amount of zero.
- if eq(errorBuffer, 1) {
- // Store left-padded selector with push4, mem[28:32]
- mstore(0, MissingItemAmount_error_selector)
-
- // revert(abi.encodeWithSignature("MissingItemAmount()"))
- revert(
- Error_selector_offset,
- MissingItemAmount_error_length
- )
- }
-
- // If errorBuffer is not 1 or 0, `amount` overflowed.
- // Panic!
- throwOverflow()
- }
-
- // Declare function for reverts on invalid fulfillment data.
- function throwInvalidFulfillmentComponentData() {
- // Store the InvalidFulfillmentComponentData error signature.
- mstore(0, InvalidFulfillmentComponentData_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "InvalidFulfillmentComponentData()"
- // ))
- revert(
- Error_selector_offset,
- InvalidFulfillmentComponentData_error_length
- )
- }
-
- // Declare function for reverts due to arithmetic overflows.
- function throwOverflow() {
- // Store the Panic error signature.
- mstore(0, Panic_error_selector)
- // Store the arithmetic (0x11) panic code.
- mstore(Panic_error_code_ptr, Panic_arithmetic)
- // revert(abi.encodeWithSignature("Panic(uint256)", 0x11))
- revert(Error_selector_offset, Panic_error_length)
- }
- }
- }
-}
diff --git a/contracts/lib/GettersAndDerivers.sol b/contracts/lib/GettersAndDerivers.sol
deleted file mode 100644
index 46ff51f3a..000000000
--- a/contracts/lib/GettersAndDerivers.sol
+++ /dev/null
@@ -1,392 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { OrderParameters } from "./ConsiderationStructs.sol";
-
-import { ConsiderationBase } from "./ConsiderationBase.sol";
-
-import {
- Create2AddressDerivation_length,
- Create2AddressDerivation_ptr,
- EIP_712_PREFIX,
- EIP712_ConsiderationItem_size,
- EIP712_DigestPayload_size,
- EIP712_DomainSeparator_offset,
- EIP712_OfferItem_size,
- EIP712_Order_size,
- EIP712_OrderHash_offset,
- FreeMemoryPointerSlot,
- information_conduitController_offset,
- information_domainSeparator_offset,
- information_length,
- information_version_cd_offset,
- information_version_offset,
- information_versionLengthPtr,
- information_versionWithLength,
- MaskOverByteTwelve,
- MaskOverLastTwentyBytes,
- OneWord,
- OneWordShift,
- OrderParameters_consideration_head_offset,
- OrderParameters_counter_offset,
- OrderParameters_offer_head_offset,
- TwoWords
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title GettersAndDerivers
- * @author 0age
- * @notice ConsiderationInternal contains pure and internal view functions
- * related to getting or deriving various values.
- */
-contract GettersAndDerivers is ConsiderationBase {
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(
- address conduitController
- ) ConsiderationBase(conduitController) {}
-
- /**
- * @dev Internal view function to derive the order hash for a given order.
- * Note that only the original consideration items are included in the
- * order hash, as additional consideration items may be supplied by the
- * caller.
- *
- * @param orderParameters The parameters of the order to hash.
- * @param counter The counter of the order to hash.
- *
- * @return orderHash The hash.
- */
- function _deriveOrderHash(
- OrderParameters memory orderParameters,
- uint256 counter
- ) internal view returns (bytes32 orderHash) {
- // Get length of original consideration array and place it on the stack.
- uint256 originalConsiderationLength = (
- orderParameters.totalOriginalConsiderationItems
- );
-
- /*
- * Memory layout for an array of structs (dynamic or not) is similar
- * to ABI encoding of dynamic types, with a head segment followed by
- * a data segment. The main difference is that the head of an element
- * is a memory pointer rather than an offset.
- */
-
- // Declare a variable for the derived hash of the offer array.
- bytes32 offerHash;
-
- // Read offer item EIP-712 typehash from runtime code & place on stack.
- bytes32 typeHash = _OFFER_ITEM_TYPEHASH;
-
- // Utilize assembly so that memory regions can be reused across hashes.
- assembly {
- // Retrieve the free memory pointer and place on the stack.
- let hashArrPtr := mload(FreeMemoryPointerSlot)
-
- // Get the pointer to the offers array.
- let offerArrPtr := mload(
- add(orderParameters, OrderParameters_offer_head_offset)
- )
-
- // Load the length.
- let offerLength := mload(offerArrPtr)
-
- // Set the pointer to the first offer's head.
- offerArrPtr := add(offerArrPtr, OneWord)
-
- // Iterate over the offer items.
- for { let i := 0 } lt(i, offerLength) {
- i := add(i, 1)
- } {
- // Read the pointer to the offer data and subtract one word
- // to get typeHash pointer.
- let ptr := sub(mload(offerArrPtr), OneWord)
-
- // Read the current value before the offer data.
- let value := mload(ptr)
-
- // Write the type hash to the previous word.
- mstore(ptr, typeHash)
-
- // Take the EIP712 hash and store it in the hash array.
- mstore(hashArrPtr, keccak256(ptr, EIP712_OfferItem_size))
-
- // Restore the previous word.
- mstore(ptr, value)
-
- // Increment the array pointers by one word.
- offerArrPtr := add(offerArrPtr, OneWord)
- hashArrPtr := add(hashArrPtr, OneWord)
- }
-
- // Derive the offer hash using the hashes of each item.
- offerHash := keccak256(
- mload(FreeMemoryPointerSlot),
- shl(OneWordShift, offerLength)
- )
- }
-
- // Declare a variable for the derived hash of the consideration array.
- bytes32 considerationHash;
-
- // Read consideration item typehash from runtime code & place on stack.
- typeHash = _CONSIDERATION_ITEM_TYPEHASH;
-
- // Utilize assembly so that memory regions can be reused across hashes.
- assembly {
- // Retrieve the free memory pointer and place on the stack.
- let hashArrPtr := mload(FreeMemoryPointerSlot)
-
- // Get the pointer to the consideration array.
- let considerationArrPtr := add(
- mload(
- add(
- orderParameters,
- OrderParameters_consideration_head_offset
- )
- ),
- OneWord
- )
-
- // Iterate over the consideration items (not including tips).
- for { let i := 0 } lt(i, originalConsiderationLength) {
- i := add(i, 1)
- } {
- // Read the pointer to the consideration data and subtract one
- // word to get typeHash pointer.
- let ptr := sub(mload(considerationArrPtr), OneWord)
-
- // Read the current value before the consideration data.
- let value := mload(ptr)
-
- // Write the type hash to the previous word.
- mstore(ptr, typeHash)
-
- // Take the EIP712 hash and store it in the hash array.
- mstore(
- hashArrPtr,
- keccak256(ptr, EIP712_ConsiderationItem_size)
- )
-
- // Restore the previous word.
- mstore(ptr, value)
-
- // Increment the array pointers by one word.
- considerationArrPtr := add(considerationArrPtr, OneWord)
- hashArrPtr := add(hashArrPtr, OneWord)
- }
-
- // Derive the consideration hash using the hashes of each item.
- considerationHash := keccak256(
- mload(FreeMemoryPointerSlot),
- shl(OneWordShift, originalConsiderationLength)
- )
- }
-
- // Read order item EIP-712 typehash from runtime code & place on stack.
- typeHash = _ORDER_TYPEHASH;
-
- // Utilize assembly to access derived hashes & other arguments directly.
- assembly {
- // Retrieve pointer to the region located just behind parameters.
- let typeHashPtr := sub(orderParameters, OneWord)
-
- // Store the value at that pointer location to restore later.
- let previousValue := mload(typeHashPtr)
-
- // Store the order item EIP-712 typehash at the typehash location.
- mstore(typeHashPtr, typeHash)
-
- // Retrieve the pointer for the offer array head.
- let offerHeadPtr := add(
- orderParameters,
- OrderParameters_offer_head_offset
- )
-
- // Retrieve the data pointer referenced by the offer head.
- let offerDataPtr := mload(offerHeadPtr)
-
- // Store the offer hash at the retrieved memory location.
- mstore(offerHeadPtr, offerHash)
-
- // Retrieve the pointer for the consideration array head.
- let considerationHeadPtr := add(
- orderParameters,
- OrderParameters_consideration_head_offset
- )
-
- // Retrieve the data pointer referenced by the consideration head.
- let considerationDataPtr := mload(considerationHeadPtr)
-
- // Store the consideration hash at the retrieved memory location.
- mstore(considerationHeadPtr, considerationHash)
-
- // Retrieve the pointer for the counter.
- let counterPtr := add(
- orderParameters,
- OrderParameters_counter_offset
- )
-
- // Store the counter at the retrieved memory location.
- mstore(counterPtr, counter)
-
- // Derive the order hash using the full range of order parameters.
- orderHash := keccak256(typeHashPtr, EIP712_Order_size)
-
- // Restore the value previously held at typehash pointer location.
- mstore(typeHashPtr, previousValue)
-
- // Restore offer data pointer at the offer head pointer location.
- mstore(offerHeadPtr, offerDataPtr)
-
- // Restore consideration data pointer at the consideration head ptr.
- mstore(considerationHeadPtr, considerationDataPtr)
-
- // Restore consideration item length at the counter pointer.
- mstore(counterPtr, originalConsiderationLength)
- }
- }
-
- /**
- * @dev Internal view function to derive the address of a given conduit
- * using a corresponding conduit key.
- *
- * @param conduitKey A bytes32 value indicating what corresponding conduit,
- * if any, to source token approvals from. This value is
- * the "salt" parameter supplied by the deployer (i.e. the
- * conduit controller) when deploying the given conduit.
- *
- * @return conduit The address of the conduit associated with the given
- * conduit key.
- */
- function _deriveConduit(
- bytes32 conduitKey
- ) internal view returns (address conduit) {
- // Read conduit controller address from runtime and place on the stack.
- address conduitController = address(_CONDUIT_CONTROLLER);
-
- // Read conduit creation code hash from runtime and place on the stack.
- bytes32 conduitCreationCodeHash = _CONDUIT_CREATION_CODE_HASH;
-
- // Leverage scratch space to perform an efficient hash.
- assembly {
- // Retrieve the free memory pointer; it will be replaced afterwards.
- let freeMemoryPointer := mload(FreeMemoryPointerSlot)
-
- // Place the control character and the conduit controller in scratch
- // space; note that eleven bytes at the beginning are left unused.
- mstore(0, or(MaskOverByteTwelve, conduitController))
-
- // Place the conduit key in the next region of scratch space.
- mstore(OneWord, conduitKey)
-
- // Place conduit creation code hash in free memory pointer location.
- mstore(TwoWords, conduitCreationCodeHash)
-
- // Derive conduit by hashing and applying a mask over last 20 bytes.
- conduit := and(
- // Hash the relevant region.
- keccak256(
- // The region starts at memory pointer 11.
- Create2AddressDerivation_ptr,
- // The region is 85 bytes long (1 + 20 + 32 + 32).
- Create2AddressDerivation_length
- ),
- // The address equals the last twenty bytes of the hash.
- MaskOverLastTwentyBytes
- )
-
- // Restore the free memory pointer.
- mstore(FreeMemoryPointerSlot, freeMemoryPointer)
- }
- }
-
- /**
- * @dev Internal view function to get the EIP-712 domain separator. If the
- * chainId matches the chainId set on deployment, the cached domain
- * separator will be returned; otherwise, it will be derived from
- * scratch.
- *
- * @return The domain separator.
- */
- function _domainSeparator() internal view returns (bytes32) {
- return block.chainid == _CHAIN_ID
- ? _DOMAIN_SEPARATOR
- : _deriveDomainSeparator();
- }
-
- /**
- * @dev Internal view function to retrieve configuration information for
- * this contract.
- *
- * @return The contract version.
- * @return The domain separator for this contract.
- * @return The conduit Controller set for this contract.
- */
- function _information()
- internal
- view
- returns (
- string memory /* version */,
- bytes32 /* domainSeparator */,
- address /* conduitController */
- )
- {
- // Derive the domain separator.
- bytes32 domainSeparator = _domainSeparator();
-
- // Declare variable as immutables cannot be accessed within assembly.
- address conduitController = address(_CONDUIT_CONTROLLER);
-
- // Return the version, domain separator, and conduit controller.
- assembly {
- mstore(information_version_offset, information_version_cd_offset)
- mstore(information_domainSeparator_offset, domainSeparator)
- mstore(information_conduitController_offset, conduitController)
- mstore(information_versionLengthPtr, information_versionWithLength)
- return(information_version_offset, information_length)
- }
- }
-
- /**
- * @dev Internal pure function to efficiently derive an digest to sign for
- * an order in accordance with EIP-712.
- *
- * @param domainSeparator The domain separator.
- * @param orderHash The order hash.
- *
- * @return value The hash.
- */
- function _deriveEIP712Digest(
- bytes32 domainSeparator,
- bytes32 orderHash
- ) internal pure returns (bytes32 value) {
- // Leverage scratch space to perform an efficient hash.
- assembly {
- // Place the EIP-712 prefix at the start of scratch space.
- mstore(0, EIP_712_PREFIX)
-
- // Place the domain separator in the next region of scratch space.
- mstore(EIP712_DomainSeparator_offset, domainSeparator)
-
- // Place the order hash in scratch space, spilling into the first
- // two bytes of the free memory pointer — this should never be set
- // as memory cannot be expanded to that size, and will be zeroed out
- // after the hash is performed.
- mstore(EIP712_OrderHash_offset, orderHash)
-
- // Hash the relevant region (65 bytes).
- value := keccak256(0, EIP712_DigestPayload_size)
-
- // Clear out the dirtied bits in the memory pointer.
- mstore(EIP712_OrderHash_offset, 0)
- }
- }
-}
diff --git a/contracts/lib/LowLevelHelpers.sol b/contracts/lib/LowLevelHelpers.sol
deleted file mode 100644
index 882410510..000000000
--- a/contracts/lib/LowLevelHelpers.sol
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- CostPerWord,
- ExtraGasBuffer,
- FreeMemoryPointerSlot,
- MemoryExpansionCoefficientShift,
- OneWord,
- OneWordShift,
- ThirtyOneBytes
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title LowLevelHelpers
- * @author 0age
- * @notice LowLevelHelpers contains logic for performing various low-level
- * operations.
- */
-contract LowLevelHelpers {
- /**
- * @dev Internal view function to revert and pass along the revert reason if
- * data was returned by the last call and that the size of that data
- * does not exceed the currently allocated memory size.
- */
- function _revertWithReasonIfOneIsReturned() internal view {
- assembly {
- // If it returned a message, bubble it up as long as sufficient gas
- // remains to do so:
- if returndatasize() {
- // Ensure that sufficient gas is available to copy returndata
- // while expanding memory where necessary. Start by computing
- // the word size of returndata and allocated memory.
- let returnDataWords := shr(
- OneWordShift,
- add(returndatasize(), ThirtyOneBytes)
- )
-
- // Note: use the free memory pointer in place of msize() to work
- // around a Yul warning that prevents accessing msize directly
- // when the IR pipeline is activated.
- let msizeWords := shr(
- OneWordShift,
- mload(FreeMemoryPointerSlot)
- )
-
- // Next, compute the cost of the returndatacopy.
- let cost := mul(CostPerWord, returnDataWords)
-
- // Then, compute cost of new memory allocation.
- if gt(returnDataWords, msizeWords) {
- cost := add(
- cost,
- add(
- mul(sub(returnDataWords, msizeWords), CostPerWord),
- shr(
- MemoryExpansionCoefficientShift,
- sub(
- mul(returnDataWords, returnDataWords),
- mul(msizeWords, msizeWords)
- )
- )
- )
- )
- }
-
- // Finally, add a small constant and compare to gas remaining;
- // bubble up the revert data if enough gas is still available.
- if lt(add(cost, ExtraGasBuffer), gas()) {
- // Copy returndata to memory; overwrite existing memory.
- returndatacopy(0, 0, returndatasize())
-
- // Revert, specifying memory region with copied returndata.
- revert(0, returndatasize())
- }
- }
- }
- }
-
- /**
- * @dev Internal view function to branchlessly select either the caller (if
- * a supplied recipient is equal to zero) or the supplied recipient (if
- * that recipient is a nonzero value).
- *
- * @param recipient The supplied recipient.
- *
- * @return updatedRecipient The updated recipient.
- */
- function _substituteCallerForEmptyRecipient(
- address recipient
- ) internal view returns (address updatedRecipient) {
- // Utilize assembly to perform a branchless operation on the recipient.
- assembly {
- // Add caller to recipient if recipient equals 0; otherwise add 0.
- updatedRecipient := add(recipient, mul(iszero(recipient), caller()))
- }
- }
-
- /**
- * @dev Internal pure function to cast a `bool` value to a `uint256` value.
- *
- * @param b The `bool` value to cast.
- *
- * @return u The `uint256` value.
- */
- function _cast(bool b) internal pure returns (uint256 u) {
- assembly {
- u := b
- }
- }
-}
diff --git a/contracts/lib/OrderCombiner.sol b/contracts/lib/OrderCombiner.sol
deleted file mode 100644
index fb26f83aa..000000000
--- a/contracts/lib/OrderCombiner.sol
+++ /dev/null
@@ -1,1155 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { Side, ItemType, OrderType } from "./ConsiderationEnums.sol";
-
-import {
- AdvancedOrder,
- ConsiderationItem,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- OfferItem,
- OrderParameters,
- ReceivedItem
-} from "./ConsiderationStructs.sol";
-
-import { OrderFulfiller } from "./OrderFulfiller.sol";
-
-import { FulfillmentApplier } from "./FulfillmentApplier.sol";
-
-import {
- _revertConsiderationNotMet,
- _revertInsufficientNativeTokensSupplied,
- _revertInvalidNativeOfferItem,
- _revertNoSpecifiedOrdersAvailable
-} from "./ConsiderationErrors.sol";
-
-import {
- AccumulatorDisarmed,
- ConsiderationItem_recipient_offset,
- Execution_offerer_offset,
- NonMatchSelector_InvalidErrorValue,
- NonMatchSelector_MagicMask,
- OneWord,
- OneWordShift,
- OrdersMatchedTopic0,
- ReceivedItem_amount_offset,
- ReceivedItem_recipient_offset,
- TwoWords
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title OrderCombiner
- * @author 0age
- * @notice OrderCombiner contains logic for fulfilling combinations of orders,
- * either by matching offer items to consideration items or by
- * fulfilling orders where available.
- */
-contract OrderCombiner is OrderFulfiller, FulfillmentApplier {
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(address conduitController) OrderFulfiller(conduitController) {}
-
- /**
- * @notice Internal function to attempt to fill a group of orders, fully or
- * partially, with an arbitrary number of items for offer and
- * consideration per order alongside criteria resolvers containing
- * specific token identifiers and associated proofs. Any order that
- * is not currently active, has already been fully filled, or has
- * been cancelled will be omitted. Remaining offer and consideration
- * items will then be aggregated where possible as indicated by the
- * supplied offer and consideration component arrays and aggregated
- * items will be transferred to the fulfiller or to each intended
- * recipient, respectively. Note that a failing item transfer or an
- * issue with order formatting will cause the entire batch to fail.
- *
- * @param advancedOrders The orders to fulfill along with the
- * fraction of those orders to attempt to
- * fill. Note that both the offerer and the
- * fulfiller must first approve this
- * contract (or a conduit if indicated by
- * the order) to transfer any relevant
- * tokens on their behalf and that
- * contracts must implement
- * `onERC1155Received` in order to receive
- * ERC1155 tokens as consideration. Also
- * note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount
- * with the supplied fraction for an
- * order's partial fill amount to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a
- * proof that the supplied token identifier
- * is contained in the merkle root held by
- * the item in question's criteria element.
- * Note that an empty criteria indicates
- * that any (transferable) token
- * identifier on the token in question is
- * valid and that no associated proof needs
- * to be supplied.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used (and
- * direct approvals set on Consideration).
- * @param recipient The intended recipient for all received
- * items.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function _fulfillAvailableAdvancedOrders(
- AdvancedOrder[] memory advancedOrders,
- CriteriaResolver[] memory criteriaResolvers,
- FulfillmentComponent[][] memory offerFulfillments,
- FulfillmentComponent[][] memory considerationFulfillments,
- bytes32 fulfillerConduitKey,
- address recipient,
- uint256 maximumFulfilled
- )
- internal
- returns (
- bool[] memory /* availableOrders */,
- Execution[] memory /* executions */
- )
- {
- // Validate orders, apply amounts, & determine if they use conduits.
- (
- bytes32[] memory orderHashes,
- bool containsNonOpen
- ) = _validateOrdersAndPrepareToFulfill(
- advancedOrders,
- criteriaResolvers,
- false, // Signifies that invalid orders should NOT revert.
- maximumFulfilled,
- recipient
- );
-
- // Aggregate used offer and consideration items and execute transfers.
- return
- _executeAvailableFulfillments(
- advancedOrders,
- offerFulfillments,
- considerationFulfillments,
- fulfillerConduitKey,
- recipient,
- orderHashes,
- containsNonOpen
- );
- }
-
- /**
- * @dev Internal function to validate a group of orders, update their
- * statuses, reduce amounts by their previously filled fractions, apply
- * criteria resolvers, and emit OrderFulfilled events. Note that this
- * function needs to be called before
- * _aggregateValidFulfillmentConsiderationItems to set the memory
- * layout that _aggregateValidFulfillmentConsiderationItems depends on.
- *
- * @param advancedOrders The advanced orders to validate and reduce by
- * their previously filled amounts.
- * @param criteriaResolvers An array where each element contains a reference
- * to a specific order as well as that order's
- * offer or consideration, a token identifier, and
- * a proof that the supplied token identifier is
- * contained in the order's merkle root. Note that
- * a root of zero indicates that any transferable
- * token identifier is valid and that no proof
- * needs to be supplied.
- * @param revertOnInvalid A boolean indicating whether to revert on any
- * order being invalid; setting this to false will
- * instead cause the invalid order to be skipped.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- * @param recipient The intended recipient for all items that do not
- * already have a designated recipient and are not
- * already used as part of a provided fulfillment.
- *
- * @return orderHashes The hashes of the orders being fulfilled.
- * @return containsNonOpen A boolean indicating whether any restricted or
- * contract orders are present within the provided
- * array of advanced orders.
- */
- function _validateOrdersAndPrepareToFulfill(
- AdvancedOrder[] memory advancedOrders,
- CriteriaResolver[] memory criteriaResolvers,
- bool revertOnInvalid,
- uint256 maximumFulfilled,
- address recipient
- ) internal returns (bytes32[] memory orderHashes, bool containsNonOpen) {
- // Ensure this function cannot be triggered during a reentrant call.
- _setReentrancyGuard(true); // Native tokens accepted during execution.
-
- // Declare an error buffer indicating status of any native offer items.
- // Native tokens may only be provided as part of contract orders or when
- // fulfilling via matchOrders or matchAdvancedOrders; if bits indicating
- // these conditions are not met have been set, throw.
- uint256 invalidNativeOfferItemErrorBuffer;
-
- // Use assembly to set the value for the second bit of the error buffer.
- assembly {
- /**
- * Use the 231st bit of the error buffer to indicate whether the
- * current function is not matchAdvancedOrders or matchOrders.
- *
- * sig func
- * -----------------------------------------------------------------
- * 1010100000010111010001000 0 000100 matchOrders
- * 1111001011010001001010110 0 010010 matchAdvancedOrders
- * 1110110110011000101001010 1 110100 fulfillAvailableOrders
- * 1000011100100000000110110 1 000001 fulfillAvailableAdvancedOrders
- * ^ 7th bit
- */
- invalidNativeOfferItemErrorBuffer := and(
- NonMatchSelector_MagicMask,
- calldataload(0)
- )
- }
-
- // Declare variables for later use.
- AdvancedOrder memory advancedOrder;
- uint256 terminalMemoryOffset;
-
- unchecked {
- // Read length of orders array and place on the stack.
- uint256 totalOrders = advancedOrders.length;
-
- // Track the order hash for each order being fulfilled.
- orderHashes = new bytes32[](totalOrders);
-
- // Determine the memory offset to terminate on during loops.
- terminalMemoryOffset = (totalOrders + 1) << OneWordShift;
- }
-
- // Skip overflow checks as all for loops are indexed starting at zero.
- unchecked {
- // Declare inner variables.
- OfferItem[] memory offer;
- ConsiderationItem[] memory consideration;
-
- // Iterate over each order.
- for (uint256 i = OneWord; i < terminalMemoryOffset; i += OneWord) {
- // Retrieve order using assembly to bypass out-of-range check.
- assembly {
- advancedOrder := mload(add(advancedOrders, i))
- }
-
- // Determine if max number orders have already been fulfilled.
- if (maximumFulfilled == 0) {
- // Mark fill fraction as zero as the order will not be used.
- advancedOrder.numerator = 0;
-
- // Continue iterating through the remaining orders.
- continue;
- }
-
- // Validate it, update status, and determine fraction to fill.
- (
- bytes32 orderHash,
- uint256 numerator,
- uint256 denominator
- ) = _validateOrderAndUpdateStatus(
- advancedOrder,
- revertOnInvalid
- );
-
- // Do not track hash or adjust prices if order is not fulfilled.
- if (numerator == 0) {
- // Mark fill fraction as zero if the order is not fulfilled.
- advancedOrder.numerator = 0;
-
- // Continue iterating through the remaining orders.
- continue;
- }
-
- // Otherwise, track the order hash in question.
- assembly {
- mstore(add(orderHashes, i), orderHash)
- }
-
- // Decrement the number of fulfilled orders.
- // Skip underflow check as the condition before
- // implies that maximumFulfilled > 0.
- --maximumFulfilled;
-
- // Place the start time for the order on the stack.
- uint256 startTime = advancedOrder.parameters.startTime;
-
- // Place the end time for the order on the stack.
- uint256 endTime = advancedOrder.parameters.endTime;
-
- // Retrieve array of offer items for the order in question.
- offer = advancedOrder.parameters.offer;
-
- // Read length of offer array and place on the stack.
- uint256 totalOfferItems = offer.length;
-
- {
- // Determine the order type, used to check for eligibility
- // for native token offer items as well as for the presence
- // of restricted and contract orders (or non-open orders).
- OrderType orderType = advancedOrder.parameters.orderType;
-
- // Utilize assembly to efficiently check for order types.
- // Note that these checks expect that there are no order
- // types beyond the current set (0-4) and will need to be
- // modified if more order types are added.
- assembly {
- // Declare a variable indicating if the order is not a
- // contract order. Cache in scratch space to avoid stack
- // depth errors.
- let isNonContract := lt(orderType, 4)
- mstore(0, isNonContract)
-
- // Update the variable indicating if the order is not an
- // open order, remaining set if it has been set already.
- containsNonOpen := or(containsNonOpen, gt(orderType, 1))
- }
- }
-
- // Iterate over each offer item on the order.
- for (uint256 j = 0; j < totalOfferItems; ++j) {
- // Retrieve the offer item.
- OfferItem memory offerItem = offer[j];
-
- // If the offer item is for the native token and the order
- // type is not a contract order type, set the first bit of
- // the error buffer to true.
- assembly {
- invalidNativeOfferItemErrorBuffer := or(
- invalidNativeOfferItemErrorBuffer,
- lt(mload(offerItem), mload(0))
- )
- }
-
- // Apply order fill fraction to offer item end amount.
- uint256 endAmount = _getFraction(
- numerator,
- denominator,
- offerItem.endAmount
- );
-
- // Reuse same fraction if start and end amounts are equal.
- if (offerItem.startAmount == offerItem.endAmount) {
- // Apply derived amount to both start and end amount.
- offerItem.startAmount = endAmount;
- } else {
- // Apply order fill fraction to offer item start amount.
- offerItem.startAmount = _getFraction(
- numerator,
- denominator,
- offerItem.startAmount
- );
- }
-
- // Adjust offer amount using current time; round down.
- uint256 currentAmount = _locateCurrentAmount(
- offerItem.startAmount,
- endAmount,
- startTime,
- endTime,
- false // round down
- );
-
- // Update amounts in memory to match the current amount.
- // Note that the end amount is used to track spent amounts.
- offerItem.startAmount = currentAmount;
- offerItem.endAmount = currentAmount;
- }
-
- // Retrieve array of consideration items for order in question.
- consideration = (advancedOrder.parameters.consideration);
-
- // Read length of consideration array and place on the stack.
- uint256 totalConsiderationItems = consideration.length;
-
- // Iterate over each consideration item on the order.
- for (uint256 j = 0; j < totalConsiderationItems; ++j) {
- // Retrieve the consideration item.
- ConsiderationItem memory considerationItem = (
- consideration[j]
- );
-
- // Apply fraction to consideration item end amount.
- uint256 endAmount = _getFraction(
- numerator,
- denominator,
- considerationItem.endAmount
- );
-
- // Reuse same fraction if start and end amounts are equal.
- if (
- considerationItem.startAmount ==
- considerationItem.endAmount
- ) {
- // Apply derived amount to both start and end amount.
- considerationItem.startAmount = endAmount;
- } else {
- // Apply fraction to consideration item start amount.
- considerationItem.startAmount = _getFraction(
- numerator,
- denominator,
- considerationItem.startAmount
- );
- }
-
- // Adjust consideration amount using current time; round up.
- uint256 currentAmount = (
- _locateCurrentAmount(
- considerationItem.startAmount,
- endAmount,
- startTime,
- endTime,
- true // round up
- )
- );
-
- considerationItem.startAmount = currentAmount;
-
- // Utilize assembly to manually "shift" the recipient value,
- // then to copy the start amount to the recipient.
- // Note that this sets up the memory layout that is
- // subsequently relied upon by
- // _aggregateValidFulfillmentConsiderationItems.
- assembly {
- // Derive the pointer to the recipient using the item
- // pointer along with the offset to the recipient.
- let considerationItemRecipientPtr := add(
- considerationItem,
- ConsiderationItem_recipient_offset // recipient
- )
-
- // Write recipient to endAmount, as endAmount is not
- // used from this point on and can be repurposed to fit
- // the layout of a ReceivedItem.
- mstore(
- add(
- considerationItem,
- ReceivedItem_recipient_offset // old endAmount
- ),
- mload(considerationItemRecipientPtr)
- )
-
- // Write startAmount to recipient, as recipient is not
- // used from this point on and can be repurposed to
- // track received amounts.
- mstore(considerationItemRecipientPtr, currentAmount)
- }
- }
- }
- }
-
- // If the first bit is set, a native offer item was encountered on an
- // order that is not a contract order. If the 231st bit is set in the
- // error buffer, the current function is not matchOrders or
- // matchAdvancedOrders. If the value is 1 + (1 << 230), then both the
- // 1st and 231st bits were set; in that case, revert with an error.
- if (
- invalidNativeOfferItemErrorBuffer ==
- NonMatchSelector_InvalidErrorValue
- ) {
- _revertInvalidNativeOfferItem();
- }
-
- // Apply criteria resolvers to each order as applicable.
- _applyCriteriaResolvers(advancedOrders, criteriaResolvers);
-
- // Emit an event for each order signifying that it has been fulfilled.
- // Skip overflow checks as all for loops are indexed starting at zero.
- unchecked {
- bytes32 orderHash;
-
- // Iterate over each order.
- for (uint256 i = OneWord; i < terminalMemoryOffset; i += OneWord) {
- assembly {
- orderHash := mload(add(orderHashes, i))
- }
-
- // Do not emit an event if no order hash is present.
- if (orderHash == bytes32(0)) {
- continue;
- }
-
- // Retrieve order using assembly to bypass out-of-range check.
- assembly {
- advancedOrder := mload(add(advancedOrders, i))
- }
-
- // Retrieve parameters for the order in question.
- OrderParameters memory orderParameters = (
- advancedOrder.parameters
- );
-
- // Emit an OrderFulfilled event.
- _emitOrderFulfilledEvent(
- orderHash,
- orderParameters.offerer,
- orderParameters.zone,
- recipient,
- orderParameters.offer,
- orderParameters.consideration
- );
- }
- }
- }
-
- /**
- * @dev Internal function to fulfill a group of validated orders, fully or
- * partially, with an arbitrary number of items for offer and
- * consideration per order and to execute transfers. Any order that is
- * not currently active, has already been fully filled, or has been
- * cancelled will be omitted. Remaining offer and consideration items
- * will then be aggregated where possible as indicated by the supplied
- * offer and consideration component arrays and aggregated items will
- * be transferred to the fulfiller or to each intended recipient,
- * respectively. Note that a failing item transfer or an issue with
- * order formatting will cause the entire batch to fail.
- *
- * @param advancedOrders The orders to fulfill along with the
- * fraction of those orders to attempt to
- * fill. Note that both the offerer and the
- * fulfiller must first approve this
- * contract (or the conduit if indicated by
- * the order) to transfer any relevant
- * tokens on their behalf and that
- * contracts must implement
- * `onERC1155Received` in order to receive
- * ERC1155 tokens as consideration. Also
- * note that all offer and consideration
- * components must have no remainder after
- * multiplication of the respective amount
- * with the supplied fraction for an
- * order's partial fill amount to be
- * considered valid.
- * @param offerFulfillments An array of FulfillmentComponent arrays
- * indicating which offer items to attempt
- * to aggregate when preparing executions.
- * @param considerationFulfillments An array of FulfillmentComponent arrays
- * indicating which consideration items to
- * attempt to aggregate when preparing
- * executions.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit,
- * if any, to source the fulfiller's token
- * approvals from. The zero hash signifies
- * that no conduit should be used, with
- * direct approvals set on Consideration.
- * @param recipient The intended recipient for all items
- * that do not already have a designated
- * recipient and are not already used as
- * part of a provided fulfillment.
- * @param orderHashes An array of order hashes for each order.
- * @param containsNonOpen A boolean indicating whether any
- * restricted or contract orders are
- * present within the provided array of
- * advanced orders.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function _executeAvailableFulfillments(
- AdvancedOrder[] memory advancedOrders,
- FulfillmentComponent[][] memory offerFulfillments,
- FulfillmentComponent[][] memory considerationFulfillments,
- bytes32 fulfillerConduitKey,
- address recipient,
- bytes32[] memory orderHashes,
- bool containsNonOpen
- )
- internal
- returns (bool[] memory availableOrders, Execution[] memory executions)
- {
- // Retrieve length of offer fulfillments array and place on the stack.
- uint256 totalOfferFulfillments = offerFulfillments.length;
-
- // Retrieve length of consideration fulfillments array & place on stack.
- uint256 totalConsiderationFulfillments = (
- considerationFulfillments.length
- );
-
- // Allocate an execution for each offer and consideration fulfillment.
- executions = new Execution[](
- totalOfferFulfillments + totalConsiderationFulfillments
- );
-
- // Skip overflow checks as all for loops are indexed starting at zero.
- unchecked {
- // Track number of filtered executions.
- uint256 totalFilteredExecutions = 0;
-
- // Iterate over each offer fulfillment.
- for (uint256 i = 0; i < totalOfferFulfillments; ) {
- // Derive aggregated execution corresponding with fulfillment.
- Execution memory execution = _aggregateAvailable(
- advancedOrders,
- Side.OFFER,
- offerFulfillments[i],
- fulfillerConduitKey,
- recipient
- );
-
- // If the execution is filterable...
- if (_isFilterableExecution(execution)) {
- // Increment total filtered executions.
- ++totalFilteredExecutions;
- } else {
- // Otherwise, assign the execution to the executions array.
- executions[i - totalFilteredExecutions] = execution;
- }
-
- // Increment iterator.
- ++i;
- }
-
- // Iterate over each consideration fulfillment.
- for (uint256 i = 0; i < totalConsiderationFulfillments; ) {
- // Derive aggregated execution corresponding with fulfillment.
- Execution memory execution = _aggregateAvailable(
- advancedOrders,
- Side.CONSIDERATION,
- considerationFulfillments[i],
- fulfillerConduitKey,
- address(0) // unused
- );
-
- // If the execution is filterable...
- if (_isFilterableExecution(execution)) {
- // Increment total filtered executions.
- ++totalFilteredExecutions;
- } else {
- // Otherwise, assign the execution to the executions array.
- executions[
- i + totalOfferFulfillments - totalFilteredExecutions
- ] = execution;
- }
-
- // Increment iterator.
- ++i;
- }
-
- // If some number of executions have been filtered...
- if (totalFilteredExecutions != 0) {
- // reduce the total length of the executions array.
- assembly {
- mstore(
- executions,
- sub(mload(executions), totalFilteredExecutions)
- )
- }
- }
- }
-
- // Revert if no orders are available.
- if (executions.length == 0) {
- _revertNoSpecifiedOrdersAvailable();
- }
-
- // Perform final checks and return.
- availableOrders = _performFinalChecksAndExecuteOrders(
- advancedOrders,
- executions,
- orderHashes,
- recipient,
- containsNonOpen
- );
-
- return (availableOrders, executions);
- }
-
- /**
- * @dev Internal function to perform a final check that each consideration
- * item for an arbitrary number of fulfilled orders has been met and to
- * trigger associated executions, transferring the respective items.
- *
- * @param advancedOrders The orders to check and perform executions for.
- * @param executions An array of elements indicating the sequence of
- * transfers to perform when fulfilling the given
- * orders.
- * @param orderHashes An array of order hashes for each order.
- * @param recipient The intended recipient for all items that do not
- * already have a designated recipient and are not
- * used as part of a provided fulfillment.
- * @param containsNonOpen A boolean indicating whether any restricted or
- * contract orders are present within the provided
- * array of advanced orders.
- *
- * @return availableOrders An array of booleans indicating if each order
- * with an index corresponding to the index of the
- * returned boolean was fulfillable or not.
- */
- function _performFinalChecksAndExecuteOrders(
- AdvancedOrder[] memory advancedOrders,
- Execution[] memory executions,
- bytes32[] memory orderHashes,
- address recipient,
- bool containsNonOpen
- ) internal returns (bool[] memory /* availableOrders */) {
- // Retrieve the length of the advanced orders array and place on stack.
- uint256 totalOrders = advancedOrders.length;
-
- // Initialize array for tracking available orders.
- bool[] memory availableOrders = new bool[](totalOrders);
-
- // Initialize an accumulator array. From this point forward, no new
- // memory regions can be safely allocated until the accumulator is no
- // longer being utilized, as the accumulator operates in an open-ended
- // fashion from this memory pointer; existing memory may still be
- // accessed and modified, however.
- bytes memory accumulator = new bytes(AccumulatorDisarmed);
-
- {
- // Declare a variable for the available native token balance.
- uint256 nativeTokenBalance;
-
- // Retrieve the length of the executions array and place on stack.
- uint256 totalExecutions = executions.length;
-
- // Iterate over each execution.
- for (uint256 i = 0; i < totalExecutions; ) {
- // Retrieve the execution and the associated received item.
- Execution memory execution = executions[i];
- ReceivedItem memory item = execution.item;
-
- // If execution transfers native tokens, reduce value available.
- if (item.itemType == ItemType.NATIVE) {
- // Get the current available balance of native tokens.
- assembly {
- nativeTokenBalance := selfbalance()
- }
-
- // Ensure that sufficient native tokens are still available.
- if (item.amount > nativeTokenBalance) {
- _revertInsufficientNativeTokensSupplied();
- }
- }
-
- // Transfer the item specified by the execution.
- _transfer(
- item,
- execution.offerer,
- execution.conduitKey,
- accumulator
- );
-
- // Skip overflow check as for loop is indexed starting at zero.
- unchecked {
- ++i;
- }
- }
- }
-
- // Skip overflow checks as all for loops are indexed starting at zero.
- unchecked {
- // Iterate over each order.
- for (uint256 i = 0; i < totalOrders; ++i) {
- // Retrieve the order in question.
- AdvancedOrder memory advancedOrder = advancedOrders[i];
-
- // Skip the order in question if not being not fulfilled.
- if (advancedOrder.numerator == 0) {
- // Explicitly set availableOrders at the given index to
- // guard against the possibility of dirtied memory.
- availableOrders[i] = false;
- continue;
- }
-
- // Mark the order as available.
- availableOrders[i] = true;
-
- // Retrieve the order parameters.
- OrderParameters memory parameters = advancedOrder.parameters;
-
- {
- // Retrieve offer items.
- OfferItem[] memory offer = parameters.offer;
-
- // Read length of offer array & place on the stack.
- uint256 totalOfferItems = offer.length;
-
- // Iterate over each offer item to restore it.
- for (uint256 j = 0; j < totalOfferItems; ++j) {
- // Retrieve the offer item in question.
- OfferItem memory offerItem = offer[j];
-
- // Transfer to recipient if unspent amount is not zero.
- // Note that the transfer will not be reflected in the
- // executions array.
- if (offerItem.startAmount != 0) {
- // Replace the endAmount parameter with the recipient to
- // make offerItem compatible with the ReceivedItem input
- // to _transfer and cache the original endAmount so it
- // can be restored after the transfer.
- uint256 originalEndAmount = _replaceEndAmountWithRecipient(
- offerItem,
- recipient
- );
-
- // Transfer excess offer item amount to recipient.
- _toOfferItemInput(_transfer)(
- offerItem,
- parameters.offerer,
- parameters.conduitKey,
- accumulator
- );
-
- // Restore the original endAmount in offerItem.
- assembly {
- mstore(
- add(
- offerItem,
- ReceivedItem_recipient_offset
- ),
- originalEndAmount
- )
- }
- }
-
- // Restore original amount on the offer item.
- offerItem.startAmount = offerItem.endAmount;
- }
- }
-
- {
- // Read consideration items & ensure they are fulfilled.
- ConsiderationItem[] memory consideration = (
- parameters.consideration
- );
-
- // Read length of consideration array & place on stack.
- uint256 totalConsiderationItems = consideration.length;
-
- // Iterate over each consideration item.
- for (uint256 j = 0; j < totalConsiderationItems; ++j) {
- ConsiderationItem memory considerationItem = (
- consideration[j]
- );
-
- // Retrieve remaining amount on consideration item.
- uint256 unmetAmount = considerationItem.startAmount;
-
- // Revert if the remaining amount is not zero.
- if (unmetAmount != 0) {
- _revertConsiderationNotMet(i, j, unmetAmount);
- }
-
- // Utilize assembly to restore the original value.
- assembly {
- // Write recipient to startAmount.
- mstore(
- add(
- considerationItem,
- ReceivedItem_amount_offset
- ),
- mload(
- add(
- considerationItem,
- ConsiderationItem_recipient_offset
- )
- )
- )
- }
- }
- }
- }
- }
-
- // Trigger any accumulated transfers via call to the conduit.
- _triggerIfArmed(accumulator);
-
- // Determine whether any native token balance remains.
- uint256 remainingNativeTokenBalance;
- assembly {
- remainingNativeTokenBalance := selfbalance()
- }
-
- // Return any remaining native token balance to the caller.
- if (remainingNativeTokenBalance != 0) {
- _transferNativeTokens(
- payable(msg.sender),
- remainingNativeTokenBalance
- );
- }
-
- // If any restricted or contract orders are present in the group of
- // orders being fulfilled, perform any validateOrder or ratifyOrder
- // calls after all executions and related transfers are complete.
- if (containsNonOpen) {
- // Iterate over each order a second time.
- for (uint256 i = 0; i < totalOrders; ) {
- // Ensure the order in question is being fulfilled.
- if (availableOrders[i]) {
- // Check restricted orders and contract orders.
- _assertRestrictedAdvancedOrderValidity(
- advancedOrders[i],
- orderHashes,
- orderHashes[i]
- );
- }
-
- // Skip overflow checks as for loop is indexed starting at zero.
- unchecked {
- ++i;
- }
- }
- }
-
- // Clear the reentrancy guard.
- _clearReentrancyGuard();
-
- // Return the array containing available orders.
- return availableOrders;
- }
-
- /**
- * @dev Internal function to emit an OrdersMatched event using the same
- * memory region as the existing order hash array.
- *
- * @param orderHashes An array of order hashes to include as an argument for
- * the OrdersMatched event.
- */
- function _emitOrdersMatched(bytes32[] memory orderHashes) internal {
- assembly {
- // Load the array length from memory.
- let length := mload(orderHashes)
-
- // Get the full size of the event data - one word for the offset,
- // one for the array length and one per hash.
- let dataSize := add(TwoWords, shl(OneWordShift, length))
-
- // Get pointer to start of data, reusing word before array length
- // for the offset.
- let dataPointer := sub(orderHashes, OneWord)
-
- // Cache the existing word in memory at the offset pointer.
- let cache := mload(dataPointer)
-
- // Write an offset of 32.
- mstore(dataPointer, OneWord)
-
- // Emit the OrdersMatched event.
- log1(dataPointer, dataSize, OrdersMatchedTopic0)
-
- // Restore the cached word.
- mstore(dataPointer, cache)
- }
- }
-
- /**
- * @dev Internal function to match an arbitrary number of full or partial
- * orders, each with an arbitrary number of items for offer and
- * consideration, supplying criteria resolvers containing specific
- * token identifiers and associated proofs as well as fulfillments
- * allocating offer components to consideration components.
- *
- * @param advancedOrders The advanced orders to match. Note that both the
- * offerer and fulfiller on each order must first
- * approve this contract (or their conduit if
- * indicated by the order) to transfer any relevant
- * tokens on their behalf and each consideration
- * recipient must implement `onERC1155Received` in
- * order to receive ERC1155 tokens. Also note that
- * the offer and consideration components for each
- * order must have no remainder after multiplying
- * the respective amount with the supplied fraction
- * in order for the group of partial fills to be
- * considered valid.
- * @param criteriaResolvers An array where each element contains a reference
- * to a specific order as well as that order's
- * offer or consideration, a token identifier, and
- * a proof that the supplied token identifier is
- * contained in the order's merkle root. Note that
- * an empty root indicates that any (transferable)
- * token identifier is valid and that no associated
- * proof needs to be supplied.
- * @param fulfillments An array of elements allocating offer components
- * to consideration components. Note that each
- * consideration component must be fully met in
- * order for the match operation to be valid.
- * @param recipient The intended recipient for all unspent offer
- * item amounts.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function _matchAdvancedOrders(
- AdvancedOrder[] memory advancedOrders,
- CriteriaResolver[] memory criteriaResolvers,
- Fulfillment[] memory fulfillments,
- address recipient
- ) internal returns (Execution[] memory /* executions */) {
- // Validate orders, update order status, and determine item amounts.
- (
- bytes32[] memory orderHashes,
- bool containsNonOpen
- ) = _validateOrdersAndPrepareToFulfill(
- advancedOrders,
- criteriaResolvers,
- true, // Signifies that invalid orders should revert.
- advancedOrders.length,
- recipient
- );
-
- // Emit OrdersMatched event, providing an array of matched order hashes.
- _emitOrdersMatched(orderHashes);
-
- // Fulfill the orders using the supplied fulfillments and recipient.
- return
- _fulfillAdvancedOrders(
- advancedOrders,
- fulfillments,
- orderHashes,
- recipient,
- containsNonOpen
- );
- }
-
- /**
- * @dev Internal function to fulfill an arbitrary number of orders, either
- * full or partial, after validating, adjusting amounts, and applying
- * criteria resolvers.
- *
- * @param advancedOrders The orders to match, including a fraction to
- * attempt to fill for each order.
- * @param fulfillments An array of elements allocating offer components
- * to consideration components. Note that the final
- * amount of each consideration component must be
- * zero for a match operation to be considered valid.
- * @param orderHashes An array of order hashes for each order.
- * @param recipient The intended recipient for all items that do not
- * already have a designated recipient and are not
- * used as part of a provided fulfillment.
- * @param containsNonOpen A boolean indicating whether any restricted or
- * contract orders are present within the provided
- * array of advanced orders.
- *
- * @return executions An array of elements indicating the sequence of
- * transfers performed as part of matching the given
- * orders.
- */
- function _fulfillAdvancedOrders(
- AdvancedOrder[] memory advancedOrders,
- Fulfillment[] memory fulfillments,
- bytes32[] memory orderHashes,
- address recipient,
- bool containsNonOpen
- ) internal returns (Execution[] memory executions) {
- // Retrieve fulfillments array length and place on the stack.
- uint256 totalFulfillments = fulfillments.length;
-
- // Allocate executions by fulfillment and apply them to each execution.
- executions = new Execution[](totalFulfillments);
-
- // Skip overflow checks as all for loops are indexed starting at zero.
- unchecked {
- // Track number of filtered executions.
- uint256 totalFilteredExecutions = 0;
-
- // Iterate over each fulfillment.
- for (uint256 i = 0; i < totalFulfillments; ++i) {
- /// Retrieve the fulfillment in question.
- Fulfillment memory fulfillment = fulfillments[i];
-
- // Derive the execution corresponding with the fulfillment.
- Execution memory execution = _applyFulfillment(
- advancedOrders,
- fulfillment.offerComponents,
- fulfillment.considerationComponents,
- i
- );
-
- // If the execution is filterable...
- if (_isFilterableExecution(execution)) {
- // Increment total filtered executions.
- ++totalFilteredExecutions;
- } else {
- // Otherwise, assign the execution to the executions array.
- executions[i - totalFilteredExecutions] = execution;
- }
- }
-
- // If some number of executions have been filtered...
- if (totalFilteredExecutions != 0) {
- // reduce the total length of the executions array.
- assembly {
- mstore(
- executions,
- sub(mload(executions), totalFilteredExecutions)
- )
- }
- }
- }
-
- // Perform final checks and execute orders.
- _performFinalChecksAndExecuteOrders(
- advancedOrders,
- executions,
- orderHashes,
- recipient,
- containsNonOpen
- );
-
- // Return the executions array.
- return executions;
- }
-
- /**
- * @dev Internal pure function to determine whether a given execution is
- * filterable and may be removed from the executions array. The offerer
- * and the recipient must be the same address and the item type cannot
- * indicate a native token transfer.
- *
- * @param execution The execution to check for filterability.
- *
- * @return filterable A boolean indicating whether the execution in question
- * can be filtered from the executions array.
- */
- function _isFilterableExecution(
- Execution memory execution
- ) internal pure returns (bool filterable) {
- // Utilize assembly to efficiently determine if execution is filterable.
- assembly {
- // Retrieve the received item referenced by the execution.
- let item := mload(execution)
-
- // Determine whether the execution is filterable.
- filterable := and(
- // Determine if offerer and recipient are the same address.
- eq(
- // Retrieve the recipient's address from the received item.
- mload(add(item, ReceivedItem_recipient_offset)),
- // Retrieve the offerer's address from the execution.
- mload(add(execution, Execution_offerer_offset))
- ),
- // Determine if received item's item type is non-zero, thereby
- // indicating that the execution does not involve native tokens.
- iszero(iszero(mload(item)))
- )
- }
- }
-}
diff --git a/contracts/lib/OrderFulfiller.sol b/contracts/lib/OrderFulfiller.sol
deleted file mode 100644
index 50cc91480..000000000
--- a/contracts/lib/OrderFulfiller.sol
+++ /dev/null
@@ -1,430 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { ItemType, OrderType } from "./ConsiderationEnums.sol";
-
-import {
- AdvancedOrder,
- ConsiderationItem,
- CriteriaResolver,
- OfferItem,
- OrderParameters,
- ReceivedItem,
- SpentItem
-} from "./ConsiderationStructs.sol";
-
-import { BasicOrderFulfiller } from "./BasicOrderFulfiller.sol";
-
-import { CriteriaResolution } from "./CriteriaResolution.sol";
-
-import { AmountDeriver } from "./AmountDeriver.sol";
-
-import {
- _revertInsufficientNativeTokensSupplied,
- _revertInvalidNativeOfferItem
-} from "./ConsiderationErrors.sol";
-
-import {
- AccumulatorDisarmed,
- ConsiderationItem_recipient_offset,
- ReceivedItem_amount_offset,
- ReceivedItem_recipient_offset
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title OrderFulfiller
- * @author 0age
- * @notice OrderFulfiller contains logic related to order fulfillment where a
- * single order is being fulfilled and where basic order fulfillment is
- * not available as an option.
- */
-contract OrderFulfiller is
- BasicOrderFulfiller,
- CriteriaResolution,
- AmountDeriver
-{
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(
- address conduitController
- ) BasicOrderFulfiller(conduitController) {}
-
- /**
- * @dev Internal function to validate an order and update its status, adjust
- * prices based on current time, apply criteria resolvers, determine
- * what portion to fill, and transfer relevant tokens.
- *
- * @param advancedOrder The order to fulfill as well as the fraction
- * to fill. Note that all offer and consideration
- * components must divide with no remainder for
- * the partial fill to be valid.
- * @param criteriaResolvers An array where each element contains a
- * reference to a specific offer or
- * consideration, a token identifier, and a proof
- * that the supplied token identifier is
- * contained in the order's merkle root. Note
- * that a criteria of zero indicates that any
- * (transferable) token identifier is valid and
- * that no proof needs to be supplied.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Consideration.
- * @param recipient The intended recipient for all received items.
- *
- * @return A boolean indicating whether the order has been fulfilled.
- */
- function _validateAndFulfillAdvancedOrder(
- AdvancedOrder memory advancedOrder,
- CriteriaResolver[] memory criteriaResolvers,
- bytes32 fulfillerConduitKey,
- address recipient
- ) internal returns (bool) {
- // Ensure this function cannot be triggered during a reentrant call.
- _setReentrancyGuard(
- // Native tokens accepted during execution for contract order types.
- advancedOrder.parameters.orderType == OrderType.CONTRACT
- );
-
- // Validate order, update status, and determine fraction to fill.
- (
- bytes32 orderHash,
- uint256 fillNumerator,
- uint256 fillDenominator
- ) = _validateOrderAndUpdateStatus(advancedOrder, true);
-
- // Create an array with length 1 containing the order.
- AdvancedOrder[] memory advancedOrders = new AdvancedOrder[](1);
-
- // Populate the order as the first and only element of the new array.
- advancedOrders[0] = advancedOrder;
-
- // Apply criteria resolvers using generated orders and details arrays.
- _applyCriteriaResolvers(advancedOrders, criteriaResolvers);
-
- // Retrieve the order parameters after applying criteria resolvers.
- OrderParameters memory orderParameters = advancedOrders[0].parameters;
-
- // Perform each item transfer with the appropriate fractional amount.
- _applyFractionsAndTransferEach(
- orderParameters,
- fillNumerator,
- fillDenominator,
- fulfillerConduitKey,
- recipient
- );
-
- // Declare empty bytes32 array and populate with the order hash.
- bytes32[] memory orderHashes = new bytes32[](1);
- orderHashes[0] = orderHash;
-
- // Ensure restricted orders have a valid submitter or pass a zone check.
- _assertRestrictedAdvancedOrderValidity(
- advancedOrders[0],
- orderHashes,
- orderHash
- );
-
- // Emit an event signifying that the order has been fulfilled.
- _emitOrderFulfilledEvent(
- orderHash,
- orderParameters.offerer,
- orderParameters.zone,
- recipient,
- orderParameters.offer,
- orderParameters.consideration
- );
-
- // Clear the reentrancy guard.
- _clearReentrancyGuard();
-
- return true;
- }
-
- /**
- * @dev Internal function to transfer each item contained in a given single
- * order fulfillment after applying a respective fraction to the amount
- * being transferred.
- *
- * @param orderParameters The parameters for the fulfilled order.
- * @param numerator A value indicating the portion of the order
- * that should be filled.
- * @param denominator A value indicating the total order size.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used, with direct approvals set on
- * Consideration.
- * @param recipient The intended recipient for all received items.
- */
- function _applyFractionsAndTransferEach(
- OrderParameters memory orderParameters,
- uint256 numerator,
- uint256 denominator,
- bytes32 fulfillerConduitKey,
- address recipient
- ) internal {
- // Read start time & end time from order parameters and place on stack.
- uint256 startTime = orderParameters.startTime;
- uint256 endTime = orderParameters.endTime;
-
- // Initialize an accumulator array. From this point forward, no new
- // memory regions can be safely allocated until the accumulator is no
- // longer being utilized, as the accumulator operates in an open-ended
- // fashion from this memory pointer; existing memory may still be
- // accessed and modified, however.
- bytes memory accumulator = new bytes(AccumulatorDisarmed);
-
- // As of solidity 0.6.0, inline assembly cannot directly access function
- // definitions, but can still access locally scoped function variables.
- // This means that a local variable to reference the internal function
- // definition (using the same type), along with a local variable with
- // the desired type, must first be created. Then, the original function
- // pointer can be recast to the desired type.
-
- /**
- * Repurpose existing OfferItem memory regions on the offer array for
- * the order by overriding the _transfer function pointer to accept a
- * modified OfferItem argument in place of the usual ReceivedItem:
- *
- * ========= OfferItem ========== ====== ReceivedItem ======
- * ItemType itemType; ------------> ItemType itemType;
- * address token; ----------------> address token;
- * uint256 identifierOrCriteria; -> uint256 identifier;
- * uint256 startAmount; ----------> uint256 amount;
- * uint256 endAmount; ------------> address recipient;
- */
-
- // Declare a nested scope to minimize stack depth.
- unchecked {
- // Read offer array length from memory and place on stack.
- uint256 totalOfferItems = orderParameters.offer.length;
-
- // Create a variable to indicate whether the order has any
- // native offer items
- uint256 anyNativeItems;
-
- // Iterate over each offer on the order.
- // Skip overflow check as for loop is indexed starting at zero.
- for (uint256 i = 0; i < totalOfferItems; ++i) {
- // Retrieve the offer item.
- OfferItem memory offerItem = orderParameters.offer[i];
-
- // Offer items for the native token can not be received outside
- // of a match order function except as part of a contract order.
- {
- ItemType itemType = offerItem.itemType;
- assembly {
- anyNativeItems := or(anyNativeItems, iszero(itemType))
- }
- }
-
- // Declare an additional nested scope to minimize stack depth.
- {
- // Apply fill fraction to get offer item amount to transfer.
- uint256 amount = _applyFraction(
- offerItem.startAmount,
- offerItem.endAmount,
- numerator,
- denominator,
- startTime,
- endTime,
- false
- );
-
- // Utilize assembly to set overloaded offerItem arguments.
- assembly {
- // Write new fractional amount to startAmount as amount.
- mstore(
- add(offerItem, ReceivedItem_amount_offset),
- amount
- )
-
- // Write recipient to endAmount.
- mstore(
- add(offerItem, ReceivedItem_recipient_offset),
- recipient
- )
- }
- }
-
- // Transfer the item from the offerer to the recipient.
- _toOfferItemInput(_transfer)(
- offerItem,
- orderParameters.offerer,
- orderParameters.conduitKey,
- accumulator
- );
- }
-
- // If a non-contract order has native offer items, throw with an
- // `InvalidNativeOfferItem` custom error.
- {
- OrderType orderType = orderParameters.orderType;
- uint256 invalidNativeOfferItem;
- assembly {
- invalidNativeOfferItem := and(
- // Note that this check requires that there are no order
- // types beyond the current set (0-4). It will need to
- // be modified if more order types are added.
- lt(orderType, 4),
- anyNativeItems
- )
- }
- if (invalidNativeOfferItem != 0) {
- _revertInvalidNativeOfferItem();
- }
- }
- }
-
- // Declare a variable for the available native token balance.
- uint256 nativeTokenBalance;
-
- /**
- * Repurpose existing ConsiderationItem memory regions on the
- * consideration array for the order by overriding the _transfer
- * function pointer to accept a modified ConsiderationItem argument in
- * place of the usual ReceivedItem:
- *
- * ====== ConsiderationItem ===== ====== ReceivedItem ======
- * ItemType itemType; ------------> ItemType itemType;
- * address token; ----------------> address token;
- * uint256 identifierOrCriteria;--> uint256 identifier;
- * uint256 startAmount; ----------> uint256 amount;
- * uint256 endAmount; /----> address recipient;
- * address recipient; ------/
- */
-
- // Declare a nested scope to minimize stack depth.
- unchecked {
- // Read consideration array length from memory and place on stack.
- uint256 totalConsiderationItems = orderParameters
- .consideration
- .length;
-
- // Iterate over each consideration item on the order.
- // Skip overflow check as for loop is indexed starting at zero.
- for (uint256 i = 0; i < totalConsiderationItems; ++i) {
- // Retrieve the consideration item.
- ConsiderationItem memory considerationItem = (
- orderParameters.consideration[i]
- );
-
- // Apply fraction & derive considerationItem amount to transfer.
- uint256 amount = _applyFraction(
- considerationItem.startAmount,
- considerationItem.endAmount,
- numerator,
- denominator,
- startTime,
- endTime,
- true
- );
-
- // Use assembly to set overloaded considerationItem arguments.
- assembly {
- // Write derived fractional amount to startAmount as amount.
- mstore(
- add(considerationItem, ReceivedItem_amount_offset),
- amount
- )
-
- // Write original recipient to endAmount as recipient.
- mstore(
- add(considerationItem, ReceivedItem_recipient_offset),
- mload(
- add(
- considerationItem,
- ConsiderationItem_recipient_offset
- )
- )
- )
- }
-
- if (considerationItem.itemType == ItemType.NATIVE) {
- // Get the current available balance of native tokens.
- assembly {
- nativeTokenBalance := selfbalance()
- }
-
- // Ensure that sufficient native tokens are still available.
- if (amount > nativeTokenBalance) {
- _revertInsufficientNativeTokensSupplied();
- }
- }
-
- // Transfer item from caller to recipient specified by the item.
- _toConsiderationItemInput(_transfer)(
- considerationItem,
- msg.sender,
- fulfillerConduitKey,
- accumulator
- );
- }
- }
-
- // Trigger any remaining accumulated transfers via call to the conduit.
- _triggerIfArmed(accumulator);
-
- // Determine whether any native token balance remains.
- assembly {
- nativeTokenBalance := selfbalance()
- }
-
- // Return any remaining native token balance to the caller.
- if (nativeTokenBalance != 0) {
- _transferNativeTokens(payable(msg.sender), nativeTokenBalance);
- }
- }
-
- /**
- * @dev Internal function to emit an OrderFulfilled event. OfferItems are
- * translated into SpentItems and ConsiderationItems are translated
- * into ReceivedItems.
- *
- * @param orderHash The order hash.
- * @param offerer The offerer for the order.
- * @param zone The zone for the order.
- * @param recipient The recipient of the order, or the null address if
- * the order was fulfilled via order matching.
- * @param offer The offer items for the order.
- * @param consideration The consideration items for the order.
- */
- function _emitOrderFulfilledEvent(
- bytes32 orderHash,
- address offerer,
- address zone,
- address recipient,
- OfferItem[] memory offer,
- ConsiderationItem[] memory consideration
- ) internal {
- // Cast already-modified offer memory region as spent items.
- SpentItem[] memory spentItems;
- assembly {
- spentItems := offer
- }
-
- // Cast already-modified consideration memory region as received items.
- ReceivedItem[] memory receivedItems;
- assembly {
- receivedItems := consideration
- }
-
- // Emit an event signifying that the order has been fulfilled.
- emit OrderFulfilled(
- orderHash,
- offerer,
- zone,
- recipient,
- spentItems,
- receivedItems
- );
- }
-}
diff --git a/contracts/lib/OrderValidator.sol b/contracts/lib/OrderValidator.sol
deleted file mode 100644
index 4f9664521..000000000
--- a/contracts/lib/OrderValidator.sol
+++ /dev/null
@@ -1,960 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { OrderType } from "./ConsiderationEnums.sol";
-
-import {
- AdvancedOrder,
- ConsiderationItem,
- OfferItem,
- Order,
- OrderComponents,
- OrderParameters,
- OrderStatus
-} from "./ConsiderationStructs.sol";
-
-import {
- _revertBadFraction,
- _revertCannotCancelOrder,
- _revertConsiderationLengthNotEqualToTotalOriginal,
- _revertInvalidContractOrder,
- _revertPartialFillsNotEnabledForOrder
-} from "./ConsiderationErrors.sol";
-
-import { Executor } from "./Executor.sol";
-
-import { ZoneInteraction } from "./ZoneInteraction.sol";
-
-import { MemoryPointer } from "../helpers/PointerLibraries.sol";
-
-import {
- AdvancedOrder_denominator_offset,
- AdvancedOrder_numerator_offset,
- BasicOrder_offerer_cdPtr,
- Common_amount_offset,
- Common_endAmount_offset,
- Common_identifier_offset,
- Common_token_offset,
- ConsiderItem_recipient_offset,
- ContractOrder_orderHash_offerer_shift,
- MaxUint120,
- OrderStatus_filledDenominator_offset,
- OrderStatus_filledNumerator_offset,
- OrderStatus_ValidatedAndNotCancelled
-} from "./ConsiderationConstants.sol";
-
-import {
- Error_selector_offset,
- Panic_arithmetic,
- Panic_error_code_ptr,
- Panic_error_length,
- Panic_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @title OrderValidator
- * @author 0age
- * @notice OrderValidator contains functionality related to validating orders
- * and updating their status.
- */
-contract OrderValidator is Executor, ZoneInteraction {
- // Track status of each order (validated, cancelled, and fraction filled).
- mapping(bytes32 => OrderStatus) private _orderStatus;
-
- // Track nonces for contract offerers.
- mapping(address => uint256) internal _contractNonces;
-
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(address conduitController) Executor(conduitController) {}
-
- /**
- * @dev Internal function to verify and update the status of a basic order.
- * Note that this function may only be safely called as part of basic
- * orders, as it assumes a specific calldata encoding structure that
- * must first be validated.
- *
- * @param orderHash The hash of the order.
- * @param signature A signature from the offerer indicating that the order
- * has been approved.
- */
- function _validateBasicOrderAndUpdateStatus(
- bytes32 orderHash,
- bytes calldata signature
- ) internal {
- // Retrieve offerer directly using fixed calldata offset based on strict
- // basic parameter encoding.
- address offerer;
- assembly {
- offerer := calldataload(BasicOrder_offerer_cdPtr)
- }
-
- // Retrieve the order status for the given order hash.
- OrderStatus storage orderStatus = _orderStatus[orderHash];
-
- // Ensure order is fillable and is not cancelled.
- _verifyOrderStatus(
- orderHash,
- orderStatus,
- true, // Only allow unused orders when fulfilling basic orders.
- true // Signifies to revert if the order is invalid.
- );
-
- // If the order is not already validated, verify the supplied signature.
- if (!orderStatus.isValidated) {
- _verifySignature(offerer, orderHash, signature);
- }
-
- // Update order status as fully filled, packing struct values.
- orderStatus.isValidated = true;
- orderStatus.isCancelled = false;
- orderStatus.numerator = 1;
- orderStatus.denominator = 1;
- }
-
- /**
- * @dev Internal function to validate an order, determine what portion to
- * fill, and update its status. The desired fill amount is supplied as
- * a fraction, as is the returned amount to fill.
- *
- * @param advancedOrder The order to fulfill as well as the fraction to
- * fill. Note that all offer and consideration
- * amounts must divide with no remainder in order
- * for a partial fill to be valid.
- * @param revertOnInvalid A boolean indicating whether to revert if the
- * order is invalid due to the time or status.
- *
- * @return orderHash The order hash.
- * @return numerator A value indicating the portion of the order that
- * will be filled.
- * @return denominator A value indicating the total size of the order.
- */
- function _validateOrderAndUpdateStatus(
- AdvancedOrder memory advancedOrder,
- bool revertOnInvalid
- )
- internal
- returns (bytes32 orderHash, uint256 numerator, uint256 denominator)
- {
- // Retrieve the parameters for the order.
- OrderParameters memory orderParameters = advancedOrder.parameters;
-
- // Ensure current timestamp falls between order start time and end time.
- if (
- !_verifyTime(
- orderParameters.startTime,
- orderParameters.endTime,
- revertOnInvalid
- )
- ) {
- // Assuming an invalid time and no revert, return zeroed out values.
- return (bytes32(0), 0, 0);
- }
-
- // Read numerator and denominator from memory and place on the stack.
- // Note that overflowed values are masked.
- assembly {
- numerator := and(
- mload(add(advancedOrder, AdvancedOrder_numerator_offset)),
- MaxUint120
- )
-
- denominator := and(
- mload(add(advancedOrder, AdvancedOrder_denominator_offset)),
- MaxUint120
- )
- }
-
- // Declare variable for tracking the validity of the supplied fraction.
- bool invalidFraction;
-
- // If the order is a contract order, return the generated order.
- if (orderParameters.orderType == OrderType.CONTRACT) {
- // Ensure that the numerator and denominator are both equal to 1.
- assembly {
- // (1 ^ nd =/= 0) => (nd =/= 1) => (n =/= 1) || (d =/= 1)
- // It's important that the values are 120-bit masked before
- // multiplication is applied. Otherwise, the last implication
- // above is not correct (mod 2^256).
- invalidFraction := xor(mul(numerator, denominator), 1)
- }
-
- // Revert if the supplied numerator and denominator are not valid.
- if (invalidFraction) {
- _revertBadFraction();
- }
-
- // Return the generated order based on the order params and the
- // provided extra data. If revertOnInvalid is true, the function
- // will revert if the input is invalid.
- return
- _getGeneratedOrder(
- orderParameters,
- advancedOrder.extraData,
- revertOnInvalid
- );
- }
-
- // Ensure numerator does not exceed denominator and is not zero.
- assembly {
- invalidFraction := or(gt(numerator, denominator), iszero(numerator))
- }
-
- // Revert if the supplied numerator and denominator are not valid.
- if (invalidFraction) {
- _revertBadFraction();
- }
-
- // If attempting partial fill (n < d) check order type & ensure support.
- if (
- _doesNotSupportPartialFills(
- orderParameters.orderType,
- numerator,
- denominator
- )
- ) {
- // Revert if partial fill was attempted on an unsupported order.
- _revertPartialFillsNotEnabledForOrder();
- }
-
- // Retrieve current counter & use it w/ parameters to derive order hash.
- orderHash = _assertConsiderationLengthAndGetOrderHash(orderParameters);
-
- // Retrieve the order status using the derived order hash.
- OrderStatus storage orderStatus = _orderStatus[orderHash];
-
- // Ensure order is fillable and is not cancelled.
- if (
- !_verifyOrderStatus(
- orderHash,
- orderStatus,
- false, // Allow partially used orders to be filled.
- revertOnInvalid
- )
- ) {
- // Assuming an invalid order status and no revert, return zero fill.
- return (orderHash, 0, 0);
- }
-
- // If the order is not already validated, verify the supplied signature.
- if (!orderStatus.isValidated) {
- _verifySignature(
- orderParameters.offerer,
- orderHash,
- advancedOrder.signature
- );
- }
-
- // Utilize assembly to determine the fraction to fill and update status.
- assembly {
- let orderStatusSlot := orderStatus.slot
- // Read filled amount as numerator and denominator and put on stack.
- let filledNumerator := sload(orderStatusSlot)
- let filledDenominator := shr(
- OrderStatus_filledDenominator_offset,
- filledNumerator
- )
-
- // "Loop" until the appropriate fill fraction has been determined.
- for { } 1 { } {
- // If no portion of the order has been filled yet...
- if iszero(filledDenominator) {
- // fill the full supplied fraction.
- filledNumerator := numerator
-
- // Exit the "loop" early.
- break
- }
-
- // Shift and mask to calculate the current filled numerator.
- filledNumerator := and(
- shr(OrderStatus_filledNumerator_offset, filledNumerator),
- MaxUint120
- )
-
- // If denominator of 1 supplied, fill entire remaining amount.
- if eq(denominator, 1) {
- // Set the amount to fill to the remaining amount.
- numerator := sub(filledDenominator, filledNumerator)
-
- // Set the fill size to the current size.
- denominator := filledDenominator
-
- // Set the filled amount to the current size.
- filledNumerator := filledDenominator
-
- // Exit the "loop" early.
- break
- }
-
- // If supplied denominator is equal to the current one:
- if eq(denominator, filledDenominator) {
- // Increment the filled numerator by the new numerator.
- filledNumerator := add(numerator, filledNumerator)
-
- // Once adjusted, if current + supplied numerator exceeds
- // the denominator:
- let carry := mul(
- sub(filledNumerator, denominator),
- gt(filledNumerator, denominator)
- )
-
- // reduce the amount to fill by the excess.
- numerator := sub(numerator, carry)
-
- // Reduce the filled amount by the excess as well.
- filledNumerator := sub(filledNumerator, carry)
-
- // Exit the "loop" early.
- break
- }
-
- // Otherwise, if supplied denominator differs from current one:
- // Scale the filled amount up by the supplied size.
- filledNumerator := mul(filledNumerator, denominator)
-
- // Scale the supplied amount and size up by the current size.
- numerator := mul(numerator, filledDenominator)
- denominator := mul(denominator, filledDenominator)
-
- // Increment the filled numerator by the new numerator.
- filledNumerator := add(numerator, filledNumerator)
-
- // Once adjusted, if current + supplied numerator exceeds
- // denominator:
- let carry := mul(
- sub(filledNumerator, denominator),
- gt(filledNumerator, denominator)
- )
-
- // reduce the amount to fill by the excess.
- numerator := sub(numerator, carry)
-
- // Reduce the filled amount by the excess as well.
- filledNumerator := sub(filledNumerator, carry)
-
- // Check filledNumerator and denominator for uint120 overflow.
- if or(
- gt(filledNumerator, MaxUint120),
- gt(denominator, MaxUint120)
- ) {
- // Derive greatest common divisor using euclidean algorithm.
- function gcd(_a, _b) -> out {
- // "Loop" until only one non-zero value remains.
- for { } _b { } {
- // Assign the second value to a temporary variable.
- let _c := _b
-
- // Derive the modulus of the two values.
- _b := mod(_a, _c)
-
- // Set the first value to the temporary value.
- _a := _c
- }
-
- // Return the remaining non-zero value.
- out := _a
- }
-
- // Determine the amount to scale down the fill fractions.
- let scaleDown := gcd(
- numerator,
- gcd(filledNumerator, denominator)
- )
-
- // Ensure that the divisor is at least one.
- let safeScaleDown := add(scaleDown, iszero(scaleDown))
-
- // Scale all fractional values down by gcd.
- numerator := div(numerator, safeScaleDown)
- filledNumerator := div(filledNumerator, safeScaleDown)
- denominator := div(denominator, safeScaleDown)
-
- // Perform the overflow check a second time.
- if or(
- gt(filledNumerator, MaxUint120),
- gt(denominator, MaxUint120)
- ) {
- // Store the Panic error signature.
- mstore(0, Panic_error_selector)
- // Store the arithmetic (0x11) panic code.
- mstore(Panic_error_code_ptr, Panic_arithmetic)
-
- // revert(abi.encodeWithSignature(
- // "Panic(uint256)", 0x11
- // ))
- revert(Error_selector_offset, Panic_error_length)
- }
- }
-
- // Exit the "loop" now that all evaluation is complete.
- break
- }
-
- // Update order status and fill amount, packing struct values.
- // [denominator: 15 bytes] [numerator: 15 bytes]
- // [isCancelled: 1 byte] [isValidated: 1 byte]
- sstore(
- orderStatusSlot,
- or(
- OrderStatus_ValidatedAndNotCancelled,
- or(
- shl(
- OrderStatus_filledNumerator_offset,
- filledNumerator
- ),
- shl(OrderStatus_filledDenominator_offset, denominator)
- )
- )
- )
- }
- }
-
- /**
- * @dev Internal pure function to check the compatibility of two offer
- * or consideration items for contract orders. Note that the itemType
- * and identifier are reset in cases where criteria = 0 (collection-
- * wide offers), which means that a contract offerer has full latitude
- * to choose any identifier it wants mid-flight, in contrast to the
- * normal behavior, where the fulfiller can pick which identifier to
- * receive by providing a CriteriaResolver.
- *
- * @param originalItem The original offer or consideration item.
- * @param newItem The new offer or consideration item.
- *
- * @return isInvalid Error buffer indicating if items are incompatible.
- */
- function _compareItems(
- MemoryPointer originalItem,
- MemoryPointer newItem
- ) internal pure returns (uint256 isInvalid) {
- assembly {
- let itemType := mload(originalItem)
- let identifier := mload(add(originalItem, Common_identifier_offset))
-
- // Set returned identifier for criteria-based items w/ criteria = 0.
- if and(gt(itemType, 3), iszero(identifier)) {
- // replace item type
- itemType := sub(3, eq(itemType, 4))
- identifier := mload(add(newItem, Common_identifier_offset))
- }
-
- let originalAmount := mload(add(originalItem, Common_amount_offset))
- let newAmount := mload(add(newItem, Common_amount_offset))
-
- isInvalid := iszero(
- and(
- // originalItem.token == newItem.token &&
- // originalItem.itemType == newItem.itemType
- and(
- eq(
- mload(add(originalItem, Common_token_offset)),
- mload(add(newItem, Common_token_offset))
- ),
- eq(itemType, mload(newItem))
- ),
- // originalItem.identifier == newItem.identifier &&
- // originalItem.startAmount == originalItem.endAmount
- and(
- eq(
- identifier,
- mload(add(newItem, Common_identifier_offset))
- ),
- eq(
- originalAmount,
- mload(add(originalItem, Common_endAmount_offset))
- )
- )
- )
- )
- }
- }
-
- /**
- * @dev Internal pure function to check the compatibility of two recipients
- * on consideration items for contract orders. This check is skipped if
- * no recipient is originally supplied.
- *
- * @param originalRecipient The original consideration item recipient.
- * @param newRecipient The new consideration item recipient.
- *
- * @return isInvalid Error buffer indicating if recipients are incompatible.
- */
- function _checkRecipients(
- address originalRecipient,
- address newRecipient
- ) internal pure returns (uint256 isInvalid) {
- assembly {
- isInvalid := iszero(
- or(
- iszero(originalRecipient),
- eq(newRecipient, originalRecipient)
- )
- )
- }
- }
-
- /**
- * @dev Internal function to generate a contract order. When a
- * collection-wide criteria-based item (criteria = 0) is provided as an
- * input to a contract order, the contract offerer has full latitude to
- * choose any identifier it wants mid-flight, which differs from the
- * usual behavior. For regular criteria-based orders with
- * identifierOrCriteria = 0, the fulfiller can pick which identifier to
- * receive by providing a CriteriaResolver. For contract offers with
- * identifierOrCriteria = 0, Seaport does not expect a corresponding
- * CriteriaResolver, and will revert if one is provided.
- *
- * @param orderParameters The parameters for the order.
- * @param context The context for generating the order.
- * @param revertOnInvalid Whether to revert on invalid input.
- *
- * @return orderHash The order hash.
- * @return numerator The numerator.
- * @return denominator The denominator.
- */
- function _getGeneratedOrder(
- OrderParameters memory orderParameters,
- bytes memory context,
- bool revertOnInvalid
- )
- internal
- returns (bytes32 orderHash, uint256 numerator, uint256 denominator)
- {
- // Ensure that consideration array length is equal to the total original
- // consideration items value.
- if (
- orderParameters.consideration.length !=
- orderParameters.totalOriginalConsiderationItems
- ) {
- _revertConsiderationLengthNotEqualToTotalOriginal();
- }
-
- {
- address offerer = orderParameters.offerer;
- bool success;
- (MemoryPointer cdPtr, uint256 size) = _encodeGenerateOrder(
- orderParameters,
- context
- );
- assembly {
- success := call(gas(), offerer, 0, cdPtr, size, 0, 0)
- }
-
- {
- // Note: overflow impossible; nonce can't increment that high.
- uint256 contractNonce;
- unchecked {
- // Note: nonce will be incremented even for skipped orders,
- // and even if generateOrder's return data does not satisfy
- // all the constraints. This is the case when errorBuffer
- // != 0 and revertOnInvalid == false.
- contractNonce = _contractNonces[offerer]++;
- }
-
- assembly {
- // Shift offerer address up 96 bytes and combine with nonce.
- orderHash := xor(
- contractNonce,
- shl(ContractOrder_orderHash_offerer_shift, offerer)
- )
- }
- }
-
- // Revert or skip if the call to generate the contract order failed.
- if (!success) {
- return _revertOrReturnEmpty(revertOnInvalid, orderHash);
- }
- }
-
- // From this point onward, do not allow for skipping orders as the
- // contract offerer may have modified state in expectation of any named
- // consideration items being sent to their designated recipients.
-
- // Decode the returned contract order and/or update the error buffer.
- (
- uint256 errorBuffer,
- OfferItem[] memory offer,
- ConsiderationItem[] memory consideration
- ) = _convertGetGeneratedOrderResult(_decodeGenerateOrderReturndata)();
-
- // Revert if the returndata could not be decoded correctly.
- if (errorBuffer != 0) {
- _revertInvalidContractOrder(orderHash);
- }
-
- {
- // Designate lengths.
- uint256 originalOfferLength = orderParameters.offer.length;
- uint256 newOfferLength = offer.length;
-
- // Explicitly specified offer items cannot be removed.
- if (originalOfferLength > newOfferLength) {
- _revertInvalidContractOrder(orderHash);
- }
-
- // Iterate over each specified offer (e.g. minimumReceived) item.
- for (uint256 i = 0; i < originalOfferLength; ) {
- // Retrieve the pointer to the originally supplied item.
- MemoryPointer mPtrOriginal = orderParameters
- .offer[i]
- .toMemoryPointer();
-
- // Retrieve the pointer to the newly returned item.
- MemoryPointer mPtrNew = offer[i].toMemoryPointer();
-
- // Compare the items and update the error buffer accordingly.
- errorBuffer |=
- _cast(
- mPtrOriginal
- .offset(Common_amount_offset)
- .readUint256() >
- mPtrNew.offset(Common_amount_offset).readUint256()
- ) |
- _compareItems(mPtrOriginal, mPtrNew);
-
- // Increment the array (cannot overflow as index starts at 0).
- unchecked {
- ++i;
- }
- }
-
- // Assign the returned offer item in place of the original item.
- orderParameters.offer = offer;
- }
-
- {
- // Designate lengths & memory locations.
- ConsiderationItem[] memory originalConsiderationArray = (
- orderParameters.consideration
- );
- uint256 newConsiderationLength = consideration.length;
-
- // New consideration items cannot be created.
- if (newConsiderationLength > originalConsiderationArray.length) {
- _revertInvalidContractOrder(orderHash);
- }
-
- // Iterate over returned consideration & do not exceed maximumSpent.
- for (uint256 i = 0; i < newConsiderationLength; ) {
- // Retrieve the pointer to the originally supplied item.
- MemoryPointer mPtrOriginal = originalConsiderationArray[i]
- .toMemoryPointer();
-
- // Retrieve the pointer to the newly returned item.
- MemoryPointer mPtrNew = consideration[i].toMemoryPointer();
-
- // Compare the items and update the error buffer accordingly
- // and ensure that the recipients are equal when provided.
- errorBuffer |=
- _cast(
- mPtrNew.offset(Common_amount_offset).readUint256() >
- mPtrOriginal
- .offset(Common_amount_offset)
- .readUint256()
- ) |
- _compareItems(mPtrOriginal, mPtrNew) |
- _checkRecipients(
- mPtrOriginal
- .offset(ConsiderItem_recipient_offset)
- .readAddress(),
- mPtrNew
- .offset(ConsiderItem_recipient_offset)
- .readAddress()
- );
-
- // Increment the array (cannot overflow as index starts at 0).
- unchecked {
- ++i;
- }
- }
-
- // Assign returned consideration item in place of the original item.
- orderParameters.consideration = consideration;
- }
-
- // Revert if any item comparison failed.
- if (errorBuffer != 0) {
- _revertInvalidContractOrder(orderHash);
- }
-
- // Return order hash and full fill amount (numerator & denominator = 1).
- return (orderHash, 1, 1);
- }
-
- /**
- * @dev Internal function to cancel an arbitrary number of orders. Note that
- * only the offerer or the zone of a given order may cancel it. Callers
- * should ensure that the intended order was cancelled by calling
- * `getOrderStatus` and confirming that `isCancelled` returns `true`.
- * Also note that contract orders are not cancellable.
- *
- * @param orders The orders to cancel.
- *
- * @return cancelled A boolean indicating whether the supplied orders were
- * successfully cancelled.
- */
- function _cancel(
- OrderComponents[] calldata orders
- ) internal returns (bool cancelled) {
- // Ensure that the reentrancy guard is not currently set.
- _assertNonReentrant();
-
- // Declare variables outside of the loop.
- OrderStatus storage orderStatus;
-
- // Declare a variable for tracking invariants in the loop.
- bool anyInvalidCallerOrContractOrder;
-
- // Skip overflow check as for loop is indexed starting at zero.
- unchecked {
- // Read length of the orders array from memory and place on stack.
- uint256 totalOrders = orders.length;
-
- // Iterate over each order.
- for (uint256 i = 0; i < totalOrders; ) {
- // Retrieve the order.
- OrderComponents calldata order = orders[i];
-
- address offerer = order.offerer;
- address zone = order.zone;
- OrderType orderType = order.orderType;
-
- assembly {
- // If caller is neither the offerer nor zone, or a contract
- // order is present, flag anyInvalidCallerOrContractOrder.
- anyInvalidCallerOrContractOrder := or(
- anyInvalidCallerOrContractOrder,
- // orderType == CONTRACT ||
- // !(caller == offerer || caller == zone)
- or(
- eq(orderType, 4),
- iszero(
- or(eq(caller(), offerer), eq(caller(), zone))
- )
- )
- )
- }
-
- bytes32 orderHash = _deriveOrderHash(
- _toOrderParametersReturnType(
- _decodeOrderComponentsAsOrderParameters
- )(order.toCalldataPointer()),
- order.counter
- );
-
- // Retrieve the order status using the derived order hash.
- orderStatus = _orderStatus[orderHash];
-
- // Update the order status as not valid and cancelled.
- orderStatus.isValidated = false;
- orderStatus.isCancelled = true;
-
- // Emit an event signifying that the order has been cancelled.
- emit OrderCancelled(orderHash, offerer, zone);
-
- // Increment counter inside body of loop for gas efficiency.
- ++i;
- }
- }
-
- if (anyInvalidCallerOrContractOrder) {
- _revertCannotCancelOrder();
- }
-
- // Return a boolean indicating that orders were successfully cancelled.
- cancelled = true;
- }
-
- /**
- * @dev Internal function to validate an arbitrary number of orders, thereby
- * registering their signatures as valid and allowing the fulfiller to
- * skip signature verification on fulfillment. Note that validated
- * orders may still be unfulfillable due to invalid item amounts or
- * other factors; callers should determine whether validated orders are
- * fulfillable by simulating the fulfillment call prior to execution.
- * Also note that anyone can validate a signed order, but only the
- * offerer can validate an order without supplying a signature.
- *
- * @param orders The orders to validate.
- *
- * @return validated A boolean indicating whether the supplied orders were
- * successfully validated.
- */
- function _validate(
- Order[] memory orders
- ) internal returns (bool validated) {
- // Ensure that the reentrancy guard is not currently set.
- _assertNonReentrant();
-
- // Declare variables outside of the loop.
- OrderStatus storage orderStatus;
- bytes32 orderHash;
- address offerer;
-
- // Skip overflow check as for loop is indexed starting at zero.
- unchecked {
- // Read length of the orders array from memory and place on stack.
- uint256 totalOrders = orders.length;
-
- // Iterate over each order.
- for (uint256 i = 0; i < totalOrders; ++i) {
- // Retrieve the order.
- Order memory order = orders[i];
-
- // Retrieve the order parameters.
- OrderParameters memory orderParameters = order.parameters;
-
- // Skip contract orders.
- if (orderParameters.orderType == OrderType.CONTRACT) {
- continue;
- }
-
- // Move offerer from memory to the stack.
- offerer = orderParameters.offerer;
-
- // Get current counter & use it w/ params to derive order hash.
- orderHash = _assertConsiderationLengthAndGetOrderHash(
- orderParameters
- );
-
- // Retrieve the order status using the derived order hash.
- orderStatus = _orderStatus[orderHash];
-
- // Ensure order is fillable and retrieve the filled amount.
- _verifyOrderStatus(
- orderHash,
- orderStatus,
- false, // Signifies that partially filled orders are valid.
- true // Signifies to revert if the order is invalid.
- );
-
- // If the order has not already been validated...
- if (!orderStatus.isValidated) {
- // Ensure that consideration array length is equal to the
- // total original consideration items value.
- if (
- orderParameters.consideration.length !=
- orderParameters.totalOriginalConsiderationItems
- ) {
- _revertConsiderationLengthNotEqualToTotalOriginal();
- }
-
- // Verify the supplied signature.
- _verifySignature(offerer, orderHash, order.signature);
-
- // Update order status to mark the order as valid.
- orderStatus.isValidated = true;
-
- // Emit an event signifying the order has been validated.
- emit OrderValidated(orderHash, orderParameters);
- }
- }
- }
-
- // Return a boolean indicating that orders were successfully validated.
- validated = true;
- }
-
- /**
- * @dev Internal view function to retrieve the status of a given order by
- * hash, including whether the order has been cancelled or validated
- * and the fraction of the order that has been filled.
- *
- * @param orderHash The order hash in question.
- *
- * @return isValidated A boolean indicating whether the order in question
- * has been validated (i.e. previously approved or
- * partially filled).
- * @return isCancelled A boolean indicating whether the order in question
- * has been cancelled.
- * @return totalFilled The total portion of the order that has been filled
- * (i.e. the "numerator").
- * @return totalSize The total size of the order that is either filled or
- * unfilled (i.e. the "denominator").
- */
- function _getOrderStatus(
- bytes32 orderHash
- )
- internal
- view
- returns (
- bool isValidated,
- bool isCancelled,
- uint256 totalFilled,
- uint256 totalSize
- )
- {
- // Retrieve the order status using the order hash.
- OrderStatus storage orderStatus = _orderStatus[orderHash];
-
- // Return the fields on the order status.
- return (
- orderStatus.isValidated,
- orderStatus.isCancelled,
- orderStatus.numerator,
- orderStatus.denominator
- );
- }
-
- /**
- * @dev Internal pure function to either revert or return an empty tuple
- * depending on the value of `revertOnInvalid`.
- *
- * @param revertOnInvalid Whether to revert on invalid input.
- * @param contractOrderHash The contract order hash.
- *
- * @return orderHash The order hash.
- * @return numerator The numerator.
- * @return denominator The denominator.
- */
- function _revertOrReturnEmpty(
- bool revertOnInvalid,
- bytes32 contractOrderHash
- )
- internal
- pure
- returns (bytes32 orderHash, uint256 numerator, uint256 denominator)
- {
- if (revertOnInvalid) {
- _revertInvalidContractOrder(contractOrderHash);
- }
-
- return (contractOrderHash, 0, 0);
- }
-
- /**
- * @dev Internal pure function to check whether a given order type indicates
- * that partial fills are not supported (e.g. only "full fills" are
- * allowed for the order in question).
- *
- * @param orderType The order type in question.
- * @param numerator The numerator in question.
- * @param denominator The denominator in question.
- *
- * @return isFullOrder A boolean indicating whether the order type only
- * supports full fills.
- */
- function _doesNotSupportPartialFills(
- OrderType orderType,
- uint256 numerator,
- uint256 denominator
- ) internal pure returns (bool isFullOrder) {
- // The "full" order types are even, while "partial" order types are odd.
- // Bitwise and by 1 is equivalent to modulo by 2, but 2 gas cheaper. The
- // check is only necessary if numerator is less than denominator.
- assembly {
- // Equivalent to `uint256(orderType) & 1 == 0`.
- isFullOrder := and(
- lt(numerator, denominator),
- iszero(and(orderType, 1))
- )
- }
- }
-}
diff --git a/contracts/lib/ReentrancyGuard.sol b/contracts/lib/ReentrancyGuard.sol
deleted file mode 100644
index 35aca6ad2..000000000
--- a/contracts/lib/ReentrancyGuard.sol
+++ /dev/null
@@ -1,88 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { ReentrancyErrors } from "../interfaces/ReentrancyErrors.sol";
-
-import { LowLevelHelpers } from "./LowLevelHelpers.sol";
-
-import {
- _revertInvalidMsgValue,
- _revertNoReentrantCalls
-} from "./ConsiderationErrors.sol";
-
-import {
- _ENTERED_AND_ACCEPTING_NATIVE_TOKENS,
- _ENTERED,
- _NOT_ENTERED
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title ReentrancyGuard
- * @author 0age
- * @notice ReentrancyGuard contains a storage variable and related functionality
- * for protecting against reentrancy.
- */
-contract ReentrancyGuard is ReentrancyErrors, LowLevelHelpers {
- // Prevent reentrant calls on protected functions.
- uint256 private _reentrancyGuard;
-
- /**
- * @dev Initialize the reentrancy guard during deployment.
- */
- constructor() {
- // Initialize the reentrancy guard in a cleared state.
- _reentrancyGuard = _NOT_ENTERED;
- }
-
- /**
- * @dev Internal function to ensure that a sentinel value for the reentrancy
- * guard is not currently set and, if not, to set a sentinel value for
- * the reentrancy guard based on whether or not native tokens may be
- * received during execution or not.
- *
- * @param acceptNativeTokens A boolean indicating whether native tokens may
- * be received during execution or not.
- */
- function _setReentrancyGuard(bool acceptNativeTokens) internal {
- // Ensure that the reentrancy guard is not already set.
- _assertNonReentrant();
-
- // Set the reentrancy guard. A value of 2 indicates that native tokens
- // may not be accepted during execution, whereas a value of 3 indicates
- // that they will be accepted (with any remaining native tokens returned
- // to the caller).
- unchecked {
- _reentrancyGuard = _ENTERED + _cast(acceptNativeTokens);
- }
- }
-
- /**
- * @dev Internal function to unset the reentrancy guard sentinel value.
- */
- function _clearReentrancyGuard() internal {
- // Clear the reentrancy guard.
- _reentrancyGuard = _NOT_ENTERED;
- }
-
- /**
- * @dev Internal view function to ensure that a sentinel value for the
- reentrancy guard is not currently set.
- */
- function _assertNonReentrant() internal view {
- // Ensure that the reentrancy guard is not currently set.
- if (_reentrancyGuard != _NOT_ENTERED) {
- _revertNoReentrantCalls();
- }
- }
-
- /**
- * @dev Internal view function to ensure that the sentinel value indicating
- * native tokens may be received during execution is currently set.
- */
- function _assertAcceptingNativeTokens() internal view {
- // Ensure that the reentrancy guard is not currently set.
- if (_reentrancyGuard != _ENTERED_AND_ACCEPTING_NATIVE_TOKENS) {
- _revertInvalidMsgValue(msg.value);
- }
- }
-}
diff --git a/contracts/lib/SignatureVerification.sol b/contracts/lib/SignatureVerification.sol
deleted file mode 100644
index a30ab656c..000000000
--- a/contracts/lib/SignatureVerification.sol
+++ /dev/null
@@ -1,350 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import {
- SignatureVerificationErrors
-} from "../interfaces/SignatureVerificationErrors.sol";
-
-import { LowLevelHelpers } from "./LowLevelHelpers.sol";
-
-import {
- ECDSA_MaxLength,
- ECDSA_signature_s_offset,
- ECDSA_signature_v_offset,
- ECDSA_twentySeventhAndTwentyEighthBytesSet,
- Ecrecover_args_size,
- Ecrecover_precompile,
- EIP1271_isValidSignature_calldata_baseLength,
- EIP1271_isValidSignature_digest_negativeOffset,
- EIP1271_isValidSignature_selector_negativeOffset,
- EIP1271_isValidSignature_selector,
- EIP1271_isValidSignature_signature_head_offset,
- EIP2098_allButHighestBitMask,
- MaxUint8,
- OneWord,
- Signature_lower_v
-} from "./ConsiderationConstants.sol";
-
-import {
- BadContractSignature_error_length,
- BadContractSignature_error_selector,
- BadSignatureV_error_length,
- BadSignatureV_error_selector,
- BadSignatureV_error_v_ptr,
- Error_selector_offset,
- InvalidSignature_error_length,
- InvalidSignature_error_selector,
- InvalidSigner_error_length,
- InvalidSigner_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @title SignatureVerification
- * @author 0age
- * @notice SignatureVerification contains logic for verifying signatures.
- */
-contract SignatureVerification is SignatureVerificationErrors, LowLevelHelpers {
- /**
- * @dev Internal view function to verify the signature of an order. An
- * ERC-1271 fallback will be attempted if either the signature length
- * is not 64 or 65 bytes or if the recovered signer does not match the
- * supplied signer.
- *
- * @param signer The signer for the order.
- * @param digest The digest to verify signature against.
- * @param originalDigest The original digest to verify signature
- * against.
- * @param originalSignatureLength The original signature length.
- * @param signature A signature from the signer indicating
- * that the order has been approved.
- */
- function _assertValidSignature(
- address signer,
- bytes32 digest,
- bytes32 originalDigest,
- uint256 originalSignatureLength,
- bytes memory signature
- ) internal view {
- // Declare value for ecrecover equality or 1271 call success status.
- bool success;
-
- // Utilize assembly to perform optimized signature verification check.
- assembly {
- // Ensure that first word of scratch space is empty.
- mstore(0, 0)
-
- // Get the length of the signature.
- let signatureLength := mload(signature)
-
- // Get the pointer to the value preceding the signature length.
- // This will be used for temporary memory overrides - either the
- // signature head for isValidSignature or the digest for ecrecover.
- let wordBeforeSignaturePtr := sub(signature, OneWord)
-
- // Cache the current value behind the signature to restore it later.
- let cachedWordBeforeSignature := mload(wordBeforeSignaturePtr)
-
- // Declare lenDiff + recoveredSigner scope to manage stack pressure.
- {
- // Take the difference between the max ECDSA signature length
- // and the actual signature length. Overflow desired for any
- // values > 65. If the diff is not 0 or 1, it is not a valid
- // ECDSA signature - move on to EIP1271 check.
- let lenDiff := sub(ECDSA_MaxLength, signatureLength)
-
- // Declare variable for recovered signer.
- let recoveredSigner
-
- // If diff is 0 or 1, it may be an ECDSA signature.
- // Try to recover signer.
- if iszero(gt(lenDiff, 1)) {
- // Read the signature `s` value.
- let originalSignatureS := mload(
- add(signature, ECDSA_signature_s_offset)
- )
-
- // Read the first byte of the word after `s`. If the
- // signature is 65 bytes, this will be the real `v` value.
- // If not, it will need to be modified - doing it this way
- // saves an extra condition.
- let v := byte(
- 0,
- mload(add(signature, ECDSA_signature_v_offset))
- )
-
- // If lenDiff is 1, parse 64-byte signature as ECDSA.
- if lenDiff {
- // Extract yParity from highest bit of vs and add 27 to
- // get v.
- v := add(
- shr(MaxUint8, originalSignatureS),
- Signature_lower_v
- )
-
- // Extract canonical s from vs, all but the highest bit.
- // Temporarily overwrite the original `s` value in the
- // signature.
- mstore(
- add(signature, ECDSA_signature_s_offset),
- and(
- originalSignatureS,
- EIP2098_allButHighestBitMask
- )
- )
- }
- // Temporarily overwrite the signature length with `v` to
- // conform to the expected input for ecrecover.
- mstore(signature, v)
-
- // Temporarily overwrite the word before the length with
- // `digest` to conform to the expected input for ecrecover.
- mstore(wordBeforeSignaturePtr, digest)
-
- // Attempt to recover the signer for the given signature. Do
- // not check the call status as ecrecover will return a null
- // address if the signature is invalid.
- pop(
- staticcall(
- gas(),
- Ecrecover_precompile, // Call ecrecover precompile.
- wordBeforeSignaturePtr, // Use data memory location.
- Ecrecover_args_size, // Size of digest, v, r, and s.
- 0, // Write result to scratch space.
- OneWord // Provide size of returned result.
- )
- )
-
- // Restore cached word before signature.
- mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature)
-
- // Restore cached signature length.
- mstore(signature, signatureLength)
-
- // Restore cached signature `s` value.
- mstore(
- add(signature, ECDSA_signature_s_offset),
- originalSignatureS
- )
-
- // Read the recovered signer from the buffer given as return
- // space for ecrecover.
- recoveredSigner := mload(0)
- }
-
- // Set success to true if the signature provided was a valid
- // ECDSA signature and the signer is not the null address. Use
- // gt instead of direct as success is used outside of assembly.
- success := and(eq(signer, recoveredSigner), gt(signer, 0))
- }
-
- // If the signature was not verified with ecrecover, try EIP1271.
- if iszero(success) {
- // Reset the original signature length.
- mstore(signature, originalSignatureLength)
-
- // Temporarily overwrite the word before the signature length
- // and use it as the head of the signature input to
- // `isValidSignature`, which has a value of 64.
- mstore(
- wordBeforeSignaturePtr,
- EIP1271_isValidSignature_signature_head_offset
- )
-
- // Get pointer to use for the selector of `isValidSignature`.
- let selectorPtr := sub(
- signature,
- EIP1271_isValidSignature_selector_negativeOffset
- )
-
- // Cache the value currently stored at the selector pointer.
- let cachedWordOverwrittenBySelector := mload(selectorPtr)
-
- // Cache the value currently stored at the digest pointer.
- let cachedWordOverwrittenByDigest := mload(
- sub(
- signature,
- EIP1271_isValidSignature_digest_negativeOffset
- )
- )
-
- // Write the selector first, since it overlaps the digest.
- mstore(selectorPtr, EIP1271_isValidSignature_selector)
-
- // Next, write the original digest.
- mstore(
- sub(
- signature,
- EIP1271_isValidSignature_digest_negativeOffset
- ),
- originalDigest
- )
-
- // Call signer with `isValidSignature` to validate signature.
- success := staticcall(
- gas(),
- signer,
- selectorPtr,
- add(
- originalSignatureLength,
- EIP1271_isValidSignature_calldata_baseLength
- ),
- 0,
- OneWord
- )
-
- // Determine if the signature is valid on successful calls.
- if success {
- // If first word of scratch space does not contain EIP-1271
- // signature selector, revert.
- if iszero(eq(mload(0), EIP1271_isValidSignature_selector)) {
- // Revert with bad 1271 signature if signer has code.
- if extcodesize(signer) {
- // Bad contract signature.
- // Store left-padded selector with push4, mem[28:32]
- mstore(0, BadContractSignature_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "BadContractSignature()"
- // ))
- revert(
- Error_selector_offset,
- BadContractSignature_error_length
- )
- }
-
- // Check if signature length was invalid.
- if gt(sub(ECDSA_MaxLength, signatureLength), 1) {
- // Revert with generic invalid signature error.
- // Store left-padded selector with push4, mem[28:32]
- mstore(0, InvalidSignature_error_selector)
-
- // revert(abi.encodeWithSignature(
- // "InvalidSignature()"
- // ))
- revert(
- Error_selector_offset,
- InvalidSignature_error_length
- )
- }
-
- // Check if v was invalid.
- if and(
- eq(signatureLength, ECDSA_MaxLength),
- iszero(
- byte(
- byte(
- 0,
- mload(
- add(
- signature,
- ECDSA_signature_v_offset
- )
- )
- ),
- ECDSA_twentySeventhAndTwentyEighthBytesSet
- )
- )
- ) {
- // Revert with invalid v value.
- // Store left-padded selector with push4, mem[28:32]
- mstore(0, BadSignatureV_error_selector)
- mstore(
- BadSignatureV_error_v_ptr,
- byte(
- 0,
- mload(
- add(signature, ECDSA_signature_v_offset)
- )
- )
- )
-
- // revert(abi.encodeWithSignature(
- // "BadSignatureV(uint8)", v
- // ))
- revert(
- Error_selector_offset,
- BadSignatureV_error_length
- )
- }
-
- // Revert with generic invalid signer error message.
- // Store left-padded selector with push4, mem[28:32]
- mstore(0, InvalidSigner_error_selector)
-
- // revert(abi.encodeWithSignature("InvalidSigner()"))
- revert(
- Error_selector_offset,
- InvalidSigner_error_length
- )
- }
- }
-
- // Restore the cached values overwritten by selector, digest and
- // signature head.
- mstore(wordBeforeSignaturePtr, cachedWordBeforeSignature)
- mstore(selectorPtr, cachedWordOverwrittenBySelector)
- mstore(
- sub(
- signature,
- EIP1271_isValidSignature_digest_negativeOffset
- ),
- cachedWordOverwrittenByDigest
- )
- }
- }
-
- // If the call failed...
- if (!success) {
- // Revert and pass reason along if one was returned.
- _revertWithReasonIfOneIsReturned();
-
- // Otherwise, revert with error indicating bad contract signature.
- assembly {
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, BadContractSignature_error_selector)
- // revert(abi.encodeWithSignature("BadContractSignature()"))
- revert(Error_selector_offset, BadContractSignature_error_length)
- }
- }
- }
-}
diff --git a/contracts/lib/TokenTransferrer.sol b/contracts/lib/TokenTransferrer.sol
deleted file mode 100644
index 05f1e7a0b..000000000
--- a/contracts/lib/TokenTransferrer.sol
+++ /dev/null
@@ -1,913 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-import {
- BadReturnValueFromERC20OnTransfer_error_amount_ptr,
- BadReturnValueFromERC20OnTransfer_error_from_ptr,
- BadReturnValueFromERC20OnTransfer_error_length,
- BadReturnValueFromERC20OnTransfer_error_selector,
- BadReturnValueFromERC20OnTransfer_error_to_ptr,
- BadReturnValueFromERC20OnTransfer_error_token_ptr,
- BatchTransfer1155Params_amounts_head_ptr,
- BatchTransfer1155Params_calldata_baseSize,
- BatchTransfer1155Params_data_head_ptr,
- BatchTransfer1155Params_data_length_basePtr,
- BatchTransfer1155Params_ids_head_ptr,
- BatchTransfer1155Params_ids_length_offset,
- BatchTransfer1155Params_ids_length_ptr,
- BatchTransfer1155Params_ptr,
- ConduitBatch1155Transfer_amounts_length_baseOffset,
- ConduitBatch1155Transfer_from_offset,
- ConduitBatch1155Transfer_ids_head_offset,
- ConduitBatch1155Transfer_ids_length_offset,
- ConduitBatch1155Transfer_usable_head_size,
- ConduitBatchTransfer_amounts_head_offset,
- CostPerWord,
- DefaultFreeMemoryPointer,
- ERC1155_safeBatchTransferFrom_signature,
- ERC1155_safeTransferFrom_amount_ptr,
- ERC1155_safeTransferFrom_data_length_offset,
- ERC1155_safeTransferFrom_data_length_ptr,
- ERC1155_safeTransferFrom_data_offset_ptr,
- ERC1155_safeTransferFrom_from_ptr,
- ERC1155_safeTransferFrom_id_ptr,
- ERC1155_safeTransferFrom_length,
- ERC1155_safeTransferFrom_sig_ptr,
- ERC1155_safeTransferFrom_signature,
- ERC1155_safeTransferFrom_to_ptr,
- ERC1155BatchTransferGenericFailure_error_signature,
- ERC1155BatchTransferGenericFailure_ids_offset,
- ERC1155BatchTransferGenericFailure_token_ptr,
- ERC20_transferFrom_amount_ptr,
- ERC20_transferFrom_from_ptr,
- ERC20_transferFrom_length,
- ERC20_transferFrom_sig_ptr,
- ERC20_transferFrom_signature,
- ERC20_transferFrom_to_ptr,
- ERC721_transferFrom_from_ptr,
- ERC721_transferFrom_id_ptr,
- ERC721_transferFrom_length,
- ERC721_transferFrom_sig_ptr,
- ERC721_transferFrom_signature,
- ERC721_transferFrom_to_ptr,
- ExtraGasBuffer,
- FreeMemoryPointerSlot,
- Generic_error_selector_offset,
- Invalid1155BatchTransferEncoding_length,
- Invalid1155BatchTransferEncoding_ptr,
- Invalid1155BatchTransferEncoding_selector,
- MemoryExpansionCoefficientShift,
- NoContract_error_account_ptr,
- NoContract_error_length,
- NoContract_error_selector,
- OneWord,
- OneWordShift,
- Slot0x80,
- Slot0xA0,
- Slot0xC0,
- ThirtyOneBytes,
- TokenTransferGenericFailure_err_identifier_ptr,
- TokenTransferGenericFailure_error_amount_ptr,
- TokenTransferGenericFailure_error_from_ptr,
- TokenTransferGenericFailure_error_identifier_ptr,
- TokenTransferGenericFailure_error_length,
- TokenTransferGenericFailure_error_selector,
- TokenTransferGenericFailure_error_to_ptr,
- TokenTransferGenericFailure_error_token_ptr,
- TwoWords,
- TwoWordsShift,
- ZeroSlot
-} from "./TokenTransferrerConstants.sol";
-
-import {
- TokenTransferrerErrors
-} from "../interfaces/TokenTransferrerErrors.sol";
-
-import { ConduitBatch1155Transfer } from "../conduit/lib/ConduitStructs.sol";
-
-/**
- * @title TokenTransferrer
- * @author 0age
- * @custom:coauthor d1ll0n
- * @custom:coauthor transmissions11
- * @notice TokenTransferrer is a library for performing optimized ERC20, ERC721,
- * ERC1155, and batch ERC1155 transfers, used by both Seaport as well as
- * by conduits deployed by the ConduitController. Use great caution when
- * considering these functions for use in other codebases, as there are
- * significant side effects and edge cases that need to be thoroughly
- * understood and carefully addressed.
- */
-contract TokenTransferrer is TokenTransferrerErrors {
- /**
- * @dev Internal function to transfer ERC20 tokens from a given originator
- * to a given recipient. Sufficient approvals must be set on the
- * contract performing the transfer.
- *
- * @param token The ERC20 token to transfer.
- * @param from The originator of the transfer.
- * @param to The recipient of the transfer.
- * @param amount The amount to transfer.
- */
- function _performERC20Transfer(
- address token,
- address from,
- address to,
- uint256 amount
- ) internal {
- // Utilize assembly to perform an optimized ERC20 token transfer.
- assembly {
- // The free memory pointer memory slot will be used when populating
- // call data for the transfer; read the value and restore it later.
- let memPointer := mload(FreeMemoryPointerSlot)
-
- // Write call data into memory, starting with function selector.
- mstore(ERC20_transferFrom_sig_ptr, ERC20_transferFrom_signature)
- mstore(ERC20_transferFrom_from_ptr, from)
- mstore(ERC20_transferFrom_to_ptr, to)
- mstore(ERC20_transferFrom_amount_ptr, amount)
-
- // Make call & copy up to 32 bytes of return data to scratch space.
- // Scratch space does not need to be cleared ahead of time, as the
- // subsequent check will ensure that either at least a full word of
- // return data is received (in which case it will be overwritten) or
- // that no data is received (in which case scratch space will be
- // ignored) on a successful call to the given token.
- let callStatus := call(
- gas(),
- token,
- 0,
- ERC20_transferFrom_sig_ptr,
- ERC20_transferFrom_length,
- 0,
- OneWord
- )
-
- // Determine whether transfer was successful using status & result.
- let success := and(
- // Set success to whether the call reverted, if not check it
- // either returned exactly 1 (can't just be non-zero data), or
- // had no return data.
- or(
- and(eq(mload(0), 1), gt(returndatasize(), 31)),
- iszero(returndatasize())
- ),
- callStatus
- )
-
- // Handle cases where either the transfer failed or no data was
- // returned. Group these, as most transfers will succeed with data.
- // Equivalent to `or(iszero(success), iszero(returndatasize()))`
- // but after it's inverted for JUMPI this expression is cheaper.
- if iszero(and(success, iszero(iszero(returndatasize())))) {
- // If the token has no code or the transfer failed: Equivalent
- // to `or(iszero(success), iszero(extcodesize(token)))` but
- // after it's inverted for JUMPI this expression is cheaper.
- if iszero(and(iszero(iszero(extcodesize(token))), success)) {
- // If the transfer failed:
- if iszero(success) {
- // If it was due to a revert:
- if iszero(callStatus) {
- // If it returned a message, bubble it up as long as
- // sufficient gas remains to do so:
- if returndatasize() {
- // Ensure that sufficient gas is available to
- // copy returndata while expanding memory where
- // necessary. Start by computing the word size
- // of returndata and allocated memory. Round up
- // to the nearest full word.
- let returnDataWords := shr(
- OneWordShift,
- add(returndatasize(), ThirtyOneBytes)
- )
-
- // Note: use the free memory pointer in place of
- // msize() to work around a Yul warning that
- // prevents accessing msize directly when the IR
- // pipeline is activated.
- let msizeWords := shr(OneWordShift, memPointer)
-
- // Next, compute the cost of the returndatacopy.
- let cost := mul(CostPerWord, returnDataWords)
-
- // Then, compute cost of new memory allocation.
- if gt(returnDataWords, msizeWords) {
- cost := add(
- cost,
- add(
- mul(
- sub(
- returnDataWords,
- msizeWords
- ),
- CostPerWord
- ),
- shr(
- MemoryExpansionCoefficientShift,
- sub(
- mul(
- returnDataWords,
- returnDataWords
- ),
- mul(msizeWords, msizeWords)
- )
- )
- )
- )
- }
-
- // Finally, add a small constant and compare to
- // gas remaining; bubble up the revert data if
- // enough gas is still available.
- if lt(add(cost, ExtraGasBuffer), gas()) {
- // Copy returndata to memory; overwrite
- // existing memory.
- returndatacopy(0, 0, returndatasize())
-
- // Revert, specifying memory region with
- // copied returndata.
- revert(0, returndatasize())
- }
- }
-
- // Store left-padded selector with push4, mem[28:32]
- mstore(
- 0,
- TokenTransferGenericFailure_error_selector
- )
- mstore(
- TokenTransferGenericFailure_error_token_ptr,
- token
- )
- mstore(
- TokenTransferGenericFailure_error_from_ptr,
- from
- )
- mstore(TokenTransferGenericFailure_error_to_ptr, to)
- mstore(
- TokenTransferGenericFailure_err_identifier_ptr,
- 0
- )
- mstore(
- TokenTransferGenericFailure_error_amount_ptr,
- amount
- )
-
- // revert(abi.encodeWithSignature(
- // "TokenTransferGenericFailure(
- // address,address,address,uint256,uint256
- // )", token, from, to, identifier, amount
- // ))
- revert(
- Generic_error_selector_offset,
- TokenTransferGenericFailure_error_length
- )
- }
-
- // Otherwise revert with a message about the token
- // returning false or non-compliant return values.
-
- // Store left-padded selector with push4, mem[28:32]
- mstore(
- 0,
- BadReturnValueFromERC20OnTransfer_error_selector
- )
- mstore(
- BadReturnValueFromERC20OnTransfer_error_token_ptr,
- token
- )
- mstore(
- BadReturnValueFromERC20OnTransfer_error_from_ptr,
- from
- )
- mstore(
- BadReturnValueFromERC20OnTransfer_error_to_ptr,
- to
- )
- mstore(
- BadReturnValueFromERC20OnTransfer_error_amount_ptr,
- amount
- )
-
- // revert(abi.encodeWithSignature(
- // "BadReturnValueFromERC20OnTransfer(
- // address,address,address,uint256
- // )", token, from, to, amount
- // ))
- revert(
- Generic_error_selector_offset,
- BadReturnValueFromERC20OnTransfer_error_length
- )
- }
-
- // Otherwise, revert with error about token not having code:
- // Store left-padded selector with push4, mem[28:32]
- mstore(0, NoContract_error_selector)
- mstore(NoContract_error_account_ptr, token)
-
- // revert(abi.encodeWithSignature(
- // "NoContract(address)", account
- // ))
- revert(
- Generic_error_selector_offset,
- NoContract_error_length
- )
- }
-
- // Otherwise, the token just returned no data despite the call
- // having succeeded; no need to optimize for this as it's not
- // technically ERC20 compliant.
- }
-
- // Restore the original free memory pointer.
- mstore(FreeMemoryPointerSlot, memPointer)
-
- // Restore the zero slot to zero.
- mstore(ZeroSlot, 0)
- }
- }
-
- /**
- * @dev Internal function to transfer an ERC721 token from a given
- * originator to a given recipient. Sufficient approvals must be set on
- * the contract performing the transfer. Note that this function does
- * not check whether the receiver can accept the ERC721 token (i.e. it
- * does not use `safeTransferFrom`).
- *
- * @param token The ERC721 token to transfer.
- * @param from The originator of the transfer.
- * @param to The recipient of the transfer.
- * @param identifier The tokenId to transfer.
- */
- function _performERC721Transfer(
- address token,
- address from,
- address to,
- uint256 identifier
- ) internal {
- // Utilize assembly to perform an optimized ERC721 token transfer.
- assembly {
- // If the token has no code, revert.
- if iszero(extcodesize(token)) {
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, NoContract_error_selector)
- mstore(NoContract_error_account_ptr, token)
-
- // revert(abi.encodeWithSignature(
- // "NoContract(address)", account
- // ))
- revert(Generic_error_selector_offset, NoContract_error_length)
- }
-
- // The free memory pointer memory slot will be used when populating
- // call data for the transfer; read the value and restore it later.
- let memPointer := mload(FreeMemoryPointerSlot)
-
- // Write call data to memory starting with function selector.
- mstore(ERC721_transferFrom_sig_ptr, ERC721_transferFrom_signature)
- mstore(ERC721_transferFrom_from_ptr, from)
- mstore(ERC721_transferFrom_to_ptr, to)
- mstore(ERC721_transferFrom_id_ptr, identifier)
-
- // Perform the call, ignoring return data.
- let success := call(
- gas(),
- token,
- 0,
- ERC721_transferFrom_sig_ptr,
- ERC721_transferFrom_length,
- 0,
- 0
- )
-
- // If the transfer reverted:
- if iszero(success) {
- // If it returned a message, bubble it up as long as sufficient
- // gas remains to do so:
- if returndatasize() {
- // Ensure that sufficient gas is available to copy
- // returndata while expanding memory where necessary. Start
- // by computing word size of returndata & allocated memory.
- // Round up to the nearest full word.
- let returnDataWords := shr(
- OneWordShift,
- add(returndatasize(), ThirtyOneBytes)
- )
-
- // Note: use the free memory pointer in place of msize() to
- // work around a Yul warning that prevents accessing msize
- // directly when the IR pipeline is activated.
- let msizeWords := shr(OneWordShift, memPointer)
-
- // Next, compute the cost of the returndatacopy.
- let cost := mul(CostPerWord, returnDataWords)
-
- // Then, compute cost of new memory allocation.
- if gt(returnDataWords, msizeWords) {
- cost := add(
- cost,
- add(
- mul(
- sub(returnDataWords, msizeWords),
- CostPerWord
- ),
- shr(
- MemoryExpansionCoefficientShift,
- sub(
- mul(returnDataWords, returnDataWords),
- mul(msizeWords, msizeWords)
- )
- )
- )
- )
- }
-
- // Finally, add a small constant and compare to gas
- // remaining; bubble up the revert data if enough gas is
- // still available.
- if lt(add(cost, ExtraGasBuffer), gas()) {
- // Copy returndata to memory; overwrite existing memory.
- returndatacopy(0, 0, returndatasize())
-
- // Revert, giving memory region with copied returndata.
- revert(0, returndatasize())
- }
- }
-
- // Otherwise revert with a generic error message.
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, TokenTransferGenericFailure_error_selector)
- mstore(TokenTransferGenericFailure_error_token_ptr, token)
- mstore(TokenTransferGenericFailure_error_from_ptr, from)
- mstore(TokenTransferGenericFailure_error_to_ptr, to)
- mstore(
- TokenTransferGenericFailure_error_identifier_ptr,
- identifier
- )
- mstore(TokenTransferGenericFailure_error_amount_ptr, 1)
-
- // revert(abi.encodeWithSignature(
- // "TokenTransferGenericFailure(
- // address,address,address,uint256,uint256
- // )", token, from, to, identifier, amount
- // ))
- revert(
- Generic_error_selector_offset,
- TokenTransferGenericFailure_error_length
- )
- }
-
- // Restore the original free memory pointer.
- mstore(FreeMemoryPointerSlot, memPointer)
-
- // Restore the zero slot to zero.
- mstore(ZeroSlot, 0)
- }
- }
-
- /**
- * @dev Internal function to transfer ERC1155 tokens from a given
- * originator to a given recipient. Sufficient approvals must be set on
- * the contract performing the transfer and contract recipients must
- * implement the ERC1155TokenReceiver interface to indicate that they
- * are willing to accept the transfer.
- *
- * @param token The ERC1155 token to transfer.
- * @param from The originator of the transfer.
- * @param to The recipient of the transfer.
- * @param identifier The id to transfer.
- * @param amount The amount to transfer.
- */
- function _performERC1155Transfer(
- address token,
- address from,
- address to,
- uint256 identifier,
- uint256 amount
- ) internal {
- // Utilize assembly to perform an optimized ERC1155 token transfer.
- assembly {
- // If the token has no code, revert.
- if iszero(extcodesize(token)) {
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, NoContract_error_selector)
- mstore(NoContract_error_account_ptr, token)
-
- // revert(abi.encodeWithSignature(
- // "NoContract(address)", account
- // ))
- revert(Generic_error_selector_offset, NoContract_error_length)
- }
-
- // The following memory slots will be used when populating call data
- // for the transfer; read the values and restore them later.
- let memPointer := mload(FreeMemoryPointerSlot)
- let slot0x80 := mload(Slot0x80)
- let slot0xA0 := mload(Slot0xA0)
- let slot0xC0 := mload(Slot0xC0)
-
- // Write call data into memory, beginning with function selector.
- mstore(
- ERC1155_safeTransferFrom_sig_ptr,
- ERC1155_safeTransferFrom_signature
- )
- mstore(ERC1155_safeTransferFrom_from_ptr, from)
- mstore(ERC1155_safeTransferFrom_to_ptr, to)
- mstore(ERC1155_safeTransferFrom_id_ptr, identifier)
- mstore(ERC1155_safeTransferFrom_amount_ptr, amount)
- mstore(
- ERC1155_safeTransferFrom_data_offset_ptr,
- ERC1155_safeTransferFrom_data_length_offset
- )
- mstore(ERC1155_safeTransferFrom_data_length_ptr, 0)
-
- // Perform the call, ignoring return data.
- let success := call(
- gas(),
- token,
- 0,
- ERC1155_safeTransferFrom_sig_ptr,
- ERC1155_safeTransferFrom_length,
- 0,
- 0
- )
-
- // If the transfer reverted:
- if iszero(success) {
- // If it returned a message, bubble it up as long as sufficient
- // gas remains to do so:
- if returndatasize() {
- // Ensure that sufficient gas is available to copy
- // returndata while expanding memory where necessary. Start
- // by computing word size of returndata & allocated memory.
- // Round up to the nearest full word.
- let returnDataWords := shr(
- OneWordShift,
- add(returndatasize(), ThirtyOneBytes)
- )
-
- // Note: use the free memory pointer in place of msize() to
- // work around a Yul warning that prevents accessing msize
- // directly when the IR pipeline is activated.
- let msizeWords := shr(OneWordShift, memPointer)
-
- // Next, compute the cost of the returndatacopy.
- let cost := mul(CostPerWord, returnDataWords)
-
- // Then, compute cost of new memory allocation.
- if gt(returnDataWords, msizeWords) {
- cost := add(
- cost,
- add(
- mul(
- sub(returnDataWords, msizeWords),
- CostPerWord
- ),
- shr(
- MemoryExpansionCoefficientShift,
- sub(
- mul(returnDataWords, returnDataWords),
- mul(msizeWords, msizeWords)
- )
- )
- )
- )
- }
-
- // Finally, add a small constant and compare to gas
- // remaining; bubble up the revert data if enough gas is
- // still available.
- if lt(add(cost, ExtraGasBuffer), gas()) {
- // Copy returndata to memory; overwrite existing memory.
- returndatacopy(0, 0, returndatasize())
-
- // Revert, giving memory region with copied returndata.
- revert(0, returndatasize())
- }
- }
-
- // Otherwise revert with a generic error message.
-
- // Store left-padded selector with push4, mem[28:32] = selector
- mstore(0, TokenTransferGenericFailure_error_selector)
- mstore(TokenTransferGenericFailure_error_token_ptr, token)
- mstore(TokenTransferGenericFailure_error_from_ptr, from)
- mstore(TokenTransferGenericFailure_error_to_ptr, to)
- mstore(
- TokenTransferGenericFailure_error_identifier_ptr,
- identifier
- )
- mstore(TokenTransferGenericFailure_error_amount_ptr, amount)
-
- // revert(abi.encodeWithSignature(
- // "TokenTransferGenericFailure(
- // address,address,address,uint256,uint256
- // )", token, from, to, identifier, amount
- // ))
- revert(
- Generic_error_selector_offset,
- TokenTransferGenericFailure_error_length
- )
- }
-
- mstore(Slot0x80, slot0x80) // Restore slot 0x80.
- mstore(Slot0xA0, slot0xA0) // Restore slot 0xA0.
- mstore(Slot0xC0, slot0xC0) // Restore slot 0xC0.
-
- // Restore the original free memory pointer.
- mstore(FreeMemoryPointerSlot, memPointer)
-
- // Restore the zero slot to zero.
- mstore(ZeroSlot, 0)
- }
- }
-
- /**
- * @dev Internal function to transfer ERC1155 tokens from a given
- * originator to a given recipient. Sufficient approvals must be set on
- * the contract performing the transfer and contract recipients must
- * implement the ERC1155TokenReceiver interface to indicate that they
- * are willing to accept the transfer. NOTE: this function is not
- * memory-safe; it will overwrite existing memory, restore the free
- * memory pointer to the default value, and overwrite the zero slot.
- * This function should only be called once memory is no longer
- * required and when uninitialized arrays are not utilized, and memory
- * should be considered fully corrupted (aside from the existence of a
- * default-value free memory pointer) after calling this function.
- *
- * @param batchTransfers The group of 1155 batch transfers to perform.
- */
- function _performERC1155BatchTransfers(
- ConduitBatch1155Transfer[] calldata batchTransfers
- ) internal {
- // Utilize assembly to perform optimized batch 1155 transfers.
- assembly {
- let len := batchTransfers.length
- // Pointer to first head in the array, which is offset to the struct
- // at each index. This gets incremented after each loop to avoid
- // multiplying by 32 to get the offset for each element.
- let nextElementHeadPtr := batchTransfers.offset
-
- // Pointer to beginning of the head of the array. This is the
- // reference position each offset references. It's held static to
- // let each loop calculate the data position for an element.
- let arrayHeadPtr := nextElementHeadPtr
-
- // Write the function selector, which will be reused for each call:
- // safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)
- mstore(
- ConduitBatch1155Transfer_from_offset,
- ERC1155_safeBatchTransferFrom_signature
- )
-
- // Iterate over each batch transfer.
- for {
- let i := 0
- } lt(i, len) {
- i := add(i, 1)
- } {
- // Read the offset to the beginning of the element and add
- // it to pointer to the beginning of the array head to get
- // the absolute position of the element in calldata.
- let elementPtr := add(
- arrayHeadPtr,
- calldataload(nextElementHeadPtr)
- )
-
- // Retrieve the token from calldata.
- let token := calldataload(elementPtr)
-
- // If the token has no code, revert.
- if iszero(extcodesize(token)) {
- // Store left-padded selector with push4, mem[28:32]
- mstore(0, NoContract_error_selector)
- mstore(NoContract_error_account_ptr, token)
-
- // revert(abi.encodeWithSignature(
- // "NoContract(address)", account
- // ))
- revert(
- Generic_error_selector_offset,
- NoContract_error_length
- )
- }
-
- // Get the total number of supplied ids.
- let idsLength := calldataload(
- add(elementPtr, ConduitBatch1155Transfer_ids_length_offset)
- )
-
- // Determine the expected offset for the amounts array.
- let expectedAmountsOffset := add(
- ConduitBatch1155Transfer_amounts_length_baseOffset,
- shl(OneWordShift, idsLength)
- )
-
- // Validate struct encoding.
- let invalidEncoding := iszero(
- and(
- // ids.length == amounts.length
- eq(
- idsLength,
- calldataload(add(elementPtr, expectedAmountsOffset))
- ),
- and(
- // ids_offset == 0xa0
- eq(
- calldataload(
- add(
- elementPtr,
- ConduitBatch1155Transfer_ids_head_offset
- )
- ),
- ConduitBatch1155Transfer_ids_length_offset
- ),
- // amounts_offset == 0xc0 + ids.length*32
- eq(
- calldataload(
- add(
- elementPtr,
- ConduitBatchTransfer_amounts_head_offset
- )
- ),
- expectedAmountsOffset
- )
- )
- )
- )
-
- // Revert with an error if the encoding is not valid.
- if invalidEncoding {
- // Store left-padded selector with push4, mem[28:32]
- mstore(
- Invalid1155BatchTransferEncoding_ptr,
- Invalid1155BatchTransferEncoding_selector
- )
-
- // revert(abi.encodeWithSignature(
- // "Invalid1155BatchTransferEncoding()"
- // ))
- revert(
- Invalid1155BatchTransferEncoding_ptr,
- Invalid1155BatchTransferEncoding_length
- )
- }
-
- // Update the offset position for the next loop
- nextElementHeadPtr := add(nextElementHeadPtr, OneWord)
-
- // Copy the first section of calldata (before dynamic values).
- calldatacopy(
- BatchTransfer1155Params_ptr,
- add(elementPtr, ConduitBatch1155Transfer_from_offset),
- ConduitBatch1155Transfer_usable_head_size
- )
-
- // Determine size of calldata required for ids and amounts. Note
- // that the size includes both lengths as well as the data.
- let idsAndAmountsSize := add(
- TwoWords,
- shl(TwoWordsShift, idsLength)
- )
-
- // Update the offset for the data array in memory.
- mstore(
- BatchTransfer1155Params_data_head_ptr,
- add(
- BatchTransfer1155Params_ids_length_offset,
- idsAndAmountsSize
- )
- )
-
- // Set the length of the data array in memory to zero.
- mstore(
- add(
- BatchTransfer1155Params_data_length_basePtr,
- idsAndAmountsSize
- ),
- 0
- )
-
- // Determine the total calldata size for the call to transfer.
- let transferDataSize := add(
- BatchTransfer1155Params_calldata_baseSize,
- idsAndAmountsSize
- )
-
- // Copy second section of calldata (including dynamic values).
- calldatacopy(
- BatchTransfer1155Params_ids_length_ptr,
- add(elementPtr, ConduitBatch1155Transfer_ids_length_offset),
- idsAndAmountsSize
- )
-
- // Perform the call to transfer 1155 tokens.
- let success := call(
- gas(),
- token,
- 0,
- ConduitBatch1155Transfer_from_offset, // Data portion start.
- transferDataSize, // Location of the length of callData.
- 0,
- 0
- )
-
- // If the transfer reverted:
- if iszero(success) {
- // If it returned a message, bubble it up as long as
- // sufficient gas remains to do so:
- if returndatasize() {
- // Ensure that sufficient gas is available to copy
- // returndata while expanding memory where necessary.
- // Start by computing word size of returndata and
- // allocated memory. Round up to the nearest full word.
- let returnDataWords := shr(
- OneWordShift,
- add(returndatasize(), ThirtyOneBytes)
- )
-
- // Note: use transferDataSize in place of msize() to
- // work around a Yul warning that prevents accessing
- // msize directly when the IR pipeline is activated.
- // The free memory pointer is not used here because
- // this function does almost all memory management
- // manually and does not update it, and transferDataSize
- // should be the largest memory value used (unless a
- // previous batch was larger).
- let msizeWords := shr(OneWordShift, transferDataSize)
-
- // Next, compute the cost of the returndatacopy.
- let cost := mul(CostPerWord, returnDataWords)
-
- // Then, compute cost of new memory allocation.
- if gt(returnDataWords, msizeWords) {
- cost := add(
- cost,
- add(
- mul(
- sub(returnDataWords, msizeWords),
- CostPerWord
- ),
- shr(
- MemoryExpansionCoefficientShift,
- sub(
- mul(
- returnDataWords,
- returnDataWords
- ),
- mul(msizeWords, msizeWords)
- )
- )
- )
- )
- }
-
- // Finally, add a small constant and compare to gas
- // remaining; bubble up the revert data if enough gas is
- // still available.
- if lt(add(cost, ExtraGasBuffer), gas()) {
- // Copy returndata to memory; overwrite existing.
- returndatacopy(0, 0, returndatasize())
-
- // Revert with memory region containing returndata.
- revert(0, returndatasize())
- }
- }
-
- // Set the error signature.
- mstore(
- 0,
- ERC1155BatchTransferGenericFailure_error_signature
- )
-
- // Write the token.
- mstore(ERC1155BatchTransferGenericFailure_token_ptr, token)
-
- // Increase the offset to ids by 32.
- mstore(
- BatchTransfer1155Params_ids_head_ptr,
- ERC1155BatchTransferGenericFailure_ids_offset
- )
-
- // Increase the offset to amounts by 32.
- mstore(
- BatchTransfer1155Params_amounts_head_ptr,
- add(
- OneWord,
- mload(BatchTransfer1155Params_amounts_head_ptr)
- )
- )
-
- // Return modified region. The total size stays the same as
- // `token` uses the same number of bytes as `data.length`.
- revert(0, transferDataSize)
- }
- }
-
- // Reset the free memory pointer to the default value; memory must
- // be assumed to be dirtied and not reused from this point forward.
- // Also note that the zero slot is not reset to zero, meaning empty
- // arrays cannot be safely created or utilized until it is restored.
- mstore(FreeMemoryPointerSlot, DefaultFreeMemoryPointer)
- }
- }
-}
diff --git a/contracts/lib/TokenTransferrerConstants.sol b/contracts/lib/TokenTransferrerConstants.sol
deleted file mode 100644
index 111a756c9..000000000
--- a/contracts/lib/TokenTransferrerConstants.sol
+++ /dev/null
@@ -1,200 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.13;
-
-/*
- * -------------------------- Disambiguation & Other Notes ---------------------
- * - The term "head" is used as it is in the documentation for ABI encoding,
- * but only in reference to dynamic types, i.e. it always refers to the
- * offset or pointer to the body of a dynamic type. In calldata, the head
- * is always an offset (relative to the parent object), while in memory,
- * the head is always the pointer to the body. More information found here:
- * https://docs.soliditylang.org/en/v0.8.17/abi-spec.html#argument-encoding
- * - Note that the length of an array is separate from and precedes the
- * head of the array.
- *
- * - The term "body" is used in place of the term "head" used in the ABI
- * documentation. It refers to the start of the data for a dynamic type,
- * e.g. the first word of a struct or the first word of the first element
- * in an array.
- *
- * - The term "pointer" is used to describe the absolute position of a value
- * and never an offset relative to another value.
- * - The suffix "_ptr" refers to a memory pointer.
- * - The suffix "_cdPtr" refers to a calldata pointer.
- *
- * - The term "offset" is used to describe the position of a value relative
- * to some parent value. For example, OrderParameters_conduit_offset is the
- * offset to the "conduit" value in the OrderParameters struct relative to
- * the start of the body.
- * - Note: Offsets are used to derive pointers.
- *
- * - Some structs have pointers defined for all of their fields in this file.
- * Lines which are commented out are fields that are not used in the
- * codebase but have been left in for readability.
- */
-
-uint256 constant ThirtyOneBytes = 0x1f;
-uint256 constant OneWord = 0x20;
-uint256 constant TwoWords = 0x40;
-uint256 constant ThreeWords = 0x60;
-
-uint256 constant OneWordShift = 0x5;
-uint256 constant TwoWordsShift = 0x6;
-
-uint256 constant FreeMemoryPointerSlot = 0x40;
-uint256 constant ZeroSlot = 0x60;
-uint256 constant DefaultFreeMemoryPointer = 0x80;
-
-uint256 constant Slot0x80 = 0x80;
-uint256 constant Slot0xA0 = 0xa0;
-uint256 constant Slot0xC0 = 0xc0;
-
-uint256 constant Generic_error_selector_offset = 0x1c;
-
-// abi.encodeWithSignature("transferFrom(address,address,uint256)")
-uint256 constant ERC20_transferFrom_signature = (
- 0x23b872dd00000000000000000000000000000000000000000000000000000000
-);
-uint256 constant ERC20_transferFrom_sig_ptr = 0x0;
-uint256 constant ERC20_transferFrom_from_ptr = 0x04;
-uint256 constant ERC20_transferFrom_to_ptr = 0x24;
-uint256 constant ERC20_transferFrom_amount_ptr = 0x44;
-uint256 constant ERC20_transferFrom_length = 0x64; // 4 + 32 * 3 == 100
-
-// abi.encodeWithSignature(
-// "safeTransferFrom(address,address,uint256,uint256,bytes)"
-// )
-uint256 constant ERC1155_safeTransferFrom_signature = (
- 0xf242432a00000000000000000000000000000000000000000000000000000000
-);
-uint256 constant ERC1155_safeTransferFrom_sig_ptr = 0x0;
-uint256 constant ERC1155_safeTransferFrom_from_ptr = 0x04;
-uint256 constant ERC1155_safeTransferFrom_to_ptr = 0x24;
-uint256 constant ERC1155_safeTransferFrom_id_ptr = 0x44;
-uint256 constant ERC1155_safeTransferFrom_amount_ptr = 0x64;
-uint256 constant ERC1155_safeTransferFrom_data_offset_ptr = 0x84;
-uint256 constant ERC1155_safeTransferFrom_data_length_ptr = 0xa4;
-uint256 constant ERC1155_safeTransferFrom_length = 0xc4; // 4 + 32 * 6 == 196
-uint256 constant ERC1155_safeTransferFrom_data_length_offset = 0xa0;
-
-// abi.encodeWithSignature(
-// "safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)"
-// )
-uint256 constant ERC1155_safeBatchTransferFrom_signature = (
- 0x2eb2c2d600000000000000000000000000000000000000000000000000000000
-);
-
-// bytes4 constant ERC1155_safeBatchTransferFrom_selector = bytes4(
-// bytes32(ERC1155_safeBatchTransferFrom_signature)
-// );
-
-uint256 constant ERC721_transferFrom_signature = (
- 0x23b872dd00000000000000000000000000000000000000000000000000000000
-);
-uint256 constant ERC721_transferFrom_sig_ptr = 0x0;
-uint256 constant ERC721_transferFrom_from_ptr = 0x04;
-uint256 constant ERC721_transferFrom_to_ptr = 0x24;
-uint256 constant ERC721_transferFrom_id_ptr = 0x44;
-uint256 constant ERC721_transferFrom_length = 0x64; // 4 + 32 * 3 == 100
-
-/*
- * error NoContract(address account)
- * - Defined in TokenTransferrerErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x00: account
- * Revert buffer is memory[0x1c:0x40]
- */
-uint256 constant NoContract_error_selector = 0x5f15d672;
-uint256 constant NoContract_error_account_ptr = 0x20;
-uint256 constant NoContract_error_length = 0x24;
-
-/*
- * error TokenTransferGenericFailure(
- * address token,
- * address from,
- * address to,
- * uint256 identifier,
- * uint256 amount
- * )
- * - Defined in TokenTransferrerErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x20: token
- * - 0x40: from
- * - 0x60: to
- * - 0x80: identifier
- * - 0xa0: amount
- * Revert buffer is memory[0x1c:0xc0]
- */
-uint256 constant TokenTransferGenericFailure_error_selector = 0xf486bc87;
-uint256 constant TokenTransferGenericFailure_error_token_ptr = 0x20;
-uint256 constant TokenTransferGenericFailure_error_from_ptr = 0x40;
-uint256 constant TokenTransferGenericFailure_error_to_ptr = 0x60;
-uint256 constant TokenTransferGenericFailure_error_identifier_ptr = 0x80;
-uint256 constant TokenTransferGenericFailure_err_identifier_ptr = 0x80;
-uint256 constant TokenTransferGenericFailure_error_amount_ptr = 0xa0;
-uint256 constant TokenTransferGenericFailure_error_length = 0xa4;
-
-uint256 constant ExtraGasBuffer = 0x20;
-uint256 constant CostPerWord = 0x3;
-uint256 constant MemoryExpansionCoefficientShift = 0x9;
-
-// Values are offset by 32 bytes in order to write the token to the beginning
-// in the event of a revert
-uint256 constant BatchTransfer1155Params_ptr = 0x24;
-uint256 constant BatchTransfer1155Params_ids_head_ptr = 0x64;
-uint256 constant BatchTransfer1155Params_amounts_head_ptr = 0x84;
-uint256 constant BatchTransfer1155Params_data_head_ptr = 0xa4;
-uint256 constant BatchTransfer1155Params_data_length_basePtr = 0xc4;
-uint256 constant BatchTransfer1155Params_calldata_baseSize = 0xc4;
-
-uint256 constant BatchTransfer1155Params_ids_length_ptr = 0xc4;
-
-uint256 constant BatchTransfer1155Params_ids_length_offset = 0xa0;
-// uint256 constant BatchTransfer1155Params_amounts_length_baseOffset = 0xc0;
-// uint256 constant BatchTransfer1155Params_data_length_baseOffset = 0xe0;
-
-uint256 constant ConduitBatch1155Transfer_usable_head_size = 0x80;
-
-uint256 constant ConduitBatch1155Transfer_from_offset = 0x20;
-uint256 constant ConduitBatch1155Transfer_ids_head_offset = 0x60;
-// uint256 constant ConduitBatch1155Transfer_amounts_head_offset = 0x80;
-uint256 constant ConduitBatch1155Transfer_ids_length_offset = 0xa0;
-uint256 constant ConduitBatch1155Transfer_amounts_length_baseOffset = 0xc0;
-// uint256 constant ConduitBatch1155Transfer_calldata_baseSize = 0xc0;
-
-// Note: abbreviated version of above constant to adhere to line length limit.
-uint256 constant ConduitBatchTransfer_amounts_head_offset = 0x80;
-
-uint256 constant Invalid1155BatchTransferEncoding_ptr = 0x00;
-uint256 constant Invalid1155BatchTransferEncoding_length = 0x04;
-uint256 constant Invalid1155BatchTransferEncoding_selector = (
- 0xeba2084c00000000000000000000000000000000000000000000000000000000
-);
-
-uint256 constant ERC1155BatchTransferGenericFailure_error_signature = (
- 0xafc445e200000000000000000000000000000000000000000000000000000000
-);
-uint256 constant ERC1155BatchTransferGenericFailure_token_ptr = 0x04;
-uint256 constant ERC1155BatchTransferGenericFailure_ids_offset = 0xc0;
-
-/*
- * error BadReturnValueFromERC20OnTransfer(
- * address token, address from, address to, uint256 amount
- * )
- * - Defined in TokenTransferrerErrors.sol
- * Memory layout:
- * - 0x00: Left-padded selector (data begins at 0x1c)
- * - 0x00: token
- * - 0x20: from
- * - 0x40: to
- * - 0x60: amount
- * Revert buffer is memory[0x1c:0xa0]
- */
-uint256 constant BadReturnValueFromERC20OnTransfer_error_selector = 0x98891923;
-uint256 constant BadReturnValueFromERC20OnTransfer_error_token_ptr = 0x20;
-uint256 constant BadReturnValueFromERC20OnTransfer_error_from_ptr = 0x40;
-uint256 constant BadReturnValueFromERC20OnTransfer_error_to_ptr = 0x60;
-uint256 constant BadReturnValueFromERC20OnTransfer_error_amount_ptr = 0x80;
-uint256 constant BadReturnValueFromERC20OnTransfer_error_length = 0x84;
diff --git a/contracts/lib/Verifiers.sol b/contracts/lib/Verifiers.sol
deleted file mode 100644
index 46587429f..000000000
--- a/contracts/lib/Verifiers.sol
+++ /dev/null
@@ -1,303 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { OrderStatus } from "./ConsiderationStructs.sol";
-
-import { Assertions } from "./Assertions.sol";
-
-import { SignatureVerification } from "./SignatureVerification.sol";
-
-import {
- _revertInvalidTime,
- _revertOrderAlreadyFilled,
- _revertOrderIsCancelled,
- _revertOrderPartiallyFilled
-} from "./ConsiderationErrors.sol";
-
-import {
- BulkOrderProof_keyShift,
- BulkOrderProof_keySize,
- BulkOrderProof_lengthAdjustmentBeforeMask,
- BulkOrderProof_lengthRangeAfterMask,
- BulkOrderProof_minSize,
- BulkOrderProof_rangeSize,
- ECDSA_MaxLength,
- OneWord,
- OneWordShift,
- ThirtyOneBytes,
- TwoWords
-} from "./ConsiderationConstants.sol";
-
-/**
- * @title Verifiers
- * @author 0age
- * @notice Verifiers contains functions for performing verifications.
- */
-contract Verifiers is Assertions, SignatureVerification {
- /**
- * @dev Derive and set hashes, reference chainId, and associated domain
- * separator during deployment.
- *
- * @param conduitController A contract that deploys conduits, or proxies
- * that may optionally be used to transfer approved
- * ERC20/721/1155 tokens.
- */
- constructor(address conduitController) Assertions(conduitController) {}
-
- /**
- * @dev Internal view function to ensure that the current time falls within
- * an order's valid timespan.
- *
- * @param startTime The time at which the order becomes active.
- * @param endTime The time at which the order becomes inactive.
- * @param revertOnInvalid A boolean indicating whether to revert if the
- * order is not active.
- *
- * @return valid A boolean indicating whether the order is active.
- */
- function _verifyTime(
- uint256 startTime,
- uint256 endTime,
- bool revertOnInvalid
- ) internal view returns (bool valid) {
- // Mark as valid if order has started and has not already ended.
- assembly {
- valid := and(
- iszero(gt(startTime, timestamp())),
- gt(endTime, timestamp())
- )
- }
-
- // Only revert on invalid if revertOnInvalid has been supplied as true.
- if (revertOnInvalid && !valid) {
- _revertInvalidTime(startTime, endTime);
- }
- }
-
- /**
- * @dev Internal view function to verify the signature of an order. An
- * ERC-1271 fallback will be attempted if either the signature length
- * is not 64 or 65 bytes or if the recovered signer does not match the
- * supplied offerer. Note that in cases where a 64 or 65 byte signature
- * is supplied, only standard ECDSA signatures that recover to a
- * non-zero address are supported.
- *
- * @param offerer The offerer for the order.
- * @param orderHash The order hash.
- * @param signature A signature from the offerer indicating that the order
- * has been approved.
- */
- function _verifySignature(
- address offerer,
- bytes32 orderHash,
- bytes memory signature
- ) internal view {
- // Determine whether the offerer is the caller.
- bool offererIsCaller;
- assembly {
- offererIsCaller := eq(offerer, caller())
- }
-
- // Skip signature verification if the offerer is the caller.
- if (offererIsCaller) {
- return;
- }
-
- // Derive the EIP-712 domain separator.
- bytes32 domainSeparator = _domainSeparator();
-
- // Derive original EIP-712 digest using domain separator and order hash.
- bytes32 originalDigest = _deriveEIP712Digest(
- domainSeparator,
- orderHash
- );
-
- // Read the length of the signature from memory and place on the stack.
- uint256 originalSignatureLength = signature.length;
-
- // Determine effective digest if signature has a valid bulk order size.
- bytes32 digest;
- if (_isValidBulkOrderSize(originalSignatureLength)) {
- // Rederive order hash and digest using bulk order proof.
- (orderHash) = _computeBulkOrderProof(signature, orderHash);
- digest = _deriveEIP712Digest(domainSeparator, orderHash);
- } else {
- // Supply the original digest as the effective digest.
- digest = originalDigest;
- }
-
- // Ensure that the signature for the digest is valid for the offerer.
- _assertValidSignature(
- offerer,
- digest,
- originalDigest,
- originalSignatureLength,
- signature
- );
- }
-
- /**
- * @dev Determines whether the specified bulk order size is valid.
- *
- * @param signatureLength The signature length of the bulk order to check.
- *
- * @return validLength True if bulk order size is valid, false otherwise.
- */
- function _isValidBulkOrderSize(
- uint256 signatureLength
- ) internal pure returns (bool validLength) {
- // Utilize assembly to validate the length; the equivalent logic is
- // (64 + x) + 3 + 32y where (0 <= x <= 1) and (1 <= y <= 24).
- assembly {
- validLength := and(
- lt(
- sub(signatureLength, BulkOrderProof_minSize),
- BulkOrderProof_rangeSize
- ),
- lt(
- and(
- add(
- signatureLength,
- BulkOrderProof_lengthAdjustmentBeforeMask
- ),
- ThirtyOneBytes
- ),
- BulkOrderProof_lengthRangeAfterMask
- )
- )
- }
- }
-
- /**
- * @dev Computes the bulk order hash for the specified proof and leaf. Note
- * that if an index that exceeds the number of orders in the bulk order
- * payload will instead "wrap around" and refer to an earlier index.
- *
- * @param proofAndSignature The proof and signature of the bulk order.
- * @param leaf The leaf of the bulk order tree.
- *
- * @return bulkOrderHash The bulk order hash.
- */
- function _computeBulkOrderProof(
- bytes memory proofAndSignature,
- bytes32 leaf
- ) internal pure returns (bytes32 bulkOrderHash) {
- // Declare arguments for the root hash and the height of the proof.
- bytes32 root;
- uint256 height;
-
- // Utilize assembly to efficiently derive the root hash using the proof.
- assembly {
- // Retrieve the length of the proof, key, and signature combined.
- let fullLength := mload(proofAndSignature)
-
- // If proofAndSignature has odd length, it is a compact signature
- // with 64 bytes.
- let signatureLength := sub(ECDSA_MaxLength, and(fullLength, 1))
-
- // Derive height (or depth of tree) with signature and proof length.
- height := shr(OneWordShift, sub(fullLength, signatureLength))
-
- // Update the length in memory to only include the signature.
- mstore(proofAndSignature, signatureLength)
-
- // Derive the pointer for the key using the signature length.
- let keyPtr := add(proofAndSignature, add(OneWord, signatureLength))
-
- // Retrieve the three-byte key using the derived pointer.
- let key := shr(BulkOrderProof_keyShift, mload(keyPtr))
-
- /// Retrieve pointer to first proof element by applying a constant
- // for the key size to the derived key pointer.
- let proof := add(keyPtr, BulkOrderProof_keySize)
-
- // Compute level 1.
- let scratchPtr1 := shl(OneWordShift, and(key, 1))
- mstore(scratchPtr1, leaf)
- mstore(xor(scratchPtr1, OneWord), mload(proof))
-
- // Compute remaining proofs.
- for {
- let i := 1
- } lt(i, height) {
- i := add(i, 1)
- } {
- proof := add(proof, OneWord)
- let scratchPtr := shl(OneWordShift, and(shr(i, key), 1))
- mstore(scratchPtr, keccak256(0, TwoWords))
- mstore(xor(scratchPtr, OneWord), mload(proof))
- }
-
- // Compute root hash.
- root := keccak256(0, TwoWords)
- }
-
- // Retrieve appropriate typehash constant based on height.
- bytes32 rootTypeHash = _lookupBulkOrderTypehash(height);
-
- // Use the typehash and the root hash to derive final bulk order hash.
- assembly {
- mstore(0, rootTypeHash)
- mstore(OneWord, root)
- bulkOrderHash := keccak256(0, TwoWords)
- }
- }
-
- /**
- * @dev Internal view function to validate that a given order is fillable
- * and not cancelled based on the order status.
- *
- * @param orderHash The order hash.
- * @param orderStatus The status of the order, including whether it has
- * been cancelled and the fraction filled.
- * @param onlyAllowUnused A boolean flag indicating whether partial fills
- * are supported by the calling function.
- * @param revertOnInvalid A boolean indicating whether to revert if the
- * order has been cancelled or filled beyond the
- * allowable amount.
- *
- * @return valid A boolean indicating whether the order is valid.
- */
- function _verifyOrderStatus(
- bytes32 orderHash,
- OrderStatus storage orderStatus,
- bool onlyAllowUnused,
- bool revertOnInvalid
- ) internal view returns (bool valid) {
- // Ensure that the order has not been cancelled.
- if (orderStatus.isCancelled) {
- // Only revert if revertOnInvalid has been supplied as true.
- if (revertOnInvalid) {
- _revertOrderIsCancelled(orderHash);
- }
-
- // Return false as the order status is invalid.
- return false;
- }
-
- // Read order status numerator from storage and place on stack.
- uint256 orderStatusNumerator = orderStatus.numerator;
-
- // If the order is not entirely unused...
- if (orderStatusNumerator != 0) {
- // ensure the order has not been partially filled when not allowed.
- if (onlyAllowUnused) {
- // Always revert on partial fills when onlyAllowUnused is true.
- _revertOrderPartiallyFilled(orderHash);
- }
- // Otherwise, ensure that order has not been entirely filled.
- else if (orderStatusNumerator >= orderStatus.denominator) {
- // Only revert if revertOnInvalid has been supplied as true.
- if (revertOnInvalid) {
- _revertOrderAlreadyFilled(orderHash);
- }
-
- // Return false as the order status is invalid.
- return false;
- }
- }
-
- // Return true as the order status is valid.
- valid = true;
- }
-}
diff --git a/contracts/lib/ZoneInteraction.sol b/contracts/lib/ZoneInteraction.sol
deleted file mode 100644
index 26868af40..000000000
--- a/contracts/lib/ZoneInteraction.sol
+++ /dev/null
@@ -1,261 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
-
-import { OrderType } from "./ConsiderationEnums.sol";
-
-import {
- AdvancedOrder,
- BasicOrderParameters,
- OrderParameters
-} from "./ConsiderationStructs.sol";
-
-import { ZoneInteractionErrors } from "../interfaces/ZoneInteractionErrors.sol";
-
-import { LowLevelHelpers } from "./LowLevelHelpers.sol";
-
-import { ConsiderationEncoder } from "./ConsiderationEncoder.sol";
-
-import { MemoryPointer } from "../helpers/PointerLibraries.sol";
-
-import {
- ContractOrder_orderHash_offerer_shift,
- MaskOverFirstFourBytes,
- OneWord,
- OrderParameters_zone_offset
-} from "./ConsiderationConstants.sol";
-
-import {
- Error_selector_offset,
- InvalidContractOrder_error_selector,
- InvalidRestrictedOrder_error_length,
- InvalidRestrictedOrder_error_orderHash_ptr,
- InvalidRestrictedOrder_error_selector
-} from "./ConsiderationErrorConstants.sol";
-
-/**
- * @title ZoneInteraction
- * @author 0age
- * @notice ZoneInteraction contains logic related to interacting with zones.
- */
-contract ZoneInteraction is
- ConsiderationEncoder,
- ZoneInteractionErrors,
- LowLevelHelpers
-{
- /**
- * @dev Internal function to determine if an order has a restricted order
- * type and, if so, to ensure that either the zone is the caller or
- * that a call to `validateOrder` on the zone returns a magic value
- * indicating that the order is currently valid. Note that contract
- * orders are not accessible via the basic fulfillment method.
- *
- * @param orderHash The hash of the order.
- * @param orderType The order type.
- * @param parameters The parameters of the basic order.
- */
- function _assertRestrictedBasicOrderValidity(
- bytes32 orderHash,
- OrderType orderType,
- BasicOrderParameters calldata parameters
- ) internal {
- // Order type 2-3 require zone be caller or zone to approve.
- // Note that in cases where fulfiller == zone, the restricted order
- // validation will be skipped.
- if (_isRestrictedAndCallerNotZone(orderType, parameters.zone)) {
- // Encode the `validateOrder` call in memory.
- (MemoryPointer callData, uint256 size) = _encodeValidateBasicOrder(
- orderHash,
- parameters
- );
-
- // Perform `validateOrder` call and ensure magic value was returned.
- _callAndCheckStatus(
- parameters.zone,
- orderHash,
- callData,
- size,
- InvalidRestrictedOrder_error_selector
- );
- }
- }
-
- /**
- * @dev Internal function to determine the post-execution validity of
- * restricted and contract orders. Restricted orders where the caller
- * is not the zone must successfully call `validateOrder` with the
- * correct magic value returned. Contract orders must successfully call
- * `ratifyOrder` with the correct magic value returned.
- *
- * @param advancedOrder The advanced order in question.
- * @param orderHashes The order hashes of each order included as part of
- * the current fulfillment.
- * @param orderHash The hash of the order.
- */
- function _assertRestrictedAdvancedOrderValidity(
- AdvancedOrder memory advancedOrder,
- bytes32[] memory orderHashes,
- bytes32 orderHash
- ) internal {
- // Declare variables that will be assigned based on the order type.
- address target;
- uint256 errorSelector;
- MemoryPointer callData;
- uint256 size;
-
- // Retrieve the parameters of the order in question.
- OrderParameters memory parameters = advancedOrder.parameters;
-
- // OrderType 2-3 require zone to be caller or approve via validateOrder.
- if (
- _isRestrictedAndCallerNotZone(parameters.orderType, parameters.zone)
- ) {
- // Encode the `validateOrder` call in memory.
- (callData, size) = _encodeValidateOrder(
- orderHash,
- parameters,
- advancedOrder.extraData,
- orderHashes
- );
-
- // Set the target to the zone.
- target = (
- parameters
- .toMemoryPointer()
- .offset(OrderParameters_zone_offset)
- .readAddress()
- );
-
- // Set the restricted-order-specific error selector.
- errorSelector = InvalidRestrictedOrder_error_selector;
- } else if (parameters.orderType == OrderType.CONTRACT) {
- // Set the target to the offerer (note the offerer has no offset).
- target = parameters.toMemoryPointer().readAddress();
-
- // Shift the target 96 bits to the left.
- uint256 shiftedOfferer;
- assembly {
- shiftedOfferer := shl(
- ContractOrder_orderHash_offerer_shift,
- target
- )
- }
-
- // Encode the `ratifyOrder` call in memory.
- (callData, size) = _encodeRatifyOrder(
- orderHash,
- parameters,
- advancedOrder.extraData,
- orderHashes,
- shiftedOfferer
- );
-
- // Set the contract-order-specific error selector.
- errorSelector = InvalidContractOrder_error_selector;
- } else {
- return;
- }
-
- // Perform call and ensure a corresponding magic value was returned.
- _callAndCheckStatus(target, orderHash, callData, size, errorSelector);
- }
-
- /**
- * @dev Determines whether the specified order type is restricted and the
- * caller is not the specified zone.
- *
- * @param orderType The type of the order to check.
- * @param zone The address of the zone to check against.
- *
- * @return mustValidate True if the order type is restricted and the caller
- * is not the specified zone, false otherwise.
- */
- function _isRestrictedAndCallerNotZone(
- OrderType orderType,
- address zone
- ) internal view returns (bool mustValidate) {
- assembly {
- mustValidate := and(
- // Note that this check requires that there are no order types
- // beyond the current set (0-4). It will need to be modified if
- // more order types are added.
- and(lt(orderType, 4), gt(orderType, 1)),
- iszero(eq(caller(), zone))
- )
- }
- }
-
- /**
- * @dev Calls the specified target with the given data and checks the status
- * of the call. Revert reasons will be "bubbled up" if one is returned,
- * otherwise reverting calls will throw a generic error based on the
- * supplied error handler.
- *
- * @param target The address of the contract to call.
- * @param orderHash The hash of the order associated with the call.
- * @param callData The data to pass to the contract call.
- * @param size The size of calldata.
- * @param errorSelector The error handling function to call if the call
- * fails or the magic value does not match.
- */
- function _callAndCheckStatus(
- address target,
- bytes32 orderHash,
- MemoryPointer callData,
- uint256 size,
- uint256 errorSelector
- ) internal {
- bool success;
- bool magicMatch;
- assembly {
- // Get magic value from the selector at start of provided calldata.
- let magic := and(mload(callData), MaskOverFirstFourBytes)
-
- // Clear the start of scratch space.
- mstore(0, 0)
-
- // Perform call, placing result in the first word of scratch space.
- success := call(gas(), target, 0, callData, size, 0, OneWord)
-
- // Determine if returned magic value matches the calldata selector.
- magicMatch := eq(magic, mload(0))
- }
-
- // Revert if the call was not successful.
- if (!success) {
- // Revert and pass reason along if one was returned.
- _revertWithReasonIfOneIsReturned();
-
- // If no reason was returned, revert with supplied error selector.
- assembly {
- mstore(0, errorSelector)
- mstore(InvalidRestrictedOrder_error_orderHash_ptr, orderHash)
- // revert(abi.encodeWithSelector(
- // "InvalidRestrictedOrder(bytes32)",
- // orderHash
- // ))
- revert(
- Error_selector_offset,
- InvalidRestrictedOrder_error_length
- )
- }
- }
-
- // Revert if the correct magic value was not returned.
- if (!magicMatch) {
- // Revert with a generic error message.
- assembly {
- mstore(0, errorSelector)
- mstore(InvalidRestrictedOrder_error_orderHash_ptr, orderHash)
-
- // revert(abi.encodeWithSelector(
- // "InvalidRestrictedOrder(bytes32)",
- // orderHash
- // ))
- revert(
- Error_selector_offset,
- InvalidRestrictedOrder_error_length
- )
- }
- }
- }
-}
diff --git a/contracts/test/ConduitControllerMock.sol b/contracts/test/ConduitControllerMock.sol
index a14d164cd..bd7f8d4d5 100644
--- a/contracts/test/ConduitControllerMock.sol
+++ b/contracts/test/ConduitControllerMock.sol
@@ -3,9 +3,11 @@ pragma solidity ^0.8.13;
import {
ConduitControllerInterface
-} from "../interfaces/ConduitControllerInterface.sol";
+} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
+import {
+ ConduitInterface
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
import { ConduitMock } from "../test/ConduitMock.sol";
diff --git a/contracts/test/ConduitMock.sol b/contracts/test/ConduitMock.sol
index aad1342e1..dbba50899 100644
--- a/contracts/test/ConduitMock.sol
+++ b/contracts/test/ConduitMock.sol
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
+import {
+ ConduitInterface
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
import {
ConduitBatch1155Transfer,
ConduitTransfer
-} from "../conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
contract ConduitMock is ConduitInterface {
constructor() {}
diff --git a/contracts/test/ConduitMockInvalidMagic.sol b/contracts/test/ConduitMockInvalidMagic.sol
index 0a822677c..2dd94cf35 100644
--- a/contracts/test/ConduitMockInvalidMagic.sol
+++ b/contracts/test/ConduitMockInvalidMagic.sol
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
+import {
+ ConduitInterface
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
import {
ConduitBatch1155Transfer,
ConduitTransfer
-} from "../conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
contract ConduitMockInvalidMagic is ConduitInterface {
constructor() {}
diff --git a/contracts/test/ConduitMockRevertBytes.sol b/contracts/test/ConduitMockRevertBytes.sol
index 38e97dfa9..045b62ce8 100644
--- a/contracts/test/ConduitMockRevertBytes.sol
+++ b/contracts/test/ConduitMockRevertBytes.sol
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
+import {
+ ConduitInterface
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
import {
ConduitBatch1155Transfer,
ConduitTransfer
-} from "../conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
contract ConduitMockRevertBytes is ConduitInterface {
constructor() {}
diff --git a/contracts/test/ConduitMockRevertNoReason.sol b/contracts/test/ConduitMockRevertNoReason.sol
index c11155e19..492facfd1 100644
--- a/contracts/test/ConduitMockRevertNoReason.sol
+++ b/contracts/test/ConduitMockRevertNoReason.sol
@@ -1,12 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ConduitInterface } from "../interfaces/ConduitInterface.sol";
+import {
+ ConduitInterface
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
import {
ConduitBatch1155Transfer,
ConduitTransfer
-} from "../conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
contract ConduitMockRevertNoReason is ConduitInterface {
constructor() {}
diff --git a/contracts/test/ERC2981.sol b/contracts/test/ERC2981.sol
index dc05853f7..ca163d97a 100644
--- a/contracts/test/ERC2981.sol
+++ b/contracts/test/ERC2981.sol
@@ -3,8 +3,8 @@
pragma solidity ^0.8.0;
-import "../interfaces/IERC2981.sol";
-import "../interfaces/ERC165.sol";
+import "@openzeppelin/contracts/interfaces/IERC2981.sol";
+import "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
diff --git a/contracts/test/ERC721ReceiverMock.sol b/contracts/test/ERC721ReceiverMock.sol
index b6c409e9c..bb5506cc7 100644
--- a/contracts/test/ERC721ReceiverMock.sol
+++ b/contracts/test/ERC721ReceiverMock.sol
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { IERC721Receiver } from "../interfaces/IERC721Receiver.sol";
+import {
+ IERC721Receiver
+} from "seaport-types/src/interfaces/IERC721Receiver.sol";
contract ERC721ReceiverMock is IERC721Receiver {
enum Error {
diff --git a/contracts/test/HashCalldataContractOfferer.sol b/contracts/test/HashCalldataContractOfferer.sol
index f6b452ec5..4bd4fafba 100644
--- a/contracts/test/HashCalldataContractOfferer.sol
+++ b/contracts/test/HashCalldataContractOfferer.sol
@@ -5,26 +5,26 @@ import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
Schema,
SpentItem,
ZoneParameters
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType, Side } from "../lib/ConsiderationEnums.sol";
+import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
import { OffererZoneFailureReason } from "./OffererZoneFailureReason.sol";
contract HashCalldataContractOfferer is ContractOffererInterface {
diff --git a/contracts/test/HashValidationZoneOfferer.sol b/contracts/test/HashValidationZoneOfferer.sol
index 7c250ecfc..56a2315e1 100644
--- a/contracts/test/HashValidationZoneOfferer.sol
+++ b/contracts/test/HashValidationZoneOfferer.sol
@@ -5,22 +5,23 @@ import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ReceivedItem,
Schema,
SpentItem,
ZoneParameters
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType, Side } from "../lib/ConsiderationEnums.sol";
+import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
+
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
-import { ZoneInterface } from "../interfaces/ZoneInterface.sol";
import { OffererZoneFailureReason } from "./OffererZoneFailureReason.sol";
/**
@@ -57,8 +58,11 @@ contract HashValidationZoneOfferer is ContractOffererInterface, ZoneInterface {
uint256 expectedBalance,
uint256 actualBalance
);
+ error HashValidationZoneOffererAuthorizeOrderReverts();
error HashValidationZoneOffererValidateOrderReverts();
error HashValidationZoneOffererRatifyOrderReverts();
+
+ event AuthorizeOrderDataHash(bytes32 dataHash);
event ValidateOrderDataHash(bytes32 dataHash);
struct ItemAmountMutation {
@@ -203,6 +207,7 @@ contract HashValidationZoneOfferer is ContractOffererInterface, ZoneInterface {
address internal _expectedOfferRecipient;
+ mapping(bytes32 => bytes32) public orderHashToAuthorizeOrderDataHash;
mapping(bytes32 => bytes32) public orderHashToValidateOrderDataHash;
// Pass in the null address to expect the fulfiller.
@@ -211,15 +216,72 @@ contract HashValidationZoneOfferer is ContractOffererInterface, ZoneInterface {
}
bool public called = false;
- uint public callCount = 0;
+ uint256 public callCount = 0;
- mapping(bytes32 => OffererZoneFailureReason) public failureReasons;
+ mapping(bytes32 => OffererZoneFailureReason) public authorizeFailureReasons;
+ mapping(bytes32 => OffererZoneFailureReason) public validateFailureReasons;
- function setFailureReason(
+ function setAuthorizeFailureReason(
bytes32 orderHash,
OffererZoneFailureReason newFailureReason
) external {
- failureReasons[orderHash] = newFailureReason;
+ authorizeFailureReasons[orderHash] = newFailureReason;
+ }
+
+ function setValidateFailureReason(
+ bytes32 orderHash,
+ OffererZoneFailureReason newFailureReason
+ ) external {
+ validateFailureReasons[orderHash] = newFailureReason;
+ }
+
+ function authorizeOrder(
+ ZoneParameters calldata zoneParameters
+ ) public returns (bytes4 authorizeOrderReturnValue) {
+ // Get the orderHash from zoneParameters
+ bytes32 orderHash = zoneParameters.orderHash;
+
+ if (
+ authorizeFailureReasons[orderHash] ==
+ OffererZoneFailureReason.Zone_authorizeRevertsMatchReverts
+ ) {
+ revert HashValidationZoneOffererAuthorizeOrderReverts();
+ }
+
+ // Get the length of msg.data
+ uint256 dataLength = msg.data.length;
+
+ // Create a variable to store msg.data in memory
+ bytes memory data;
+
+ // Copy msg.data to memory
+ assembly {
+ let ptr := mload(0x40)
+ calldatacopy(add(ptr, 0x20), 0, dataLength)
+ mstore(ptr, dataLength)
+ data := ptr
+ }
+
+ // Get the hash of msg.data
+ bytes32 calldataHash = keccak256(data);
+
+ // Store callDataHash in orderHashToAuthorizeOrderDataHash
+ orderHashToAuthorizeOrderDataHash[orderHash] = calldataHash;
+
+ // Emit a DataHash event with the hash of msg.data
+ emit AuthorizeOrderDataHash(calldataHash);
+
+ if (
+ authorizeFailureReasons[orderHash] ==
+ OffererZoneFailureReason.Zone_authorizeInvalidMagicValue
+ ) {
+ authorizeOrderReturnValue = bytes4(0x12345678);
+ } else {
+ // Return the selector of authorizeOrder as the magic value.
+ authorizeOrderReturnValue = this.authorizeOrder.selector;
+ }
+
+ return authorizeOrderReturnValue;
}
/**
@@ -237,7 +299,8 @@ contract HashValidationZoneOfferer is ContractOffererInterface, ZoneInterface {
bytes32 orderHash = zoneParameters.orderHash;
if (
- failureReasons[orderHash] == OffererZoneFailureReason.Zone_reverts
+ validateFailureReasons[orderHash] ==
+ OffererZoneFailureReason.Zone_validateReverts
) {
revert HashValidationZoneOffererValidateOrderReverts();
}
@@ -283,8 +346,8 @@ contract HashValidationZoneOfferer is ContractOffererInterface, ZoneInterface {
callCount++;
if (
- failureReasons[orderHash] ==
- OffererZoneFailureReason.Zone_InvalidMagicValue
+ validateFailureReasons[orderHash] ==
+ OffererZoneFailureReason.Zone_validateInvalidMagicValue
) {
validOrderMagicValue = bytes4(0x12345678);
} else {
diff --git a/contracts/test/OffererZoneFailureReason.sol b/contracts/test/OffererZoneFailureReason.sol
index c4ce07d7c..41c325224 100644
--- a/contracts/test/OffererZoneFailureReason.sol
+++ b/contracts/test/OffererZoneFailureReason.sol
@@ -11,6 +11,8 @@ enum OffererZoneFailureReason {
ContractOfferer_ExcessMaximumSpent, // too many maximum spent items
ContractOfferer_IncorrectMaximumSpent, // incorrect (too many, wrong token, etc.) maximum spent items
ContractOfferer_InvalidMagicValue, // Offerer did not return correct magic value
- Zone_reverts, // Zone validateOrder call reverts
- Zone_InvalidMagicValue // Zone validateOrder call returns invalid magic value
+ Zone_authorizeRevertsMatchReverts, // Zone authorizeOrder call reverts, which triggers a top level revert only on match*
+ Zone_validateReverts, // Zone validateOrder call reverts
+ Zone_authorizeInvalidMagicValue, // Zone authorizeOrder call returns invalid magic value
+ Zone_validateInvalidMagicValue // Zone validateOrder call returns invalid magic value
}
diff --git a/contracts/test/TestBadContractOfferer.sol b/contracts/test/TestBadContractOfferer.sol
index 07c7bf1fd..4ae232284 100644
--- a/contracts/test/TestBadContractOfferer.sol
+++ b/contracts/test/TestBadContractOfferer.sol
@@ -1,19 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ERC721Interface } from "../interfaces/AbridgedTokenInterfaces.sol";
+import {
+ ERC721Interface
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
Schema,
SpentItem
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract TestBadContractOfferer is ContractOffererInterface {
error IntentionalRevert();
diff --git a/contracts/test/TestCalldataHashContractOfferer.sol b/contracts/test/TestCalldataHashContractOfferer.sol
index 679da7396..54a5fa1a6 100644
--- a/contracts/test/TestCalldataHashContractOfferer.sol
+++ b/contracts/test/TestCalldataHashContractOfferer.sol
@@ -5,24 +5,24 @@ import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ReceivedItem,
Schema,
SpentItem,
ZoneParameters
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
contract TestCalldataHashContractOfferer is ContractOffererInterface {
error InvalidNativeTokenBalance(
diff --git a/contracts/test/TestContractOfferer.sol b/contracts/test/TestContractOfferer.sol
index a3f135a0a..0fb9f73c6 100644
--- a/contracts/test/TestContractOfferer.sol
+++ b/contracts/test/TestContractOfferer.sol
@@ -5,21 +5,20 @@ import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../interfaces/ERC165.sol";
-
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
Schema,
SpentItem
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
/**
* @title TestContractOfferer
diff --git a/contracts/test/TestContractOffererNativeToken.sol b/contracts/test/TestContractOffererNativeToken.sol
index 760eac52b..ff31946d9 100644
--- a/contracts/test/TestContractOffererNativeToken.sol
+++ b/contracts/test/TestContractOffererNativeToken.sol
@@ -4,21 +4,20 @@ pragma solidity ^0.8.13;
import {
ERC721Interface,
ERC1155Interface
-} from "../interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../interfaces/ERC165.sol";
-
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
Schema,
SpentItem
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
/**
* @title TestContractOffererNativeToken
diff --git a/contracts/test/TestERC1271.sol b/contracts/test/TestERC1271.sol
index ed510e441..19f30505f 100644
--- a/contracts/test/TestERC1271.sol
+++ b/contracts/test/TestERC1271.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;
-import { IERC1271 } from "../interfaces/IERC1271.sol";
+import { IERC1271 } from "@openzeppelin/contracts/interfaces/IERC1271.sol";
contract TestERC1271 is IERC1271 {
address public immutable owner;
diff --git a/contracts/test/TestInvalidContractOfferer.sol b/contracts/test/TestInvalidContractOfferer.sol
index 627849945..d704ae686 100644
--- a/contracts/test/TestInvalidContractOfferer.sol
+++ b/contracts/test/TestInvalidContractOfferer.sol
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ReceivedItem, SpentItem } from "../lib/ConsiderationStructs.sol";
+import {
+ ReceivedItem,
+ SpentItem
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { TestContractOfferer } from "./TestContractOfferer.sol";
diff --git a/contracts/test/TestInvalidContractOfferer165.sol b/contracts/test/TestInvalidContractOfferer165.sol
index 2661ae0f2..0575dd474 100644
--- a/contracts/test/TestInvalidContractOfferer165.sol
+++ b/contracts/test/TestInvalidContractOfferer165.sol
@@ -5,21 +5,20 @@ import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../interfaces/ERC165.sol";
-
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
Schema,
SpentItem
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract TestInvalidContractOfferer165 {
error OrderUnavailable();
diff --git a/contracts/test/TestInvalidContractOffererRatifyOrder.sol b/contracts/test/TestInvalidContractOffererRatifyOrder.sol
index c9a81c84e..0c578c640 100644
--- a/contracts/test/TestInvalidContractOffererRatifyOrder.sol
+++ b/contracts/test/TestInvalidContractOffererRatifyOrder.sol
@@ -1,7 +1,10 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ReceivedItem, SpentItem } from "../lib/ConsiderationStructs.sol";
+import {
+ ReceivedItem,
+ SpentItem
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { TestContractOfferer } from "./TestContractOfferer.sol";
diff --git a/contracts/test/TestInvalidZone.sol b/contracts/test/TestInvalidZone.sol
index 50c54cd85..41a32bc6f 100644
--- a/contracts/test/TestInvalidZone.sol
+++ b/contracts/test/TestInvalidZone.sol
@@ -1,13 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { ZoneParameters, Schema } from "../lib/ConsiderationStructs.sol";
+import {
+ ZoneParameters,
+ Schema
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ERC165 } from "../interfaces/ERC165.sol";
-
-import { ZoneInterface } from "../interfaces/ZoneInterface.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
contract TestInvalidZone is ERC165, ZoneInterface {
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) public pure returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
+
// Returns invalid magic value
function validateOrder(
ZoneParameters calldata
diff --git a/contracts/test/TestPostExecution.sol b/contracts/test/TestPostExecution.sol
index f5669b84a..54ffb6b54 100644
--- a/contracts/test/TestPostExecution.sol
+++ b/contracts/test/TestPostExecution.sol
@@ -1,21 +1,28 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ZoneInterface } from "../interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
-import { ERC165 } from "../interfaces/ERC165.sol";
-
-import { ERC721Interface } from "../interfaces/AbridgedTokenInterfaces.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+import {
+ ERC721Interface
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
Schema,
ZoneParameters
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract TestPostExecution is ERC165, ZoneInterface {
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) public pure returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
+
function validateOrder(
ZoneParameters calldata zoneParameters
) external view override returns (bytes4 validOrderMagicValue) {
diff --git a/contracts/test/TestTransferValidationZoneOfferer.sol b/contracts/test/TestTransferValidationZoneOfferer.sol
index 9427c5c19..fefb49ddd 100644
--- a/contracts/test/TestTransferValidationZoneOfferer.sol
+++ b/contracts/test/TestTransferValidationZoneOfferer.sol
@@ -5,24 +5,23 @@ import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../interfaces/AbridgedTokenInterfaces.sol";
-
-import { ERC165 } from "../interfaces/ERC165.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {
ReceivedItem,
Schema,
SpentItem,
ZoneParameters
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType } from "../lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ContractOffererInterface
-} from "../interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ZoneInterface } from "../interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
/**
* @dev This contract is used to validate transfer within the zone/offerer. Use
@@ -61,6 +60,7 @@ contract TestTransferValidationZoneOfferer is
uint256 expectedBalance,
uint256 actualBalance
);
+
event ValidateOrderDataHash(bytes32 dataHash);
receive() external payable {}
@@ -75,7 +75,13 @@ contract TestTransferValidationZoneOfferer is
}
bool public called = false;
- uint public callCount = 0;
+ uint256 public callCount = 0;
+
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) public pure returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
/**
* @dev Validates that the parties have received the correct items.
diff --git a/contracts/test/TestZone.sol b/contracts/test/TestZone.sol
index 27db79584..1f87ee687 100644
--- a/contracts/test/TestZone.sol
+++ b/contracts/test/TestZone.sol
@@ -1,13 +1,20 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ZoneInterface } from "../interfaces/ZoneInterface.sol";
-
-import { ERC165 } from "../interfaces/ERC165.sol";
-
-import { Schema, ZoneParameters } from "../lib/ConsiderationStructs.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+import {
+ Schema,
+ ZoneParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract TestZone is ERC165, ZoneInterface {
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) public pure returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
+
function validateOrder(
ZoneParameters calldata zoneParameters
) external pure override returns (bytes4 validOrderMagicValue) {
diff --git a/contracts/test/TypehashDirectory.sol b/contracts/test/TypehashDirectory.sol
index c37eac131..80678a759 100644
--- a/contracts/test/TypehashDirectory.sol
+++ b/contracts/test/TypehashDirectory.sol
@@ -1,12 +1,12 @@
// SPDX-License-Identifier: MIT
-pragma solidity 0.8.17;
+pragma solidity ^0.8.17;
import {
FreeMemoryPointerSlot,
OneWord,
OneWordShift,
ThirtyOneBytes
-} from "../lib/ConsiderationConstants.sol";
+} from "seaport-types/src/lib/ConsiderationConstants.sol";
/**
* @title TypehashDirectory
diff --git a/contracts/zones/PausableZone.sol b/contracts/zones/PausableZone.sol
index c6dd084b7..e0a2da5eb 100644
--- a/contracts/zones/PausableZone.sol
+++ b/contracts/zones/PausableZone.sol
@@ -1,15 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ZoneInterface } from "../interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
import {
PausableZoneEventsAndErrors
} from "./interfaces/PausableZoneEventsAndErrors.sol";
-import { ERC165 } from "../interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import { SeaportInterface } from "../interfaces/SeaportInterface.sol";
+import {
+ SeaportInterface
+} from "seaport-types/src/interfaces/SeaportInterface.sol";
import {
AdvancedOrder,
@@ -20,7 +22,7 @@ import {
OrderComponents,
Schema,
ZoneParameters
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { PausableZoneInterface } from "./interfaces/PausableZoneInterface.sol";
@@ -28,9 +30,9 @@ import { PausableZoneInterface } from "./interfaces/PausableZoneInterface.sol";
* @title PausableZone
* @author cupOJoseph, BCLeFevre, ryanio
* @notice PausableZone is a simple zone implementation that approves every
- * order. It can be self-destructed by its controller to pause
- * restricted orders that have it set as their zone. Note that this zone
- * cannot execute orders that return native tokens to the fulfiller.
+ * order. It can be paused by its controller to pause restricted orders
+ * that have it set as their zone. Note that this zone cannot execute
+ * orders that return native tokens to the fulfiller.
*/
contract PausableZone is
ERC165,
@@ -44,6 +46,9 @@ contract PausableZone is
// Set an operator that can instruct the zone to cancel or execute orders.
address public operator;
+ // Set a boolean indicating whether the zone is paused.
+ bool public isPaused;
+
/**
* @dev Ensure that the caller is either the operator or controller.
*/
@@ -57,6 +62,19 @@ contract PausableZone is
_;
}
+ /**
+ * @dev Ensure that the zone is not paused.
+ */
+ modifier isNotPaused() {
+ // Ensure that the zone is not paused.
+ if (isPaused) {
+ revert ZoneIsPaused();
+ }
+
+ // Continue with function execution.
+ _;
+ }
+
/**
* @dev Ensure that the caller is the controller.
*/
@@ -102,16 +120,14 @@ contract PausableZone is
/**
* @notice Pause this contract, safely stopping orders from using
* the contract as a zone. Restricted orders with this address as a
- * zone will not be fulfillable unless the zone is redeployed to the
- * same address.
+ * zone will no longer be fulfillable.
*/
- function pause(address payee) external override isController {
+ function pause() external override isController {
// Emit an event signifying that the zone is paused.
emit Paused();
- // Destroy the zone, sending any native tokens to the transaction
- // submitter.
- selfdestruct(payable(payee));
+ // Pause the zone.
+ isPaused = true;
}
/**
@@ -159,6 +175,7 @@ contract PausableZone is
payable
override
isOperator
+ isNotPaused
returns (Execution[] memory executions)
{
// Call matchOrders on Seaport and return the sequence of transfers
@@ -200,6 +217,7 @@ contract PausableZone is
payable
override
isOperator
+ isNotPaused
returns (Execution[] memory executions)
{
// Call matchAdvancedOrders on Seaport and return the sequence of
@@ -212,6 +230,12 @@ contract PausableZone is
);
}
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) external view isNotPaused returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
+
/**
* @notice Check if a given order including extraData is currently valid.
*
@@ -232,7 +256,7 @@ contract PausableZone is
* @custom:name zoneParameters
*/
ZoneParameters calldata
- ) external pure override returns (bytes4 validOrderMagicValue) {
+ ) external view override isNotPaused returns (bytes4 validOrderMagicValue) {
// Return the selector of isValidOrder as the magic value.
validOrderMagicValue = ZoneInterface.validateOrder.selector;
}
diff --git a/contracts/zones/PausableZoneController.sol b/contracts/zones/PausableZoneController.sol
index 1e731ca95..c55249512 100644
--- a/contracts/zones/PausableZoneController.sol
+++ b/contracts/zones/PausableZoneController.sol
@@ -18,9 +18,11 @@ import {
Fulfillment,
Order,
OrderComponents
-} from "../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { SeaportInterface } from "../interfaces/SeaportInterface.sol";
+import {
+ SeaportInterface
+} from "seaport-types/src/interfaces/SeaportInterface.sol";
/**
* @title PausableZoneController
@@ -101,7 +103,7 @@ contract PausableZoneController is
)
);
- // Revert if a zone is currently deployed to the derived address.
+ // Revert if a zone is already deployed to the derived address.
if (derivedAddress.code.length != 0) {
revert ZoneAlreadyExists(derivedAddress);
}
@@ -124,7 +126,7 @@ contract PausableZoneController is
address zone
) external override isPauser returns (bool success) {
// Call pause on the given zone.
- PausableZone(zone).pause(msg.sender);
+ PausableZone(zone).pause();
// Return a boolean indicating the pause was successful.
success = true;
diff --git a/contracts/zones/interfaces/PausableZoneControllerInterface.sol b/contracts/zones/interfaces/PausableZoneControllerInterface.sol
index fb661b395..ab48d9225 100644
--- a/contracts/zones/interfaces/PausableZoneControllerInterface.sol
+++ b/contracts/zones/interfaces/PausableZoneControllerInterface.sol
@@ -8,9 +8,11 @@ import {
Fulfillment,
Order,
OrderComponents
-} from "../../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { SeaportInterface } from "../../interfaces/SeaportInterface.sol";
+import {
+ SeaportInterface
+} from "seaport-types/src/interfaces/SeaportInterface.sol";
/**
* @title PausableZoneController
diff --git a/contracts/zones/interfaces/PausableZoneEventsAndErrors.sol b/contracts/zones/interfaces/PausableZoneEventsAndErrors.sol
index bb80f9402..d31185e98 100644
--- a/contracts/zones/interfaces/PausableZoneEventsAndErrors.sol
+++ b/contracts/zones/interfaces/PausableZoneEventsAndErrors.sol
@@ -108,4 +108,9 @@ interface PausableZoneEventsAndErrors {
* the potentialOwner role.
*/
error CallerIsNotPotentialOwner();
+
+ /**
+ * @dev Revert with an error when the zone is paused
+ */
+ error ZoneIsPaused();
}
diff --git a/contracts/zones/interfaces/PausableZoneInterface.sol b/contracts/zones/interfaces/PausableZoneInterface.sol
index 42b5dfc0e..bfb553731 100644
--- a/contracts/zones/interfaces/PausableZoneInterface.sol
+++ b/contracts/zones/interfaces/PausableZoneInterface.sol
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { SeaportInterface } from "../../interfaces/SeaportInterface.sol";
+import {
+ SeaportInterface
+} from "seaport-types/src/interfaces/SeaportInterface.sol";
import {
AdvancedOrder,
@@ -10,7 +12,7 @@ import {
Fulfillment,
Order,
OrderComponents
-} from "../../lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
/**
* @title PausableZone
@@ -86,10 +88,9 @@ interface PausableZoneInterface {
/**
* @notice Pause this contract, safely stopping orders from using
* the contract as a zone. Restricted orders with this address as a
- * zone will not be fulfillable unless the zone is redeployed to the
- * same address.
+ * zone will not be fulfillable unless the zone is unpaused.
*/
- function pause(address payee) external;
+ function pause() external;
/**
* @notice Assign the given address with the ability to operate the zone.
diff --git a/docs/AuditLink.md b/docs/AuditLink.md
new file mode 100644
index 000000000..6271cdbe8
--- /dev/null
+++ b/docs/AuditLink.md
@@ -0,0 +1,10 @@
+---
+title: Audit
+category: 6520398b749af50013f52ff4
+slug: seaport-audit
+parentDocSlug: seaport-overview
+order: 6
+hidden: false
+type: link
+link_url: https://github.com/ProjectOpenSea/seaport/tree/main#audits
+---
diff --git a/docs/Deployment.md b/docs/Deployment.md
index b2c6c68d9..ad0959dd4 100644
--- a/docs/Deployment.md
+++ b/docs/Deployment.md
@@ -1,3 +1,12 @@
+---
+title: Deployment
+category: 6520398b749af50013f52ff4
+slug: seaport-deployment
+parentDocSlug: seaport-overview
+order: 6
+hidden: false
+---
+
# Deploying Seaport
Seaport 1.5 and the ConduitController can each be deployed to their respective canonical deployment address on all EVM chains using the CREATE2 Factory. Note that a pre-155 transaction with a gas price of 100 gwei (or a manual workaround) is required as part of the deployment process (subsequent transactions can be submitted without these constraints), and that EVM equivalence (particularly consistent CREATE2 address derivation) is required in order to deploy to the canonical cross-chain deployment addresses.
@@ -81,7 +90,7 @@ cast send --rpc-url ${RPC_URL} --private-key ${PK} 0x0000000000ffe8b47b3e2130213
3. Validate deployments were successful by checking that `Seaport` is returned:
```
-cast --to-ascii $(cast call --rpc-url ${RPC_URL} 0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC 'name()')
+cast call --rpc-url ${RPC_URL} 0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC 'name()(string)'
```
## Verifying Seaport and ConduitController
@@ -92,7 +101,7 @@ After `Seaport` and `ConduitController` are deployed, they are verified as follo
```
git clone https://github.com/ProjectOpenSea/seaport && cd seaport
git checkout 821a049
-yarn build
+yarn install && yarn build
```
3. Verify `ConduitController` by calling:
@@ -121,4 +130,4 @@ yarn build
```
npx hardhat verify --network verificationNetwork "0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC" "0x00000000F9490004C11Cef243f5400493c00Ad63"
-```
\ No newline at end of file
+```
diff --git a/docs/FunctionSignatures.md b/docs/FunctionSignatures.md
index cc7e950c9..99789d382 100644
--- a/docs/FunctionSignatures.md
+++ b/docs/FunctionSignatures.md
@@ -1,3 +1,12 @@
+---
+title: Seaport Functions
+category: 6520398b749af50013f52ff4
+slug: seaport-functions
+parentDocSlug: seaport-overview
+order: 4
+hidden: false
+---
+
# Seaport Function Signatures
diff --git a/docs/OrderValidator.md b/docs/OrderValidator.md
index 5d29be2f4..fcd5a9a74 100644
--- a/docs/OrderValidator.md
+++ b/docs/OrderValidator.md
@@ -1,80 +1,113 @@
+---
+title: Order Validation
+category: 6520398b749af50013f52ff4
+slug: seaport-order-validator
+parentDocSlug: seaport-overview
+order: 3
+hidden: false
+---
+
# Seaport Order Validator
The SeaportValidator contract offers various validation methods to ensure that supplied Seaport orders are being constructed correctly. Most contract calls return an `ErrorsAndWarnings` struct with two `uint16` arrays to help developers debug issues with their orders.
See below for the full list of Errors and Warnings.
-The contract has been verified and deployed to [0x00000000be3af6882a06323fd3f400a9e6a0dc42](https://etherscan.io/address/0x00000000be3af6882a06323fd3f400a9e6a0dc42#code).
+The contract is deployed to the following addresses:
+
+
+
+Contract |
+Canonical Cross-chain Deployment Address |
+
+SeaportValidator |
+0x00e5F120f500006757E984F1DED400fc00370000 |
+
+
+SeaportValidator 1.1 (legacy) |
+0xF75194740067D6E4000000003b350688DD770000 |
+
+
+SeaportValidator 1.4 (legacy) |
+0x00000000BE3Af6882A06323fd3f400A9e6A0DC42 |
+
+SeaportValidator 1.5 (legacy) |
+0x000000000DD1F1B245b936b2771408555CF8B8af |
+
+
-Special thanks to [arr00](https://github.com/arr00), who deployed an earlier version of a SeaportValidator contract which can be found [here](https://etherscan.io/address/0xF75194740067D6E4000000003b350688DD770000#code).
+Special thanks to:
+- [arr00](https://github.com/arr00), who deployed an earlier version of a SeaportValidator contract which can be found [here](https://etherscan.io/address/0xF75194740067D6E4000000003b350688DD770000#code)
+- [stephankmin](https://github.com/stephankmin), who extended the SeaportValidator contract to support more errors/warnings and arbitary Seaport instances with compatible versions
+- [horsefacts](https://github.com/horsefacts), who implemented support for a ready-only version of the helper contract
## Errors and Warnings
-| Code | Issue |
-| - | ----------- |
-| 100 | Invalid order format. Ensure offer/consideration follow requirements |
-| 200 | ERC20 identifier must be zero |
-| 201 | ERC20 invalid token |
-| 202 | ERC20 insufficient allowance to conduit |
-| 203 | ERC20 insufficient balance |
-| 300 | ERC721 amount must be one |
-| 301 | ERC721 token is invalid |
-| 302 | ERC721 token with identifier does not exist |
-| 303 | ERC721 not owner of token |
-| 304 | ERC721 conduit not approved |
-| 305 | ERC721 offer item using criteria and more than amount of one requires partial fills |
-| 400 | ERC1155 invalid token |
-| 401 | ERC1155 conduit not approved |
-| 402 | ERC1155 insufficient balance |
-| 500 | Consideration amount must not be zero |
-| 501 | Consideration recipient must not be null address |
-| 502 | Consideration contains extra items |
-| 503 | Private sale cannot be to self |
-| 504 | Zero consideration items |
-| 505 | Duplicate consideration items |
-| 506 | Offerer is not receiving at least one item |
-| 507 | Private Sale Order. Be careful on fulfillment |
-| 508 | Amount velocity is too high. Amount changes over 5% per 30 min if warning and over 50% per 30 min if error |
-| 509 | Amount step large. The steps between each step may be more than expected. Offer items are rounded down and consideration items are rounded up. |
-| 600 | Zero offer items |
-| 601 | Offer amount must not be zero |
-| 602 | More than one offer item |
-| 603 | Native offer item |
-| 604 | Duplicate offer item |
-| 605 | Amount velocity is too high. Amount changes over 5% per 30 min if warning and over 50% per 30 min if error |
-| 606 | Amount step large. The steps between each step may be more than expected. Offer items are rounded down and consideration items are rounded up. |
-| 700 | Primary fee missing |
-| 701 | Primary fee item type incorrect |
-| 702 | Primary fee token incorrect |
-| 703 | Primary fee start amount too low |
-| 704 | Primary fee end amount too low |
-| 705 | Primary fee recipient incorrect |
-| 800 | Order cancelled |
-| 801 | Order fully filled |
-| 802 | Cannot validate status of contract order
-| 900 | End time is before start time |
-| 901 | Order expired |
-| 902 | Order expiration in too long (default 26 weeks) |
-| 903 | Order not active |
-| 904 | Short order duration (default 30 min) |
-| 1000 | Conduit key invalid |
-| 1001 | Conduit does not have canonical Seaport as an open channel |
-| 1100 | Signature invalid |
-| 1101 | Contract orders do not have signatures |
-| 1102 | Signature counter below current counter |
-| 1103 | Signature counter above current counter |
-| 1104 | Signature may be invalid since `totalOriginalConsiderationItems` is not set correctly |
-| 1200 | Creator fee missing |
-| 1201 | Creator fee item type incorrect |
-| 1202 | Creator fee token incorrect |
-| 1203 | Creator fee start amount too low |
-| 1204 | Creator fee end amount too low |
-| 1205 | Creator fee recipient incorrect |
-| 1300 | Native token address must be null address |
-| 1301 | Native token identifier must be zero |
-| 1302 | Native token insufficient balance |
-| 1400 | Zone is invalid |
-| 1401 | Zone rejected order. This order must be fulfilled by the zone. |
-| 1401 | Zone not set. Order unfulfillable |
-| 1500 | Merkle input only has one leaf |
-| 1501 | Merkle input not sorted correctly |
-| 1600 | Contract offerer is invalid |
\ No newline at end of file
+| Code | Issue | Type
+| - | ----------- | - |
+| 100 | Invalid order format. Ensure offer/consideration follow requirements | Error |
+| 200 | ERC20 identifier must be zero | Error |
+| 201 | ERC20 invalid token | Error |
+| 202 | ERC20 insufficient allowance to conduit | Error |
+| 203 | ERC20 insufficient balance | Error |
+| 300 | ERC721 amount must be one | Error |
+| 301 | ERC721 token is invalid | Error |
+| 302 | ERC721 token with identifier does not exist | Error |
+| 303 | ERC721 not owner of token | Error |
+| 304 | ERC721 conduit not approved | Error |
+| 305 | ERC721 offer item using criteria and more than amount of one requires partial fills | Error |
+| 400 | ERC1155 invalid token | Error |
+| 401 | ERC1155 conduit not approved | Error |
+| 402 | ERC1155 insufficient balance | Error |
+| 500 | Consideration amount must not be zero | Error |
+| 501 | Consideration recipient must not be null address | Error |
+| 502 | Consideration contains extra items | Error |
+| 503 | Private sale cannot be to self | Error |
+| 504 | Zero consideration items | Warning |
+| 505 | Duplicate consideration items | Warning |
+| 506 | Offerer is not receiving at least one item | Warning |
+| 507 | Private Sale Order. Be careful on fulfillment | Warning |
+| 508 | Amount velocity is too high. Amount changes over 5% per 30 min if warning and over 50% per 30 min if error | Both |
+| 509 | Amount step large. The steps between each step may be more than expected. Offer items are rounded down and consideration items are rounded up. | Warning |
+| 600 | Zero offer items | Warning |
+| 601 | Offer amount must not be zero | Error |
+| 602 | More than one offer item | Warning |
+| 603 | Native offer item | Warning |
+| 604 | Duplicate offer item | Error |
+| 605 | Amount velocity is too high. Amount changes over 5% per 30 min if warning and over 50% per 30 min if error | Both |
+| 606 | Amount step large. The steps between each step may be more than expected. Offer items are rounded down and consideration items are rounded up. | Warning |
+| 700 | Primary fee missing | Error |
+| 701 | Primary fee item type incorrect | Error |
+| 702 | Primary fee token incorrect | Error |
+| 703 | Primary fee start amount too low | Error |
+| 704 | Primary fee end amount too low | Error |
+| 705 | Primary fee recipient incorrect | Error |
+| 800 | Order cancelled | Error |
+| 801 | Order fully filled | Error |
+| 802 | Cannot validate status of contract order | Warning |
+| 900 | End time is before start time | Error |
+| 901 | Order expired | Error |
+| 902 | Order expiration in too long (default 26 weeks) | Warning |
+| 903 | Order not active | Warning |
+| 904 | Short order duration (default 30 min) | Warning |
+| 1000 | Conduit key invalid | Error |
+| 1001 | Conduit does not have canonical Seaport as an open channel | Error |
+| 1100 | Signature invalid | Error |
+| 1101 | Contract orders do not have signatures | Warning |
+| 1102 | Signature counter below current counter | Error |
+| 1103 | Signature counter above current counter | Error |
+| 1104 | Signature may be invalid since `totalOriginalConsiderationItems` is not set correctly | Warning |
+| 1200 | Creator fee missing | Error |
+| 1201 | Creator fee item type incorrect | Error |
+| 1202 | Creator fee token incorrect | Error |
+| 1203 | Creator fee start amount too low | Error |
+| 1204 | Creator fee end amount too low | Error |
+| 1205 | Creator fee recipient incorrect | Error |
+| 1300 | Native token address must be null address | Error |
+| 1301 | Native token identifier must be zero | Error |
+| 1302 | Native token insufficient balance | Error |
+| 1400 | Zone is invalid | Warning |
+| 1401 | Zone rejected order. This order must be fulfilled by the zone. | Warning |
+| 1402 | Zone not set. Order unfulfillable | Error |
+| 1500 | Merkle input only has one leaf | Error |
+| 1501 | Merkle input not sorted correctly | Error |
+| 1600 | Contract offerer is invalid | Warning |
diff --git a/docs/Overview.md b/docs/Overview.md
new file mode 100644
index 000000000..484489387
--- /dev/null
+++ b/docs/Overview.md
@@ -0,0 +1,9 @@
+---
+title: Seaport
+category: 6520398b749af50013f52ff4
+slug: seaport-overview
+order: 0
+hidden: false
+---
+
+Seaport is a marketplace protocol for safely and efficiently buying and selling NFTs. Each listing 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").
\ No newline at end of file
diff --git a/docs/SeaportDiagramLink.md b/docs/SeaportDiagramLink.md
new file mode 100644
index 000000000..ad06497b7
--- /dev/null
+++ b/docs/SeaportDiagramLink.md
@@ -0,0 +1,10 @@
+---
+title: Seaport Diagram
+category: 6520398b749af50013f52ff4
+slug: seaport-diagram
+parentDocSlug: seaport-overview
+order: 5
+hidden: false
+type: link
+link_url: https://github.com/ProjectOpenSea/seaport/blob/main/diagrams/README.md
+---
\ No newline at end of file
diff --git a/docs/SeaportDocumentation.md b/docs/SeaportDocumentation.md
index 7fa55acd4..f9ce6335b 100644
--- a/docs/SeaportDocumentation.md
+++ b/docs/SeaportDocumentation.md
@@ -1,3 +1,12 @@
+---
+title: Interacting with Seaport
+category: 6520398b749af50013f52ff4
+slug: seaport-interactions
+parentDocSlug: seaport-overview
+order: 1
+hidden: false
+---
+
# Seaport Documentation
Documentation around creating orders, fulfillment, and interacting with Seaport.
diff --git a/docs/ZoneDocumentation.md b/docs/ZoneDocumentation.md
index 21294191c..6d493c6b4 100644
--- a/docs/ZoneDocumentation.md
+++ b/docs/ZoneDocumentation.md
@@ -1,3 +1,12 @@
+---
+title: Seaport Zones
+category: 6520398b749af50013f52ff4
+slug: seaport-zones
+parentDocSlug: seaport-overview
+order: 2
+hidden: false
+---
+
# Zone Documentation
The `zone` of the order is an optional secondary account attached to the order with two additional privileges:
diff --git a/foundry.toml b/foundry.toml
index 06f511f1c..47cb902c1 100644
--- a/foundry.toml
+++ b/foundry.toml
@@ -1,5 +1,6 @@
[profile.default]
-solc = '0.8.17'
+solc = '0.8.24'
+evm_version='cancun'
src = 'contracts'
out = 'out'
libs = ["node_modules", "lib"]
@@ -9,11 +10,13 @@ remappings = [
'ds-test/=lib/ds-test/src/',
'forge-std/=lib/forge-std/src/',
'murky/=lib/murky/src/',
- 'openzeppelin-contracts/=lib/openzeppelin-contracts/',
- 'seaport-sol/=contracts/helpers/sol/',
- 'seaport-core/=contracts/',
+ '@openzeppelin/=lib/openzeppelin-contracts/',
'solarray/=lib/solarray/src/',
- 'solady/=lib/solady/'
+ 'solady/=lib/solady/',
+ 'seaport-sol/=lib/seaport-sol/',
+ 'seaport-types/=lib/seaport-types/',
+ 'seaport-core/=lib/seaport-core/',
+ 'seaport/=contracts/'
]
optimizer_runs = 4_294_967_295
fs_permissions = [
@@ -35,12 +38,14 @@ runs = 1_000
max_test_rejects = 1_000_000
[profile.reference]
-solc = '0.8.13'
+solc = '0.8.24'
src = 'reference'
+via_ir = false
out = 'reference-out'
script = 'reference'
-# specify something so it doesn't try to compile the 0.8.17 files in test/foundry
-test = 'reference'
+test = 'test/foundry'
+cache_path = 'reference-cache'
+
[profile.optimized]
via_ir = true
diff --git a/hardhat-coverage.config.ts b/hardhat-coverage.config.ts
index 03dca0df8..c8d0d1369 100644
--- a/hardhat-coverage.config.ts
+++ b/hardhat-coverage.config.ts
@@ -13,8 +13,9 @@ const config: HardhatUserConfig = {
solidity: {
compilers: [
{
- version: "0.8.17",
+ version: "0.8.24",
settings: {
+ evmVersion: "cancun",
viaIR: false,
optimizer: {
enabled: false,
@@ -25,8 +26,9 @@ const config: HardhatUserConfig = {
},
networks: {
hardhat: {
- blockGasLimit: 30_000_000,
+ blockGasLimit: 300_000_000,
throwOnCallFailures: false,
+ allowUnlimitedContractSize: true,
},
},
gasReporter: {
diff --git a/hardhat.config.ts b/hardhat.config.ts
index b0b032f06..863ba6a32 100644
--- a/hardhat.config.ts
+++ b/hardhat.config.ts
@@ -69,8 +69,9 @@ const config: HardhatUserConfig = {
solidity: {
compilers: [
{
- version: "0.8.17",
+ version: "0.8.24",
settings: {
+ evmVersion: "cancun",
viaIR: true,
optimizer: {
...(process.env.NO_SPECIALIZER
@@ -133,6 +134,7 @@ const config: HardhatUserConfig = {
},
networks: {
hardhat: {
+ hardfork: "cancun",
blockGasLimit: 30_000_000,
throwOnCallFailures: false,
allowUnlimitedContractSize: false,
diff --git a/lib/forge-std b/lib/forge-std
index a2edd39db..cffb56287 160000
--- a/lib/forge-std
+++ b/lib/forge-std
@@ -1 +1 @@
-Subproject commit a2edd39db95df7e9dd3f9ef9edc8c55fefddb6df
+Subproject commit cffb5628775fbf120bfc3c123149f6a6d99dc275
diff --git a/lib/seaport-core b/lib/seaport-core
new file mode 160000
index 000000000..523097f9c
--- /dev/null
+++ b/lib/seaport-core
@@ -0,0 +1 @@
+Subproject commit 523097f9cee66c15d308c900c50f336b291cda08
diff --git a/lib/seaport-sol b/lib/seaport-sol
new file mode 160000
index 000000000..7b480ce2b
--- /dev/null
+++ b/lib/seaport-sol
@@ -0,0 +1 @@
+Subproject commit 7b480ce2b5f258f283726c3a001b8bf7a8ae62fc
diff --git a/lib/seaport-types b/lib/seaport-types
new file mode 160000
index 000000000..b72493221
--- /dev/null
+++ b/lib/seaport-types
@@ -0,0 +1 @@
+Subproject commit b72493221ee1d2f2fb30ed94a3cc535a9028d09f
diff --git a/package.json b/package.json
index 0afdbf85d..d4ee6724f 100644
--- a/package.json
+++ b/package.json
@@ -1,20 +1,24 @@
{
"name": "seaport",
- "version": "1.5.0",
+ "version": "1.6.0",
"description": "Seaport is a marketplace protocol for safely and efficiently buying and selling NFTs. Each listing 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\").",
"main": "contracts/Seaport.sol",
"author": "0age",
"license": "MIT",
"private": false,
"engines": {
- "node": ">=16.15.1"
+ "node": ">=18.15.0"
},
"dependencies": {
"@nomicfoundation/hardhat-network-helpers": "^1.0.7",
+ "@openzeppelin/contracts": "^4.9.3",
"ethers": "^5.5.3",
"ethers-eip712": "^0.2.0",
- "hardhat": "^2.12.1-ir.0",
+ "hardhat": "^2.21.0",
"merkletreejs": "^0.3.9",
+ "seaport-core": "1.6.6",
+ "seaport-sol": "1.6.0",
+ "seaport-types": "1.6.3",
"solady": "^0.0.84"
},
"devDependencies": {
@@ -46,7 +50,7 @@
"prettier-plugin-solidity": "^1.1.0",
"scuffed-abi": "^1.0.4",
"solhint": "^3.3.6",
- "solidity-coverage": "^0.8.2",
+ "solidity-coverage": "^0.8.10",
"ts-node": "^10.4.0",
"typechain": "^8.0.0",
"typescript": "^4.5.4"
@@ -101,6 +105,7 @@
"show:headroom": "jq -r '.deployedBytecode' artifacts/contracts/Seaport.sol/Seaport.json | tr -d '\n' | wc -m | awk '{print 24577 - ($1 - 2)/2}'",
"test:forge": "FOUNDRY_PROFILE=reference forge build; FOUNDRY_PROFILE=optimized forge build; FOUNDRY_PROFILE=test forge test -vvv",
"test:forge:lite": "FOUNDRY_PROFILE=reference forge build; FOUNDRY_PROFILE=lite forge test -vvv",
+ "test:forge:ref": "FOUNDRY_PROFILE=reference forge build; FOUNDRY_PROFILE=optimized forge build; FOUNDRY_PROFILE=reference MOAT_PROFILE=reference forge test -vvv",
"build:validator": "hardhat compile --config ./hardhat-validator.config.ts",
"test:validator": "hardhat test --config ./hardhat-validator.config.ts",
"test:fuzz": "forge test --mp test/foundry/new/FuzzMain.t.sol",
diff --git a/reference/ReferenceConsideration.sol b/reference/ReferenceConsideration.sol
index b41a261b8..5cb353efd 100644
--- a/reference/ReferenceConsideration.sol
+++ b/reference/ReferenceConsideration.sol
@@ -3,9 +3,9 @@ pragma solidity ^0.8.13;
import {
ConsiderationInterface
-} from "../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
-import { OrderType } from "../contracts/lib/ConsiderationEnums.sol";
+import { OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdvancedOrder,
@@ -17,7 +17,7 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ReferenceOrderCombiner } from "./lib/ReferenceOrderCombiner.sol";
@@ -28,7 +28,9 @@ import { OrderToExecute } from "./lib/ReferenceConsiderationStructs.sol";
* @author 0age
* @custom:coauthor d1ll0n
* @custom:coauthor transmissions11
- * @custom:version 1.5-reference
+ * @custom:coauthor James Wenzel
+ * @custom:coauthor Daniel Viau
+ * @custom:version 1.6-reference
* @notice Consideration is a generalized native token/ERC20/ERC721/ERC1155
* marketplace. It minimizes external calls to the greatest extent
* possible and provides lightweight methods for common routes as well
diff --git a/reference/conduit/ReferenceConduit.sol b/reference/conduit/ReferenceConduit.sol
index e38b19f74..db655be09 100644
--- a/reference/conduit/ReferenceConduit.sol
+++ b/reference/conduit/ReferenceConduit.sol
@@ -3,9 +3,11 @@ pragma solidity ^0.8.13;
import {
ConduitInterface
-} from "../../contracts/interfaces/ConduitInterface.sol";
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
-import { ConduitItemType } from "../../contracts/conduit/lib/ConduitEnums.sol";
+import {
+ ConduitItemType
+} from "seaport-types/src/conduit/lib/ConduitEnums.sol";
import {
ReferenceTokenTransferrer
@@ -14,7 +16,7 @@ import {
import {
ConduitBatch1155Transfer,
ConduitTransfer
-} from "../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
/**
* @title ReferenceConduit
diff --git a/reference/conduit/ReferenceConduitController.sol b/reference/conduit/ReferenceConduitController.sol
index 22dcc978c..87d936665 100644
--- a/reference/conduit/ReferenceConduitController.sol
+++ b/reference/conduit/ReferenceConduitController.sol
@@ -5,11 +5,11 @@ import { ReferenceConduit } from "./ReferenceConduit.sol";
import {
ConduitControllerInterface
-} from "../../contracts/interfaces/ConduitControllerInterface.sol";
+} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";
import {
ConduitInterface
-} from "../../contracts/interfaces/ConduitInterface.sol";
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
/**
* @title ConduitController
diff --git a/reference/lib/ReferenceAmountDeriver.sol b/reference/lib/ReferenceAmountDeriver.sol
index fa17dd181..91c2504ae 100644
--- a/reference/lib/ReferenceAmountDeriver.sol
+++ b/reference/lib/ReferenceAmountDeriver.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.13;
import {
AmountDerivationErrors
-} from "../../contracts/interfaces/AmountDerivationErrors.sol";
+} from "seaport-types/src/interfaces/AmountDerivationErrors.sol";
import { FractionData } from "./ReferenceConsiderationStructs.sol";
diff --git a/reference/lib/ReferenceAssertions.sol b/reference/lib/ReferenceAssertions.sol
index f9a6bfd1a..d87810842 100644
--- a/reference/lib/ReferenceAssertions.sol
+++ b/reference/lib/ReferenceAssertions.sol
@@ -1,13 +1,15 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { OrderParameters } from "../../contracts/lib/ConsiderationStructs.sol";
+import {
+ OrderParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ReferenceGettersAndDerivers } from "./ReferenceGettersAndDerivers.sol";
import {
TokenTransferrerErrors
-} from "../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
import { ReferenceCounterManager } from "./ReferenceCounterManager.sol";
diff --git a/reference/lib/ReferenceBasicOrderFulfiller.sol b/reference/lib/ReferenceBasicOrderFulfiller.sol
index 50222a7d3..6ac84bead 100644
--- a/reference/lib/ReferenceBasicOrderFulfiller.sol
+++ b/reference/lib/ReferenceBasicOrderFulfiller.sol
@@ -6,7 +6,7 @@ import {
BasicOrderType,
ItemType,
OrderType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdditionalRecipient,
@@ -15,7 +15,7 @@ import {
OfferItem,
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
AccumulatorStruct,
@@ -815,6 +815,15 @@ contract ReferenceBasicOrderFulfiller is ReferenceOrderValidator {
);
}
+ // Determine whether order is restricted and, if so, that it is valid.
+ _assertRestrictedBasicOrderAuthorization(
+ hashes.orderHash,
+ orderType,
+ parameters,
+ offeredItemType,
+ receivedItemType
+ );
+
// Verify and update the status of the derived order.
_validateBasicOrderAndUpdateStatus(
hashes.orderHash,
diff --git a/reference/lib/ReferenceConsiderationBase.sol b/reference/lib/ReferenceConsiderationBase.sol
index 01391b0e4..4ec28ca62 100644
--- a/reference/lib/ReferenceConsiderationBase.sol
+++ b/reference/lib/ReferenceConsiderationBase.sol
@@ -3,15 +3,15 @@ pragma solidity ^0.8.13;
import {
ConduitControllerInterface
-} from "../../contracts/interfaces/ConduitControllerInterface.sol";
+} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";
import {
ConsiderationEventsAndErrors
-} from "../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import {
ReentrancyErrors
-} from "../../contracts/interfaces/ReentrancyErrors.sol";
+} from "seaport-types/src/interfaces/ReentrancyErrors.sol";
/**
* @title ConsiderationBase
@@ -25,7 +25,7 @@ contract ReferenceConsiderationBase is
{
// Declare constants for name, version, and reentrancy sentinel values.
string internal constant _NAME = "Consideration";
- string internal constant _VERSION = "1.5-reference";
+ string internal constant _VERSION = "1.6-reference";
uint256 internal constant _NOT_ENTERED = 1;
uint256 internal constant _ENTERED = 2;
diff --git a/reference/lib/ReferenceConsiderationStructs.sol b/reference/lib/ReferenceConsiderationStructs.sol
index adb4e2a19..f90a427a2 100644
--- a/reference/lib/ReferenceConsiderationStructs.sol
+++ b/reference/lib/ReferenceConsiderationStructs.sol
@@ -4,19 +4,49 @@ pragma solidity ^0.8.13;
import {
ItemType,
OrderType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ConduitTransfer
-} from "../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
// This file should only be used by the Reference Implementation
+/**
+ * @dev A struct used to hold the numerator and denominator of an order in-memory
+ * during validation, before it is written to storage when updating order
+ * status.
+ */
+struct StoredFractions {
+ uint256 storedNumerator;
+ uint256 storedDenominator;
+}
+
+/**
+ * @dev An intermediate struct used to hold information about an order after
+ * validation to prepare for execution.
+ */
+struct OrderValidation {
+ bytes32 orderHash;
+ uint256 newNumerator;
+ uint256 newDenominator;
+ OrderToExecute orderToExecute;
+}
+
+/**
+ * @dev A struct used to hold the parameters used to validate an order.
+ */
+struct OrderValidationParams {
+ bool revertOnInvalid;
+ uint256 maximumFulfilled;
+ address recipient;
+}
+
/**
* @dev A struct used to hold Consideration Indexes and Fulfillment validity.
*/
diff --git a/reference/lib/ReferenceCounterManager.sol b/reference/lib/ReferenceCounterManager.sol
index 32608da42..b424f9e72 100644
--- a/reference/lib/ReferenceCounterManager.sol
+++ b/reference/lib/ReferenceCounterManager.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.13;
import {
ConsiderationEventsAndErrors
-} from "../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import { ReferenceReentrancyGuard } from "./ReferenceReentrancyGuard.sol";
diff --git a/reference/lib/ReferenceCriteriaResolution.sol b/reference/lib/ReferenceCriteriaResolution.sol
index 4ad5e05bd..e592a436c 100644
--- a/reference/lib/ReferenceCriteriaResolution.sol
+++ b/reference/lib/ReferenceCriteriaResolution.sol
@@ -1,7 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ItemType, Side } from "../../contracts/lib/ConsiderationEnums.sol";
+import {
+ ItemType,
+ OrderType,
+ Side
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdvancedOrder,
@@ -11,13 +15,13 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { OrderToExecute } from "./ReferenceConsiderationStructs.sol";
import {
CriteriaResolutionErrors
-} from "../../contracts/interfaces/CriteriaResolutionErrors.sol";
+} from "seaport-types/src/interfaces/CriteriaResolutionErrors.sol";
/**
* @title CriteriaResolution
@@ -41,6 +45,7 @@ contract ReferenceCriteriaResolution is CriteriaResolutionErrors {
* that no proof needs to be supplied.
*/
function _applyCriteriaResolvers(
+ AdvancedOrder[] memory advancedOrders,
OrderToExecute[] memory ordersToExecute,
CriteriaResolver[] memory criteriaResolvers
) internal pure {
@@ -171,7 +176,13 @@ contract ReferenceCriteriaResolution is CriteriaResolutionErrors {
if (
_isItemWithCriteria(orderToExecute.spentItems[j].itemType)
) {
- revert UnresolvedOfferCriteria(i, j);
+ if (
+ advancedOrders[i].parameters.orderType !=
+ OrderType.CONTRACT ||
+ orderToExecute.spentItems[j].identifier != 0
+ ) {
+ revert UnresolvedOfferCriteria(i, j);
+ }
}
}
@@ -186,7 +197,13 @@ contract ReferenceCriteriaResolution is CriteriaResolutionErrors {
orderToExecute.receivedItems[j].itemType
)
) {
- revert UnresolvedConsiderationCriteria(i, j);
+ if (
+ advancedOrders[i].parameters.orderType !=
+ OrderType.CONTRACT ||
+ orderToExecute.receivedItems[j].identifier != 0
+ ) {
+ revert UnresolvedConsiderationCriteria(i, j);
+ }
}
}
}
@@ -321,7 +338,16 @@ contract ReferenceCriteriaResolution is CriteriaResolutionErrors {
advancedOrder.parameters.consideration[i].itemType
)
) {
- revert UnresolvedConsiderationCriteria(0, i);
+ if (
+ advancedOrder.parameters.orderType != OrderType.CONTRACT ||
+ advancedOrder
+ .parameters
+ .consideration[i]
+ .identifierOrCriteria !=
+ 0
+ ) {
+ revert UnresolvedConsiderationCriteria(0, i);
+ }
}
}
@@ -334,7 +360,12 @@ contract ReferenceCriteriaResolution is CriteriaResolutionErrors {
if (
_isItemWithCriteria(advancedOrder.parameters.offer[i].itemType)
) {
- revert UnresolvedOfferCriteria(0, i);
+ if (
+ advancedOrder.parameters.orderType != OrderType.CONTRACT ||
+ advancedOrder.parameters.offer[i].identifierOrCriteria != 0
+ ) {
+ revert UnresolvedOfferCriteria(0, i);
+ }
}
}
}
diff --git a/reference/lib/ReferenceExecutor.sol b/reference/lib/ReferenceExecutor.sol
index 02e58fa30..6bfbbc8e8 100644
--- a/reference/lib/ReferenceExecutor.sol
+++ b/reference/lib/ReferenceExecutor.sol
@@ -1,19 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ConduitItemType } from "../../contracts/conduit/lib/ConduitEnums.sol";
+import {
+ ConduitItemType
+} from "seaport-types/src/conduit/lib/ConduitEnums.sol";
import {
ConduitInterface
-} from "../../contracts/interfaces/ConduitInterface.sol";
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
import {
ConduitTransfer
-} from "../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
-import { ItemType } from "../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
-import { ReceivedItem } from "../../contracts/lib/ConsiderationStructs.sol";
+import { ReceivedItem } from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ReferenceVerifiers } from "./ReferenceVerifiers.sol";
diff --git a/reference/lib/ReferenceFulfillmentApplier.sol b/reference/lib/ReferenceFulfillmentApplier.sol
index d3b938468..9d7268ddc 100644
--- a/reference/lib/ReferenceFulfillmentApplier.sol
+++ b/reference/lib/ReferenceFulfillmentApplier.sol
@@ -1,14 +1,14 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ItemType, Side } from "../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
Execution,
FulfillmentComponent,
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ConsiderationItemIndicesAndValidity,
@@ -17,11 +17,11 @@ import {
import {
FulfillmentApplicationErrors
-} from "../../contracts/interfaces/FulfillmentApplicationErrors.sol";
+} from "seaport-types/src/interfaces/FulfillmentApplicationErrors.sol";
import {
TokenTransferrerErrors
-} from "../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
/**
* @title FulfillmentApplier
@@ -79,12 +79,6 @@ contract ReferenceFulfillmentApplier is
// Skip aggregating offer items if no consideration items are available.
if (considerationItem.amount == 0) {
- // Set the offerer and recipient to null address and item type to a
- // non-native item type if execution amount is zero. This will cause
- // the execution item to be skipped.
- execution.offerer = address(0);
- execution.item.recipient = payable(0);
- execution.item.itemType = ItemType.ERC20;
return execution;
}
@@ -141,11 +135,14 @@ contract ReferenceFulfillmentApplier is
}
// Reuse execution struct with consideration amount and recipient.
+ // Only set the recipient if the item amount is non-zero.
execution.item.amount = considerationItem.amount;
- execution.item.recipient = considerationItem.recipient;
+ if (execution.item.amount != 0) {
+ execution.item.recipient = considerationItem.recipient;
+ }
// Return the final execution that will be triggered for relevant items.
- return execution; // Execution(considerationItem, offerer, conduitKey);
+ return execution; // Execution(execution, offerer, conduitKey);
}
/**
@@ -204,21 +201,6 @@ contract ReferenceFulfillmentApplier is
);
}
- if (execution.item.amount == 0) {
- return
- Execution(
- ReceivedItem(
- ItemType.ERC20,
- address(0),
- 0,
- 0,
- payable(address(0))
- ),
- address(0),
- bytes32(0)
- );
- }
-
return execution;
}
@@ -395,12 +377,21 @@ contract ReferenceFulfillmentApplier is
)
);
- // Return execution for aggregated items provided by the fulfiller.
- execution = Execution(
- receiveConsiderationItem,
- msg.sender,
- fulfillerConduitKey
- );
+ if (receiveConsiderationItem.amount != 0) {
+ // Return execution for aggregated items provided by the fulfiller.
+ execution = Execution(
+ receiveConsiderationItem,
+ msg.sender,
+ fulfillerConduitKey
+ );
+ } else {
+ // Return an empty execution if the received item amount is zero.
+ execution = Execution(
+ receiveConsiderationItem,
+ address(0),
+ bytes32(0)
+ );
+ }
}
/**
diff --git a/reference/lib/ReferenceGenerateOrderReturndataDecoder.sol b/reference/lib/ReferenceGenerateOrderReturndataDecoder.sol
index 2331f4cbf..b257f35ee 100644
--- a/reference/lib/ReferenceGenerateOrderReturndataDecoder.sol
+++ b/reference/lib/ReferenceGenerateOrderReturndataDecoder.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.13;
import {
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract ReferenceGenerateOrderReturndataDecoder {
function decode(
diff --git a/reference/lib/ReferenceGettersAndDerivers.sol b/reference/lib/ReferenceGettersAndDerivers.sol
index 2ea74a5a8..043b42b62 100644
--- a/reference/lib/ReferenceGettersAndDerivers.sol
+++ b/reference/lib/ReferenceGettersAndDerivers.sol
@@ -5,7 +5,7 @@ import {
ConsiderationItem,
OfferItem,
OrderParameters
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ReferenceConsiderationBase } from "./ReferenceConsiderationBase.sol";
diff --git a/reference/lib/ReferenceOrderCombiner.sol b/reference/lib/ReferenceOrderCombiner.sol
index e2fbccc02..88b03c15c 100644
--- a/reference/lib/ReferenceOrderCombiner.sol
+++ b/reference/lib/ReferenceOrderCombiner.sol
@@ -5,7 +5,7 @@ import {
ItemType,
OrderType,
Side
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdvancedOrder,
@@ -18,21 +18,24 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import {
+ SeaportInterface
+} from "seaport-types/src/interfaces/SeaportInterface.sol";
import {
AccumulatorStruct,
- OrderToExecute
+ OrderToExecute,
+ StoredFractions,
+ OrderValidation,
+ OrderValidationParams
} from "./ReferenceConsiderationStructs.sol";
import { ReferenceOrderFulfiller } from "./ReferenceOrderFulfiller.sol";
import { ReferenceFulfillmentApplier } from "./ReferenceFulfillmentApplier.sol";
-import {
- SeaportInterface
-} from "../../contracts/interfaces/SeaportInterface.sol";
-
/**
* @title OrderCombiner
* @author 0age
@@ -149,9 +152,11 @@ contract ReferenceOrderCombiner is
advancedOrders,
ordersToExecute,
criteriaResolvers,
- false, // Signifies that invalid orders should NOT revert.
- maximumFulfilled,
- recipient
+ OrderValidationParams(
+ false, // Signifies that invalid orders should NOT revert.
+ maximumFulfilled,
+ recipient
+ )
);
// Execute transfers.
@@ -186,11 +191,7 @@ contract ReferenceOrderCombiner is
* a root of zero indicates that any transferable
* token identifier is valid and that no proof
* needs to be supplied.
- * @param revertOnInvalid A boolean indicating whether to revert on any
- * order being invalid; setting this to false will
- * instead cause the invalid order to be skipped.
- * @param maximumFulfilled The maximum number of orders to fulfill.
- * @param recipient The intended recipient for all received items.
+ * @param orderValidationParams Various order validation params.
*
* @return orderHashes The hashes of the orders being fulfilled.
* @return containsNonOpen A boolean indicating whether any restricted or
@@ -201,65 +202,51 @@ contract ReferenceOrderCombiner is
AdvancedOrder[] memory advancedOrders,
OrderToExecute[] memory ordersToExecute,
CriteriaResolver[] memory criteriaResolvers,
- bool revertOnInvalid,
- uint256 maximumFulfilled,
- address recipient
+ OrderValidationParams memory orderValidationParams
) internal returns (bytes32[] memory orderHashes, bool containsNonOpen) {
// Track the order hash for each order being fulfilled.
orderHashes = new bytes32[](advancedOrders.length);
- // Determine whether or not order matching is underway.
- bool nonMatchFn = msg.sig !=
- SeaportInterface.matchAdvancedOrders.selector &&
- msg.sig != SeaportInterface.matchOrders.selector;
-
// Declare a variable for tracking whether native offer items are
// present on orders that are not contract orders.
bool anyNativeOfferItemsOnNonContractOrders;
+ StoredFractions[] memory storedFractions = new StoredFractions[](
+ advancedOrders.length
+ );
+
// Iterate over each order.
for (uint256 i = 0; i < advancedOrders.length; ++i) {
// Retrieve the current order.
AdvancedOrder memory advancedOrder = advancedOrders[i];
- // Determine if max number orders have already been fulfilled.
- if (maximumFulfilled == 0) {
- // Mark fill fraction as zero as the order will not be used.
- advancedOrder.numerator = 0;
-
- // Mark fill fraction as zero as the order will not be used.
- ordersToExecute[i].numerator = 0;
-
- // Continue iterating through the remaining orders.
- continue;
- }
-
- // Validate it, update status, and determine fraction to fill.
- (
- bytes32 orderHash,
- uint256 numerator,
- uint256 denominator,
- OrderToExecute memory orderToExecute
- ) = _validateOrderAndUpdateStatus(advancedOrder, revertOnInvalid);
+ // Validate the order and determine fraction to fill.
+ OrderValidation memory orderValidation = _validateOrder(
+ advancedOrder,
+ orderValidationParams.revertOnInvalid
+ );
// Do not track hash or adjust prices if order is not fulfilled.
- if (numerator == 0) {
+ if (orderValidation.newNumerator == 0) {
// Mark fill fraction as zero if the order is not fulfilled.
advancedOrder.numerator = 0;
// Mark fill fraction as zero as the order will not be used.
- orderToExecute.numerator = 0;
- ordersToExecute[i] = orderToExecute;
+ orderValidation.orderToExecute.numerator = 0;
+ ordersToExecute[i] = orderValidation.orderToExecute;
// Continue iterating through the remaining orders.
continue;
}
// Otherwise, track the order hash in question.
- orderHashes[i] = orderHash;
+ orderHashes[i] = orderValidation.orderHash;
- // Decrement the number of fulfilled orders.
- maximumFulfilled--;
+ // Store the numerator and denominator for the order status.
+ storedFractions[i] = StoredFractions({
+ storedNumerator: orderValidation.newNumerator,
+ storedDenominator: orderValidation.newDenominator
+ });
{
// Retrieve array of offer items for the order in question.
@@ -284,8 +271,8 @@ contract ReferenceOrderCombiner is
// Retrieve the offer item.
OfferItem memory offerItem = offer[j];
- // Determine if there are any native offer items on non-contract
- // orders.
+ // Determine if there are any native offer items on
+ // non-contract orders.
anyNativeOfferItemsOnNonContractOrders =
anyNativeOfferItemsOnNonContractOrders ||
(offerItem.itemType == ItemType.NATIVE &&
@@ -293,25 +280,25 @@ contract ReferenceOrderCombiner is
// Apply order fill fraction to offer item end amount.
uint256 endAmount = _getFraction(
- numerator,
- denominator,
+ orderValidation.newNumerator,
+ orderValidation.newDenominator,
offerItem.endAmount
);
- // Reuse same fraction if start and end amounts are equal.
+ // Reuse same fraction if start & end amounts are equal.
if (offerItem.startAmount == offerItem.endAmount) {
- // Apply derived amount to both start and end amount.
+ // Apply derived amount to both start & end amount.
offerItem.startAmount = endAmount;
} else {
- // Apply order fill fraction to offer item start amount.
+ // Apply order fill fraction to item start amount.
offerItem.startAmount = _getFraction(
- numerator,
- denominator,
+ orderValidation.newNumerator,
+ orderValidation.newDenominator,
offerItem.startAmount
);
}
- // Update end amount in memory to match the derived amount.
+ // Update end amount in memory to match derived amount.
offerItem.endAmount = endAmount;
// Adjust offer amount using current time; round down.
@@ -324,16 +311,19 @@ contract ReferenceOrderCombiner is
);
// Modify the OrderToExecute Spent Item Amount.
- orderToExecute.spentItems[j].amount = offerItem
- .startAmount;
- // Modify the OrderToExecute Spent Item Original Amount.
- orderToExecute.spentItemOriginalAmounts[j] = offerItem
- .startAmount;
+ orderValidation
+ .orderToExecute
+ .spentItems[j]
+ .amount = offerItem.startAmount;
+ // Modify the OrderToExecute Spent Item Original amount.
+ orderValidation.orderToExecute.spentItemOriginalAmounts[
+ j
+ ] = (offerItem.startAmount);
}
}
{
- // Retrieve array of consideration items for order in question.
+ // Get array of consideration items for order in question.
ConsiderationItem[] memory consideration = (
advancedOrder.parameters.consideration
);
@@ -347,31 +337,27 @@ contract ReferenceOrderCombiner is
// Apply fraction to consideration item end amount.
uint256 endAmount = _getFraction(
- numerator,
- denominator,
+ orderValidation.newNumerator,
+ orderValidation.newDenominator,
considerationItem.endAmount
);
- // Reuse same fraction if start and end amounts are equal.
+ // Reuse same fraction if start & end amounts are equal.
if (
considerationItem.startAmount ==
- considerationItem.endAmount
+ (considerationItem.endAmount)
) {
- // Apply derived amount to both start and end amount.
+ // Apply derived amount to both start & end amount.
considerationItem.startAmount = endAmount;
} else {
- // Apply fraction to consideration item start amount.
+ // Apply fraction to item start amount.
considerationItem.startAmount = _getFraction(
- numerator,
- denominator,
+ orderValidation.newNumerator,
+ orderValidation.newDenominator,
considerationItem.startAmount
);
}
- // TODO: Check with 0. Appears to be no longer in optimized.
- // // Update end amount in memory to match the derived amount.
- // considerationItem.endAmount = endAmount;
-
uint256 currentAmount = (
_locateCurrentAmount(
considerationItem.startAmount,
@@ -385,60 +371,156 @@ contract ReferenceOrderCombiner is
considerationItem.startAmount = currentAmount;
// Modify the OrderToExecute Received item amount.
- orderToExecute
+ orderValidation
+ .orderToExecute
.receivedItems[j]
.amount = considerationItem.startAmount;
- // Modify the OrderToExecute Received item original amount.
- orderToExecute.receivedItemOriginalAmounts[
- j
- ] = considerationItem.startAmount;
+ // Modify OrderToExecute Received item original amount.
+ orderValidation
+ .orderToExecute
+ .receivedItemOriginalAmounts[j] = (
+ considerationItem.startAmount
+ );
}
}
}
- ordersToExecute[i] = orderToExecute;
+ ordersToExecute[i] = orderValidation.orderToExecute;
}
- if (anyNativeOfferItemsOnNonContractOrders && nonMatchFn) {
+ if (
+ anyNativeOfferItemsOnNonContractOrders &&
+ (msg.sig != SeaportInterface.matchAdvancedOrders.selector &&
+ msg.sig != SeaportInterface.matchOrders.selector)
+ ) {
revert InvalidNativeOfferItem();
}
// Apply criteria resolvers to each order as applicable.
- _applyCriteriaResolvers(ordersToExecute, criteriaResolvers);
+ _applyCriteriaResolvers(
+ advancedOrders,
+ ordersToExecute,
+ criteriaResolvers
+ );
- // Emit an event for each order signifying that it has been fulfilled.
- // Iterate over each order.
+ bool someOrderAvailable;
+
+ // Iterate over each order to check authorization status (for restricted
+ // orders), generate orders (for contract orders), and emit events (for
+ // all available orders) signifying that they have been fulfilled.
for (uint256 i = 0; i < advancedOrders.length; ++i) {
// Do not emit an event if no order hash is present.
if (orderHashes[i] == bytes32(0)) {
continue;
}
+ // Determine if max number orders have already been fulfilled.
+ if (orderValidationParams.maximumFulfilled == 0) {
+ orderHashes[i] = bytes32(0);
+ ordersToExecute[i].numerator = 0;
+
+ // Continue iterating through the remaining orders.
+ continue;
+ }
+
// Retrieve parameters for the order in question.
OrderParameters memory orderParameters = (
advancedOrders[i].parameters
);
+ // Ensure restricted orders have valid submitter or pass zone check.
+ (
+ bool valid /* bool checked */,
+
+ ) = _checkRestrictedAdvancedOrderAuthorization(
+ advancedOrders[i],
+ ordersToExecute[i],
+ _shorten(orderHashes, i),
+ orderHashes[i],
+ orderValidationParams.revertOnInvalid
+ );
+
+ if (!valid) {
+ orderHashes[i] = bytes32(0);
+ ordersToExecute[i].numerator = 0;
+ continue;
+ }
+
+ // Update status if the order is still valid or skip if not checked
+ if (orderParameters.orderType != OrderType.CONTRACT) {
+ if (
+ !_updateStatus(
+ orderHashes[i],
+ storedFractions[i].storedNumerator,
+ storedFractions[i].storedDenominator,
+ _revertOnFailedUpdate(
+ orderParameters,
+ orderValidationParams.revertOnInvalid
+ )
+ )
+ ) {
+ orderHashes[i] = bytes32(0);
+ ordersToExecute[i].numerator = 0;
+ continue;
+ }
+ } else {
+ bytes32 orderHash = _getGeneratedOrder(
+ ordersToExecute[i],
+ orderParameters,
+ advancedOrders[i].extraData,
+ orderValidationParams.revertOnInvalid
+ );
+
+ orderHashes[i] = orderHash;
+
+ if (orderHash == bytes32(0)) {
+ ordersToExecute[i].numerator = 0;
+ continue;
+ }
+ }
+
+ // Decrement the number of fulfilled orders.
+ orderValidationParams.maximumFulfilled--;
+
// Get the array of spentItems from the orderToExecute struct.
SpentItem[] memory spentItems = ordersToExecute[i].spentItems;
// Get the array of spent receivedItems from the
// orderToExecute struct.
- ReceivedItem[] memory receivedItems = ordersToExecute[i]
- .receivedItems;
+ ReceivedItem[] memory receivedItems = (
+ ordersToExecute[i].receivedItems
+ );
// Emit an event signifying that the order has been fulfilled.
emit OrderFulfilled(
orderHashes[i],
orderParameters.offerer,
orderParameters.zone,
- recipient,
+ orderValidationParams.recipient,
spentItems,
receivedItems
);
+
+ someOrderAvailable = true;
+ }
+
+ // Revert if no orders are available.
+ if (!someOrderAvailable) {
+ revert NoSpecifiedOrdersAvailable();
}
}
+ function _shorten(
+ bytes32[] memory orderHashes,
+ uint256 index
+ ) internal pure returns (bytes32[] memory) {
+ bytes32[] memory shortened = new bytes32[](index);
+ for (uint256 i = 0; i < index; i++) {
+ shortened[i] = orderHashes[i];
+ }
+ return shortened;
+ }
+
/**
* @dev Internal function to fulfill a group of validated orders, fully or
* partially, with an arbitrary number of items for offer and
@@ -524,90 +606,32 @@ contract ReferenceOrderCombiner is
totalOfferFulfillments + totalConsiderationFulfillments
);
- // Track number of filtered executions.
- uint256 totalFilteredExecutions = 0;
-
// Iterate over each offer fulfillment.
for (uint256 i = 0; i < totalOfferFulfillments; ++i) {
- // Derive aggregated execution corresponding with fulfillment.
- Execution memory execution = _aggregateAvailable(
+ // Derive aggregated execution corresponding with fulfillment and
+ // assign the execution to the executions array.
+ executions[i] = _aggregateAvailable(
ordersToExecute,
Side.OFFER,
offerFulfillments[i],
fulfillerConduitKey,
recipient
);
-
- // If offerer and recipient on the execution are the same and the
- // execution item has a non-native item type...
- if (
- execution.item.recipient == execution.offerer &&
- execution.item.itemType != ItemType.NATIVE
- ) {
- // Increment total filtered executions.
- ++totalFilteredExecutions;
- } else {
- // Otherwise, assign the execution to the executions array.
- executions[i - totalFilteredExecutions] = execution;
- }
}
// Iterate over each consideration fulfillment.
for (uint256 i = 0; i < totalConsiderationFulfillments; ++i) {
- // Derive aggregated execution corresponding with fulfillment.
- Execution memory execution = _aggregateAvailable(
+ // Derive aggregated execution corresponding with fulfillment and
+ // assign the execution to the executions array.
+ executions[i + totalOfferFulfillments] = _aggregateAvailable(
ordersToExecute,
Side.CONSIDERATION,
considerationFulfillments[i],
fulfillerConduitKey,
address(0) // unused
);
-
- // If offerer and recipient on the execution are the same and the
- // execution item has a non-native item type...
- if (
- execution.item.recipient == execution.offerer &&
- execution.item.itemType != ItemType.NATIVE
- ) {
- // Increment total filtered executions.
- ++totalFilteredExecutions;
- } else {
- // Otherwise, assign the execution to the executions array.
- executions[
- i + totalOfferFulfillments - totalFilteredExecutions
- ] = execution;
- }
}
- // If some number of executions have been filtered...
- if (totalFilteredExecutions != 0) {
- /**
- * The following is highly inefficient, but written this way
- * to show in the most simplest form what the optimized
- * contract is performing inside its assembly.
- */
-
- // Get the total execution length.
- uint256 executionLength = (totalOfferFulfillments +
- totalConsiderationFulfillments) - totalFilteredExecutions;
-
- // Create an array of executions that will be executed.
- Execution[] memory filteredExecutions = new Execution[](
- executionLength
- );
-
- // Create new array from the existing Executions
- for (uint256 i = 0; i < executionLength; ++i) {
- filteredExecutions[i] = executions[i];
- }
-
- // Set the executions array to the newly created array.
- executions = filteredExecutions;
- }
- // Revert if no orders are available.
- if (executions.length == 0) {
- revert NoSpecifiedOrdersAvailable();
- }
// Perform final checks and compress executions into standard and batch.
availableOrders = _performFinalChecksAndExecuteOrders(
advancedOrders,
@@ -667,6 +691,11 @@ contract ReferenceOrderCombiner is
Execution memory execution = executions[i];
ReceivedItem memory item = execution.item;
+ // Skip transfers if the execution amount is zero.
+ if (item.amount == 0) {
+ continue;
+ }
+
// If execution transfers native tokens, reduce value available.
if (item.itemType == ItemType.NATIVE) {
// Ensure that sufficient native tokens are still available.
@@ -712,23 +741,22 @@ contract ReferenceOrderCombiner is
{
// Retrieve offer items.
- OfferItem[] memory offer = parameters.offer;
+ SpentItem[] memory offer = orderToExecute.spentItems;
// Read length of offer array & place on the stack.
uint256 totalOfferItems = offer.length;
// Iterate over each offer item to restore it.
for (uint256 j = 0; j < totalOfferItems; ++j) {
- SpentItem memory offerSpentItem = orderToExecute.spentItems[
- j
- ];
+ SpentItem memory offerSpentItem = offer[j];
// Retrieve remaining amount on the offer item.
uint256 unspentAmount = offerSpentItem.amount;
// Retrieve original amount on the offer item.
- uint256 originalAmount = orderToExecute
- .spentItemOriginalAmounts[j];
+ uint256 originalAmount = (
+ orderToExecute.spentItemOriginalAmounts[j]
+ );
// Transfer to recipient if unspent amount is not zero.
// Note that the transfer will not be reflected in the
@@ -767,21 +795,9 @@ contract ReferenceOrderCombiner is
}
// Restore original amount.
- consideration[j].amount = orderToExecute
- .receivedItemOriginalAmounts[j];
- }
- }
-
- {
- // Get offer items as well.
- SpentItem[] memory offer = (orderToExecute.spentItems);
-
- // Iterate over each consideration item to ensure it is met.
- for (uint256 j = 0; j < offer.length; ++j) {
- // Restore original amount.
- offer[j].amount = orderToExecute.spentItemOriginalAmounts[
- j
- ];
+ consideration[j].amount = (
+ orderToExecute.receivedItemOriginalAmounts[j]
+ );
}
}
}
@@ -848,6 +864,7 @@ contract ReferenceOrderCombiner is
address recipient
) internal pure returns (ReceivedItem memory) {
address payable _recipient;
+
_recipient = payable(recipient);
return
@@ -905,10 +922,9 @@ contract ReferenceOrderCombiner is
address recipient
) internal returns (Execution[] memory executions) {
// Convert Advanced Orders to Orders to Execute
- OrderToExecute[]
- memory ordersToExecute = _convertAdvancedToOrdersToExecute(
- advancedOrders
- );
+ OrderToExecute[] memory ordersToExecute = (
+ _convertAdvancedToOrdersToExecute(advancedOrders)
+ );
// Validate orders, apply amounts, & determine if they utilize conduits.
(
@@ -918,9 +934,11 @@ contract ReferenceOrderCombiner is
advancedOrders,
ordersToExecute,
criteriaResolvers,
- true, // Signifies that invalid orders should revert.
- advancedOrders.length,
- recipient
+ OrderValidationParams(
+ true, // Signifies that invalid orders should revert.
+ advancedOrders.length,
+ recipient
+ )
);
// Emit OrdersMatched event.
@@ -974,49 +992,19 @@ contract ReferenceOrderCombiner is
// Allocate executions by fulfillment and apply them to each execution.
executions = new Execution[](totalFulfillments);
- // Track number of filtered executions.
- uint256 totalFilteredExecutions = 0;
-
// Iterate over each fulfillment.
for (uint256 i = 0; i < totalFulfillments; ++i) {
/// Retrieve the fulfillment in question.
Fulfillment calldata fulfillment = fulfillments[i];
- // Derive the execution corresponding with the fulfillment.
- Execution memory execution = _applyFulfillment(
+ // Derive the execution corresponding with the fulfillment and
+ // assign the execution to the executions array.
+ executions[i] = _applyFulfillment(
ordersToExecute,
fulfillment.offerComponents,
fulfillment.considerationComponents,
i
);
-
- // If offerer and recipient on the execution are the same and the
- // execution item has a non-native item type...
- if (
- execution.item.recipient == execution.offerer &&
- execution.item.itemType != ItemType.NATIVE
- ) {
- // Increment total filtered executions.
- ++totalFilteredExecutions;
- } else {
- // Otherwise, assign the execution to the executions array.
- executions[i - totalFilteredExecutions] = execution;
- }
- }
-
- // If some number of executions have been filtered...
- if (totalFilteredExecutions != 0) {
- uint256 executionLength = totalFulfillments -
- totalFilteredExecutions;
- Execution[] memory filteredExecutions = new Execution[](
- executionLength
- );
- // Create new array from executions.
- for (uint256 i = 0; i < executionLength; ++i) {
- filteredExecutions[i] = executions[i];
- }
-
- executions = filteredExecutions;
}
// Perform final checks and execute orders.
@@ -1032,4 +1020,32 @@ contract ReferenceOrderCombiner is
// Return executions.
return executions;
}
+
+ /**
+ * @dev Internal view function to determine whether a status update failure
+ * should cause a revert or allow a skipped order. The call must revert
+ * if an `authorizeOrder` call has been successfully performed and the
+ * status update cannot be performed, regardless of whether the order
+ * could be otherwise marked as skipped. Note that a revert is not
+ * required on a failed update if the call originates from the zone, as
+ * no `authorizeOrder` call is performed in that case.
+ *
+ * @param orderParameters The order parameters in question.
+ * @param revertOnInvalid A boolean indicating whether the call should
+ * revert for non-restricted order types.
+ *
+ * @return revertOnFailedUpdate A boolean indicating whether the order
+ * should revert on a failed status update.
+ */
+ function _revertOnFailedUpdate(
+ OrderParameters memory orderParameters,
+ bool revertOnInvalid
+ ) internal view returns (bool revertOnFailedUpdate) {
+ OrderType orderType = orderParameters.orderType;
+ address zone = orderParameters.zone;
+ return (revertOnInvalid ||
+ ((orderType == OrderType.FULL_RESTRICTED ||
+ orderType == OrderType.PARTIAL_RESTRICTED) &&
+ zone != msg.sender));
+ }
}
diff --git a/reference/lib/ReferenceOrderFulfiller.sol b/reference/lib/ReferenceOrderFulfiller.sol
index 0b3287e6b..2a05cd9b7 100644
--- a/reference/lib/ReferenceOrderFulfiller.sol
+++ b/reference/lib/ReferenceOrderFulfiller.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.13;
import {
ItemType,
OrderType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdvancedOrder,
@@ -15,12 +15,13 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
AccumulatorStruct,
FractionData,
- OrderToExecute
+ OrderToExecute,
+ OrderValidation
} from "./ReferenceConsiderationStructs.sol";
import {
@@ -85,13 +86,11 @@ contract ReferenceOrderFulfiller is
bytes32 fulfillerConduitKey,
address recipient
) internal returns (bool) {
- // Validate order, update status, and determine fraction to fill.
- (
- bytes32 orderHash,
- uint256 fillNumerator,
- uint256 fillDenominator,
- OrderToExecute memory orderToExecute
- ) = _validateOrderAndUpdateStatus(advancedOrder, true);
+ // Validate the order and revert if it's invalid.
+ OrderValidation memory orderValidation = _validateOrder(
+ advancedOrder,
+ true
+ );
// Apply criteria resolvers using generated orders and details arrays.
_applyCriteriaResolversAdvanced(advancedOrder, criteriaResolvers);
@@ -100,24 +99,65 @@ contract ReferenceOrderFulfiller is
OrderParameters memory orderParameters = advancedOrder.parameters;
// Perform each item transfer with the appropriate fractional amount.
- orderToExecute = _applyFractionsAndTransferEach(
+ orderValidation.orderToExecute = _applyFractions(
orderParameters,
- fillNumerator,
- fillDenominator,
+ orderValidation.newNumerator,
+ orderValidation.newDenominator
+ );
+
+ // Declare empty bytes32 array.
+ bytes32[] memory priorOrderHashes = new bytes32[](0);
+
+ if (orderParameters.orderType != OrderType.CONTRACT) {
+ // Ensure restricted orders have valid submitter or pass zone check.
+ _assertRestrictedAdvancedOrderAuthorization(
+ advancedOrder,
+ orderValidation.orderToExecute,
+ priorOrderHashes,
+ orderValidation.orderHash,
+ orderParameters.zoneHash,
+ orderParameters.orderType,
+ orderParameters.offerer,
+ orderParameters.zone
+ );
+
+ // Update the order status to reflect the new numerator and denominator.
+ // Revert if the order is not valid.
+ _updateStatus(
+ orderValidation.orderHash,
+ orderValidation.newNumerator,
+ orderValidation.newDenominator,
+ true
+ );
+ } else {
+ bytes32 orderHash = _getGeneratedOrder(
+ orderValidation.orderToExecute,
+ advancedOrder.parameters,
+ advancedOrder.extraData,
+ true
+ );
+
+ orderValidation.orderHash = orderHash;
+ }
+
+ // Transfer each item contained in the order.
+ _transferEach(
+ orderParameters,
+ orderValidation.orderToExecute,
fulfillerConduitKey,
recipient
);
// Declare bytes32 array with this order's hash
- bytes32[] memory priorOrderHashes = new bytes32[](1);
- priorOrderHashes[0] = orderHash;
+ priorOrderHashes = new bytes32[](1);
+ priorOrderHashes[0] = orderValidation.orderHash;
- // Ensure restricted orders have a valid submitter or pass a zone check.
+ // Ensure restricted orders have valid submitter or pass zone check.
_assertRestrictedAdvancedOrderValidity(
advancedOrder,
- orderToExecute,
+ orderValidation.orderToExecute,
priorOrderHashes,
- orderHash,
+ orderValidation.orderHash,
orderParameters.zoneHash,
orderParameters.orderType,
orderParameters.offerer,
@@ -126,65 +166,47 @@ contract ReferenceOrderFulfiller is
// Emit an event signifying that the order has been fulfilled.
emit OrderFulfilled(
- orderHash,
+ orderValidation.orderHash,
orderParameters.offerer,
orderParameters.zone,
recipient,
- orderToExecute.spentItems,
- orderToExecute.receivedItems
+ orderValidation.orderToExecute.spentItems,
+ orderValidation.orderToExecute.receivedItems
);
return true;
}
/**
- * @dev Internal function to transfer each item contained in a given single
- * order fulfillment after applying a respective fraction to the amount
- * being transferred.
+ * @dev Internal view function to apply a respective fraction to the
+ * amount being transferred on each item of an order.
*
* @param orderParameters The parameters for the fulfilled order.
* @param numerator A value indicating the portion of the order
* that should be filled.
* @param denominator A value indicating the total order size.
- * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
- * any, to source the fulfiller's token approvals
- * from. The zero hash signifies that no conduit
- * should be used (and direct approvals set on
- * Consideration).
- * @param recipient The intended recipient for all received items.
- * @return orderToExecute Returns the order of items that are being
+ * @return orderToExecute Returns the order with items that are being
* transferred. This will be used for the
* OrderFulfilled Event.
*/
- function _applyFractionsAndTransferEach(
+ function _applyFractions(
OrderParameters memory orderParameters,
uint256 numerator,
- uint256 denominator,
- bytes32 fulfillerConduitKey,
- address recipient
- ) internal returns (OrderToExecute memory orderToExecute) {
+ uint256 denominator
+ ) internal view returns (OrderToExecute memory orderToExecute) {
// Derive order duration, time elapsed, and time remaining.
// Store in memory to avoid stack too deep issues.
FractionData memory fractionData = FractionData(
numerator,
denominator,
- fulfillerConduitKey,
+ 0, // fulfillerConduitKey is not used here.
orderParameters.startTime,
orderParameters.endTime
);
- // Create the accumulator struct.
- AccumulatorStruct memory accumulatorStruct;
-
- // Get the offerer of the order.
- address offerer = orderParameters.offerer;
-
- // Get the conduitKey of the order
- bytes32 conduitKey = orderParameters.conduitKey;
-
// Create the array to store the spent items for event.
- orderToExecute.spentItems = new SpentItem[](
- orderParameters.offer.length
+ orderToExecute.spentItems = (
+ new SpentItem[](orderParameters.offer.length)
);
// Declare a nested scope to minimize stack depth.
@@ -211,31 +233,19 @@ contract ReferenceOrderFulfiller is
false
);
- // Create Received Item from Offer Item for transfer.
- ReceivedItem memory receivedItem = ReceivedItem(
+ // Create Spent Item for the OrderFulfilled event.
+ orderToExecute.spentItems[i] = SpentItem(
offerItem.itemType,
offerItem.token,
offerItem.identifierOrCriteria,
- amount,
- payable(recipient)
- );
-
- // Create Spent Item for the OrderFulfilled event.
- orderToExecute.spentItems[i] = SpentItem(
- receivedItem.itemType,
- receivedItem.token,
- receivedItem.identifier,
amount
);
-
- // Transfer the item from the offerer to the recipient.
- _transfer(receivedItem, offerer, conduitKey, accumulatorStruct);
}
}
// Create the array to store the received items for event.
- orderToExecute.receivedItems = new ReceivedItem[](
- orderParameters.consideration.length
+ orderToExecute.receivedItems = (
+ new ReceivedItem[](orderParameters.consideration.length)
);
// Declare a nested scope to minimize stack depth.
@@ -255,20 +265,82 @@ contract ReferenceOrderFulfiller is
true
);
- // Create Received Item from Offer item.
- ReceivedItem memory receivedItem = ReceivedItem(
+ // Create Received Item from Offer item & add to structs array.
+ orderToExecute.receivedItems[i] = ReceivedItem(
considerationItem.itemType,
considerationItem.token,
considerationItem.identifierOrCriteria,
amount,
considerationItem.recipient
);
- // Add ReceivedItem to structs array.
- orderToExecute.receivedItems[i] = receivedItem;
+ }
+ }
+
+ // Return the order to execute.
+ return orderToExecute;
+ }
+
+ /**
+ * @dev Internal function to transfer each item contained in a given single
+ * order fulfillment.
+ *
+ * @param orderParameters The parameters for the fulfilled order.
+ * @param orderToExecute The items that are being transferred.
+ * @param fulfillerConduitKey A bytes32 value indicating what conduit, if
+ * any, to source the fulfiller's token approvals
+ * from. The zero hash signifies that no conduit
+ * should be used (and direct approvals set on
+ * Consideration).
+ * @param recipient The intended recipient for all received items.
+ */
+ function _transferEach(
+ OrderParameters memory orderParameters,
+ OrderToExecute memory orderToExecute,
+ bytes32 fulfillerConduitKey,
+ address recipient
+ ) internal {
+ // Create the accumulator struct.
+ AccumulatorStruct memory accumulatorStruct;
+
+ // Get the offerer of the order.
+ address offerer = orderParameters.offerer;
+
+ // Get the conduitKey of the order
+ bytes32 conduitKey = orderParameters.conduitKey;
+
+ // Declare a nested scope to minimize stack depth.
+ {
+ // Iterate over each spent item on the order.
+ for (uint256 i = 0; i < orderToExecute.spentItems.length; ++i) {
+ // Retrieve the spent item.
+ SpentItem memory spentItem = orderToExecute.spentItems[i];
+
+ // Create Received Item from Spent Item for transfer.
+ ReceivedItem memory receivedItem = ReceivedItem(
+ spentItem.itemType,
+ spentItem.token,
+ spentItem.identifier,
+ spentItem.amount,
+ payable(recipient)
+ );
+
+ // Transfer the item from the offerer to the recipient.
+ _transfer(receivedItem, offerer, conduitKey, accumulatorStruct);
+ }
+ }
+
+ // Declare a nested scope to minimize stack depth.
+ {
+ // Iterate over each received item on the order.
+ for (uint256 i = 0; i < orderToExecute.receivedItems.length; ++i) {
+ // Retrieve the received item.
+ ReceivedItem memory receivedItem = (
+ orderToExecute.receivedItems[i]
+ );
if (receivedItem.itemType == ItemType.NATIVE) {
// Ensure that sufficient native tokens are still available.
- if (amount > address(this).balance) {
+ if (receivedItem.amount > address(this).balance) {
revert InsufficientNativeTokensSupplied();
}
}
@@ -277,7 +349,7 @@ contract ReferenceOrderFulfiller is
_transfer(
receivedItem,
msg.sender,
- fractionData.fulfillerConduitKey,
+ fulfillerConduitKey,
accumulatorStruct
);
}
@@ -286,13 +358,11 @@ contract ReferenceOrderFulfiller is
// Trigger any remaining accumulated transfers via call to the conduit.
_triggerIfArmed(accumulatorStruct);
- // If any native token remains after fulfillments...
+ // If any native tokens remain after applying fulfillments...
if (address(this).balance != 0) {
- // return it to the caller.
+ // return them to the caller.
_transferNativeTokens(payable(msg.sender), address(this).balance);
}
- // Return the order to execute.
- return orderToExecute;
}
/**
diff --git a/reference/lib/ReferenceOrderValidator.sol b/reference/lib/ReferenceOrderValidator.sol
index ddbc0aa37..4c40b7ada 100644
--- a/reference/lib/ReferenceOrderValidator.sol
+++ b/reference/lib/ReferenceOrderValidator.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.13;
import {
OrderType,
ItemType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdvancedOrder,
@@ -16,7 +16,7 @@ import {
OrderStatus,
ReceivedItem,
SpentItem
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ReferenceExecutor } from "./ReferenceExecutor.sol";
@@ -24,13 +24,16 @@ import { ReferenceZoneInteraction } from "./ReferenceZoneInteraction.sol";
import {
ContractOffererInterface
-} from "../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
import {
ReferenceGenerateOrderReturndataDecoder
} from "./ReferenceGenerateOrderReturndataDecoder.sol";
-import { OrderToExecute } from "./ReferenceConsiderationStructs.sol";
+import {
+ OrderToExecute,
+ OrderValidation
+} from "./ReferenceConsiderationStructs.sol";
/**
* @title OrderValidator
@@ -97,9 +100,9 @@ contract ReferenceOrderValidator is
}
/**
- * @dev Internal function to validate an order, determine what portion to
- * fill, and update its status. The desired fill amount is supplied as
- * a fraction, as is the returned amount to fill.
+ * @dev Internal function to validate an order and determine what portion to
+ * fill. The desired fill amount is supplied as a fraction, as is the
+ * returned amount to fill.
*
* @param advancedOrder The order to fulfill as well as the fraction to
* fill. Note that all offer and consideration
@@ -108,23 +111,13 @@ contract ReferenceOrderValidator is
* @param revertOnInvalid A boolean indicating whether to revert if the
* order is invalid due to the time or order status.
*
- * @return orderHash The order hash.
- * @return newNumerator A value indicating the portion of the order that
- * will be filled.
- * @return newDenominator A value indicating the total size of the order.
+ * @return orderValidation The order validation details, including the fill
+ * amount.
*/
- function _validateOrderAndUpdateStatus(
+ function _validateOrder(
AdvancedOrder memory advancedOrder,
bool revertOnInvalid
- )
- internal
- returns (
- bytes32 orderHash,
- uint256 newNumerator,
- uint256 newDenominator,
- OrderToExecute memory orderToExecute
- )
- {
+ ) internal view returns (OrderValidation memory orderValidation) {
// Retrieve the parameters for the order.
OrderParameters memory orderParameters = advancedOrder.parameters;
@@ -137,12 +130,13 @@ contract ReferenceOrderValidator is
)
) {
// Assuming an invalid time and no revert, return zeroed out values.
- return (
- bytes32(0),
- 0,
- 0,
- _convertAdvancedToOrder(orderParameters, 0)
- );
+ return
+ OrderValidation(
+ bytes32(0),
+ 0,
+ 0,
+ _convertAdvancedToOrder(orderParameters, 0)
+ );
}
// Read numerator and denominator from memory and place on the stack.
@@ -157,10 +151,11 @@ contract ReferenceOrderValidator is
}
return
- _getGeneratedOrder(
- orderParameters,
- advancedOrder.extraData,
- revertOnInvalid
+ OrderValidation(
+ bytes32(uint256(1)),
+ 1,
+ 1,
+ _convertAdvancedToOrder(orderParameters, 1)
);
}
@@ -180,34 +175,40 @@ contract ReferenceOrderValidator is
}
// Retrieve current counter and use it w/ parameters to get order hash.
- orderHash = _assertConsiderationLengthAndGetOrderHash(orderParameters);
+ orderValidation.orderHash = (
+ _assertConsiderationLengthAndGetOrderHash(orderParameters)
+ );
// Retrieve the order status using the derived order hash.
- OrderStatus storage orderStatus = _orderStatus[orderHash];
+ OrderStatus storage orderStatus = (
+ _orderStatus[orderValidation.orderHash]
+ );
// Ensure order is fillable and is not cancelled.
if (
+ // Allow partially used orders to be filled.
!_verifyOrderStatus(
- orderHash,
+ orderValidation.orderHash,
orderStatus,
- false, // Allow partially used orders to be filled.
+ false,
revertOnInvalid
)
) {
// Assuming an invalid order status and no revert, return zero fill.
- return (
- orderHash,
- 0,
- 0,
- _convertAdvancedToOrder(orderParameters, 0)
- );
+ return
+ OrderValidation(
+ orderValidation.orderHash,
+ 0,
+ 0,
+ _convertAdvancedToOrder(orderParameters, 0)
+ );
}
// If the order is not already validated, verify the supplied signature.
if (!orderStatus.isValidated) {
_verifySignature(
orderParameters.offerer,
- orderHash,
+ orderValidation.orderHash,
advancedOrder.signature
);
}
@@ -263,6 +264,91 @@ contract ReferenceOrderValidator is
uint256 maxOverhead = type(uint256).max - type(uint120).max;
((filledNumerator + maxOverhead) & (denominator + maxOverhead));
}
+ }
+
+ // Return order hash, new numerator and denominator.
+ return
+ OrderValidation(
+ orderValidation.orderHash,
+ uint120(numerator),
+ uint120(denominator),
+ _convertAdvancedToOrder(orderParameters, uint120(numerator))
+ );
+ }
+
+ /**
+ * @dev Internal function to update an order's status.
+ *
+ * @param orderHash The hash of the order.
+ * @param numerator The numerator of the fraction to fill.
+ * @param denominator The denominator of the fraction to fill.
+ * @param revertOnInvalid Whether to revert on invalid input.
+ *
+ * @return valid A boolean indicating whether the order is valid.
+ */
+ function _updateStatus(
+ bytes32 orderHash,
+ uint256 numerator,
+ uint256 denominator,
+ bool revertOnInvalid
+ ) internal returns (bool valid) {
+ if (numerator == 0) {
+ return false;
+ }
+
+ // Retrieve the order status using the provided order hash.
+ OrderStatus storage orderStatus = _orderStatus[orderHash];
+
+ // Read filled amount as numerator and denominator and put on the stack.
+ uint256 filledNumerator = uint256(orderStatus.numerator);
+ uint256 filledDenominator = uint256(orderStatus.denominator);
+
+ // If order currently has a non-zero denominator it is partially filled.
+ if (filledDenominator != 0) {
+ // if supplied denominator differs from current one...
+ if (filledDenominator != denominator) {
+ // scale current numerator by the supplied denominator, then...
+ filledNumerator *= denominator;
+
+ // the supplied numerator & denominator by current denominator.
+ numerator *= filledDenominator;
+ denominator *= filledDenominator;
+ }
+
+ // Once adjusted, if current+supplied numerator exceeds
+ // denominator...
+ if (filledNumerator + numerator > denominator) {
+ // Revert or return false, which indicates that the order is
+ // invalid.
+ if (revertOnInvalid) {
+ revert OrderAlreadyFilled(orderHash);
+ } else {
+ return false;
+ }
+ }
+
+ // Increment the filled numerator by the new numerator.
+ filledNumerator += numerator;
+
+ // Ensure fractional amounts are below max uint120.
+ if (
+ filledNumerator > type(uint120).max ||
+ denominator > type(uint120).max
+ ) {
+ // Derive greatest common divisor using euclidean algorithm.
+ uint256 scaleDown = _greatestCommonDivisor(
+ filledNumerator,
+ denominator
+ );
+
+ // Scale new filled fractional values down by gcd.
+ filledNumerator = filledNumerator / scaleDown;
+ denominator = denominator / scaleDown;
+
+ // Perform the overflow check a second time.
+ uint256 maxOverhead = type(uint256).max - type(uint120).max;
+ ((filledNumerator + maxOverhead) & (denominator + maxOverhead));
+ }
// Update order status and fill amount, packing struct values.
orderStatus.isValidated = true;
@@ -270,20 +356,16 @@ contract ReferenceOrderValidator is
orderStatus.numerator = uint120(filledNumerator);
orderStatus.denominator = uint120(denominator);
} else {
- // Update order status and fill amount, packing struct values.
+ // If the order currently has a zero denominator, it is not
+ // partially filled. Update the order status and fill amount,
+ // packing struct values.
orderStatus.isValidated = true;
orderStatus.isCancelled = false;
orderStatus.numerator = uint120(numerator);
orderStatus.denominator = uint120(denominator);
}
- // Return order hash, new numerator and denominator.
- return (
- orderHash,
- uint120(numerator),
- uint120(denominator),
- _convertAdvancedToOrder(orderParameters, uint120(numerator))
- );
+ return true;
}
function _callGenerateOrder(
@@ -315,27 +397,19 @@ contract ReferenceOrderValidator is
* identifierOrCriteria = 0, Seaport does not expect a corresponding
* CriteriaResolver, and will revert if one is provided.
*
+ * @param orderToExecute The order to execute.
* @param orderParameters The parameters for the order.
* @param context The context for generating the order.
* @param revertOnInvalid Whether to revert on invalid input.
*
* @return orderHash The order hash.
- * @return numerator The numerator.
- * @return denominator The denominator.
*/
function _getGeneratedOrder(
+ OrderToExecute memory orderToExecute,
OrderParameters memory orderParameters,
bytes memory context,
bool revertOnInvalid
- )
- internal
- returns (
- bytes32 orderHash,
- uint256 numerator,
- uint256 denominator,
- OrderToExecute memory orderToExecute
- )
- {
+ ) internal returns (bytes32 orderHash) {
// Ensure that consideration array length is equal to the total original
// consideration items value.
if (
@@ -346,13 +420,10 @@ contract ReferenceOrderValidator is
}
// Convert offer and consideration to spent and received items.
- (
- SpentItem[] memory originalOfferItems,
- SpentItem[] memory originalConsiderationItems
- ) = _convertToSpent(
- orderParameters.offer,
- orderParameters.consideration
- );
+ SpentItem[] memory originalOfferItems = orderToExecute.spentItems;
+ SpentItem[] memory originalConsiderationItems = _convertToSpent(
+ orderToExecute.receivedItems
+ );
// Create arrays for returned offer and consideration items.
SpentItem[] memory offer;
@@ -401,13 +472,15 @@ contract ReferenceOrderValidator is
}
} else {
// If the call fails, revert or return empty.
- return _revertOrReturnEmpty(revertOnInvalid, orderHash);
+ (orderHash, orderToExecute) = _revertOrReturnEmpty(
+ revertOnInvalid,
+ orderHash
+ );
+ return orderHash;
}
}
{
- orderToExecute = _convertAdvancedToOrder(orderParameters, 1);
-
// Designate lengths.
uint256 originalOfferLength = orderParameters.offer.length;
uint256 newOfferLength = offer.length;
@@ -415,50 +488,13 @@ contract ReferenceOrderValidator is
// Explicitly specified offer items cannot be removed.
if (originalOfferLength > newOfferLength) {
revert InvalidContractOrder(orderHash);
- } else if (newOfferLength > originalOfferLength) {
- {
- // If new offer items are added, extend the original offer.
- OfferItem[] memory extendedOffer = new OfferItem[](
- newOfferLength
- );
- // Copy original offer items to new array.
- for (uint256 i = 0; i < originalOfferLength; ++i) {
- extendedOffer[i] = orderParameters.offer[i];
- }
- // Update order parameters with extended offer.
- orderParameters.offer = extendedOffer;
- }
- {
- // Do the same for ordersToExecute arrays.
- SpentItem[] memory extendedSpent = new SpentItem[](
- newOfferLength
- );
- uint256[]
- memory extendedSpentItemOriginalAmounts = new uint256[](
- newOfferLength
- );
-
- // Copy original spent items to new array.
- for (uint256 i = 0; i < originalOfferLength; ++i) {
- extendedSpent[i] = orderToExecute.spentItems[i];
- extendedSpentItemOriginalAmounts[i] = orderToExecute
- .spentItemOriginalAmounts[i];
- }
-
- // Update order to execute with extended items.
- orderToExecute.spentItems = extendedSpent;
- orderToExecute
- .spentItemOriginalAmounts = extendedSpentItemOriginalAmounts;
- }
-
- {}
}
// Loop through each new offer and ensure the new amounts are at
// least as much as the respective original amounts.
for (uint256 i = 0; i < originalOfferLength; ++i) {
// Designate original and new offer items.
- OfferItem memory originalOffer = orderParameters.offer[i];
+ SpentItem memory originalOffer = orderToExecute.spentItems[i];
SpentItem memory newOffer = offer[i];
// Set returned identifier for criteria-based items with
@@ -469,55 +505,40 @@ contract ReferenceOrderValidator is
// CriteriaResolver.
if (
uint256(originalOffer.itemType) > 3 &&
- originalOffer.identifierOrCriteria == 0
+ originalOffer.identifier == 0
) {
originalOffer.itemType = ItemType(
uint256(originalOffer.itemType) - 2
);
- originalOffer.identifierOrCriteria = newOffer.identifier;
+ originalOffer.identifier = newOffer.identifier;
}
// Ensure the original and generated items are compatible.
if (
- originalOffer.startAmount != originalOffer.endAmount ||
- originalOffer.endAmount > newOffer.amount ||
+ originalOffer.amount > newOffer.amount ||
originalOffer.itemType != newOffer.itemType ||
originalOffer.token != newOffer.token ||
- originalOffer.identifierOrCriteria != newOffer.identifier
+ originalOffer.identifier != newOffer.identifier
) {
revert InvalidContractOrder(orderHash);
}
-
- // Update the original amounts to use the generated amounts.
- originalOffer.startAmount = newOffer.amount;
- originalOffer.endAmount = newOffer.amount;
- orderToExecute.spentItems[i].amount = newOffer.amount;
- orderToExecute.spentItemOriginalAmounts[i] = newOffer.amount;
}
- // Add new offer items if there are more than original.
- for (uint256 i = originalOfferLength; i < newOfferLength; ++i) {
- OfferItem memory originalOffer = orderParameters.offer[i];
- SpentItem memory newOffer = offer[i];
+ orderToExecute.spentItems = offer;
+ orderToExecute.spentItemOriginalAmounts = new uint256[](
+ offer.length
+ );
- originalOffer.itemType = newOffer.itemType;
- originalOffer.token = newOffer.token;
- originalOffer.identifierOrCriteria = newOffer.identifier;
- originalOffer.startAmount = newOffer.amount;
- originalOffer.endAmount = newOffer.amount;
-
- orderToExecute.spentItems[i].itemType = newOffer.itemType;
- orderToExecute.spentItems[i].token = newOffer.token;
- orderToExecute.spentItems[i].identifier = newOffer.identifier;
- orderToExecute.spentItems[i].amount = newOffer.amount;
- orderToExecute.spentItemOriginalAmounts[i] = newOffer.amount;
+ // Add new offer items if there are more than original.
+ for (uint256 i = 0; i < offer.length; ++i) {
+ orderToExecute.spentItemOriginalAmounts[i] = offer[i].amount;
}
}
{
// Designate lengths & memory locations.
- ConsiderationItem[] memory originalConsiderationArray = (
- orderParameters.consideration
+ ReceivedItem[] memory originalConsiderationArray = (
+ orderToExecute.receivedItems
);
uint256 newConsiderationLength = consideration.length;
@@ -529,32 +550,31 @@ contract ReferenceOrderValidator is
// Loop through and check consideration.
for (uint256 i = 0; i < newConsiderationLength; ++i) {
ReceivedItem memory newConsideration = consideration[i];
- ConsiderationItem memory originalConsideration = (
+ ReceivedItem memory originalConsideration = (
originalConsiderationArray[i]
);
if (
uint256(originalConsideration.itemType) > 3 &&
- originalConsideration.identifierOrCriteria == 0
+ originalConsideration.identifier == 0
) {
originalConsideration.itemType = ItemType(
uint256(originalConsideration.itemType) - 2
);
- originalConsideration
- .identifierOrCriteria = newConsideration.identifier;
+ originalConsideration.identifier = (
+ newConsideration.identifier
+ );
}
// All fields must match the originally supplied fields except
// for the amount (which may be reduced by the contract offerer)
// and the recipient if some non-zero address has been provided.
if (
- originalConsideration.startAmount !=
- originalConsideration.endAmount ||
- newConsideration.amount > originalConsideration.endAmount ||
+ newConsideration.amount > originalConsideration.amount ||
originalConsideration.itemType !=
newConsideration.itemType ||
originalConsideration.token != newConsideration.token ||
- originalConsideration.identifierOrCriteria !=
+ originalConsideration.identifier !=
newConsideration.identifier ||
(originalConsideration.recipient != address(0) &&
originalConsideration.recipient !=
@@ -562,66 +582,23 @@ contract ReferenceOrderValidator is
) {
revert InvalidContractOrder(orderHash);
}
-
- // Update the original amounts to use the generated amounts.
- originalConsideration.startAmount = newConsideration.amount;
- originalConsideration.endAmount = newConsideration.amount;
- originalConsideration.recipient = newConsideration.recipient;
-
- orderToExecute.receivedItems[i].amount = newConsideration
- .amount;
- orderToExecute.receivedItems[i].recipient = newConsideration
- .recipient;
- orderToExecute.receivedItemOriginalAmounts[i] = newConsideration
- .amount;
- }
-
- {
- // Shorten original consideration array if longer than new array.
- ConsiderationItem[] memory shortenedConsiderationArray = (
- new ConsiderationItem[](newConsiderationLength)
- );
-
- // Iterate over original consideration array and copy to new.
- for (uint256 i = 0; i < newConsiderationLength; ++i) {
- shortenedConsiderationArray[i] = originalConsiderationArray[
- i
- ];
- }
-
- // Replace original consideration array with new shortend array.
- orderParameters.consideration = shortenedConsiderationArray;
}
- {
- ReceivedItem[] memory shortenedReceivedItems = (
- new ReceivedItem[](newConsiderationLength)
- );
-
- // Iterate over original consideration array and copy to new.
- for (uint256 i = 0; i < newConsiderationLength; ++i) {
- shortenedReceivedItems[i] = orderToExecute.receivedItems[i];
- }
-
- orderToExecute.receivedItems = shortenedReceivedItems;
- }
- uint256[]
- memory shortenedReceivedItemOriginalAmounts = new uint256[](
- newConsiderationLength
- );
+ orderToExecute.receivedItems = consideration;
+ orderToExecute.receivedItemOriginalAmounts = new uint256[](
+ consideration.length
+ );
// Iterate over original consideration array and copy to new.
- for (uint256 i = 0; i < newConsiderationLength; ++i) {
- shortenedReceivedItemOriginalAmounts[i] = orderToExecute
- .receivedItemOriginalAmounts[i];
+ for (uint256 i = 0; i < consideration.length; ++i) {
+ orderToExecute.receivedItemOriginalAmounts[i] = (
+ consideration[i].amount
+ );
}
-
- orderToExecute
- .receivedItemOriginalAmounts = shortenedReceivedItemOriginalAmounts;
}
- // Return the order hash, the numerator, and the denominator.
- return (orderHash, 1, 1, orderToExecute);
+ // Return the order hash.
+ return orderHash;
}
/**
@@ -822,8 +799,6 @@ contract ReferenceOrderValidator is
* @param contractOrderHash The contract order hash.
*
* @return orderHash The order hash.
- * @return numerator The numerator.
- * @return denominator The denominator.
*/
function _revertOrReturnEmpty(
bool revertOnInvalid,
@@ -831,18 +806,13 @@ contract ReferenceOrderValidator is
)
internal
pure
- returns (
- bytes32 orderHash,
- uint256 numerator,
- uint256 denominator,
- OrderToExecute memory emptyOrder
- )
+ returns (bytes32 orderHash, OrderToExecute memory emptyOrder)
{
// If invalid input should not revert...
if (!revertOnInvalid) {
- // Return the contract order hash and zero values for the numerator
+ // Return no contract order hash and zero values for the numerator
// and denominator.
- return (contractOrderHash, 0, 0, emptyOrder);
+ return (bytes32(0), emptyOrder);
}
// Otherwise, revert.
@@ -850,60 +820,29 @@ contract ReferenceOrderValidator is
}
/**
- * @dev Internal pure function to convert both offer and consideration items
- * to spent items.
+ * @dev Internal pure function to convert received items to spent items.
*
- * @param offer The offer items to convert.
* @param consideration The consideration items to convert.
*
- * @return spentItems The converted spent items.
* @return receivedItems The converted received items.
*/
function _convertToSpent(
- OfferItem[] memory offer,
- ConsiderationItem[] memory consideration
- )
- internal
- pure
- returns (
- SpentItem[] memory spentItems,
- SpentItem[] memory receivedItems
- )
- {
- // Create an array of spent items equal to the offer length.
- spentItems = new SpentItem[](offer.length);
-
- // Iterate over each offer item on the order.
- for (uint256 i = 0; i < offer.length; ++i) {
- // Retrieve the offer item.
- OfferItem memory offerItem = offer[i];
-
- // Create spent item for event based on the offer item.
- SpentItem memory spentItem = SpentItem(
- offerItem.itemType,
- offerItem.token,
- offerItem.identifierOrCriteria,
- offerItem.startAmount
- );
-
- // Add to array of spent items.
- spentItems[i] = spentItem;
- }
-
+ ReceivedItem[] memory consideration
+ ) internal pure returns (SpentItem[] memory receivedItems) {
// Create an array of received items equal to the consideration length.
receivedItems = new SpentItem[](consideration.length);
- // Iterate over each consideration item on the order.
+ // Iterate over each received item on the order.
for (uint256 i = 0; i < consideration.length; ++i) {
// Retrieve the consideration item.
- ConsiderationItem memory considerationItem = (consideration[i]);
+ ReceivedItem memory considerationItem = (consideration[i]);
// Create spent item for event based on the consideration item.
SpentItem memory receivedItem = SpentItem(
considerationItem.itemType,
considerationItem.token,
- considerationItem.identifierOrCriteria,
- considerationItem.startAmount
+ considerationItem.identifier,
+ considerationItem.amount
);
// Add to array of received items.
diff --git a/reference/lib/ReferenceReentrancyGuard.sol b/reference/lib/ReferenceReentrancyGuard.sol
index 7bb4052e7..d58dff14b 100644
--- a/reference/lib/ReferenceReentrancyGuard.sol
+++ b/reference/lib/ReferenceReentrancyGuard.sol
@@ -3,17 +3,17 @@ pragma solidity ^0.8.13;
import {
ConsiderationEventsAndErrors
-} from "../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import {
ReentrancyErrors
-} from "../../contracts/interfaces/ReentrancyErrors.sol";
+} from "seaport-types/src/interfaces/ReentrancyErrors.sol";
import {
- _ENTERED_AND_ACCEPTING_NATIVE_TOKENS,
- _ENTERED,
- _NOT_ENTERED
-} from "../../contracts/lib/ConsiderationConstants.sol";
+ _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE,
+ _ENTERED_SSTORE,
+ _NOT_ENTERED_SSTORE
+} from "seaport-types/src/lib/ConsiderationConstants.sol";
/**
* @title ReentrancyGuard
@@ -33,7 +33,7 @@ contract ReferenceReentrancyGuard is
*/
constructor() {
// Initialize the reentrancy guard in a cleared state.
- _reentrancyGuard = _NOT_ENTERED;
+ _reentrancyGuard = _NOT_ENTERED_SSTORE;
}
/**
@@ -41,7 +41,7 @@ contract ReferenceReentrancyGuard is
* is not currently set by a previous call.
*/
modifier notEntered() {
- if (_reentrancyGuard != _NOT_ENTERED) {
+ if (_reentrancyGuard != _NOT_ENTERED_SSTORE) {
revert NoReentrantCalls();
}
@@ -56,19 +56,19 @@ contract ReferenceReentrancyGuard is
* be received during execution or not.
*/
modifier nonReentrant(bool acceptNativeTokens) {
- if (_reentrancyGuard != _NOT_ENTERED) {
+ if (_reentrancyGuard != _NOT_ENTERED_SSTORE) {
revert NoReentrantCalls();
}
if (acceptNativeTokens) {
- _reentrancyGuard = _ENTERED_AND_ACCEPTING_NATIVE_TOKENS;
+ _reentrancyGuard = _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE;
} else {
- _reentrancyGuard = _ENTERED;
+ _reentrancyGuard = _ENTERED_SSTORE;
}
_;
- _reentrancyGuard = _NOT_ENTERED;
+ _reentrancyGuard = _NOT_ENTERED_SSTORE;
}
/**
@@ -77,7 +77,7 @@ contract ReferenceReentrancyGuard is
*/
function _assertAcceptingNativeTokens() internal view {
// Ensure that the reentrancy guard is not currently set.
- if (_reentrancyGuard != _ENTERED_AND_ACCEPTING_NATIVE_TOKENS) {
+ if (_reentrancyGuard != _ENTERED_AND_ACCEPTING_NATIVE_TOKENS_SSTORE) {
revert InvalidMsgValue(msg.value);
}
}
diff --git a/reference/lib/ReferenceSignatureVerification.sol b/reference/lib/ReferenceSignatureVerification.sol
index 1954dc23e..f2d923b77 100644
--- a/reference/lib/ReferenceSignatureVerification.sol
+++ b/reference/lib/ReferenceSignatureVerification.sol
@@ -3,15 +3,15 @@ pragma solidity ^0.8.13;
import {
EIP1271Interface
-} from "../../contracts/interfaces/EIP1271Interface.sol";
+} from "seaport-types/src/interfaces/EIP1271Interface.sol";
import {
SignatureVerificationErrors
-} from "../../contracts/interfaces/SignatureVerificationErrors.sol";
+} from "seaport-types/src/interfaces/SignatureVerificationErrors.sol";
import {
EIP2098_allButHighestBitMask
-} from "../../contracts/lib/ConsiderationConstants.sol";
+} from "seaport-types/src/lib/ConsiderationConstants.sol";
/**
* @title SignatureVerification
diff --git a/reference/lib/ReferenceTokenTransferrer.sol b/reference/lib/ReferenceTokenTransferrer.sol
index 054220474..e0192faa6 100644
--- a/reference/lib/ReferenceTokenTransferrer.sol
+++ b/reference/lib/ReferenceTokenTransferrer.sol
@@ -5,11 +5,11 @@ import {
ERC20Interface,
ERC721Interface,
ERC1155Interface
-} from "../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
TokenTransferrerErrors
-} from "../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
contract ReferenceTokenTransferrer is TokenTransferrerErrors {
/**
diff --git a/reference/lib/ReferenceVerifiers.sol b/reference/lib/ReferenceVerifiers.sol
index 9874e070b..e478500b3 100644
--- a/reference/lib/ReferenceVerifiers.sol
+++ b/reference/lib/ReferenceVerifiers.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { OrderStatus } from "../../contracts/lib/ConsiderationStructs.sol";
+import { OrderStatus } from "seaport-types/src/lib/ConsiderationStructs.sol";
import { ReferenceAssertions } from "./ReferenceAssertions.sol";
diff --git a/reference/lib/ReferenceZoneInteraction.sol b/reference/lib/ReferenceZoneInteraction.sol
index f314017ee..c205d5e76 100644
--- a/reference/lib/ReferenceZoneInteraction.sol
+++ b/reference/lib/ReferenceZoneInteraction.sol
@@ -1,16 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ZoneInterface } from "../../contracts/interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
import {
ContractOffererInterface
-} from "../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
import {
ItemType,
OrderType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdditionalRecipient,
@@ -19,13 +19,13 @@ import {
ReceivedItem,
SpentItem,
ZoneParameters
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { OrderToExecute } from "./ReferenceConsiderationStructs.sol";
import {
ZoneInteractionErrors
-} from "../../contracts/interfaces/ZoneInteractionErrors.sol";
+} from "seaport-types/src/interfaces/ZoneInteractionErrors.sol";
/**
* @title ZoneInteraction
@@ -33,6 +33,56 @@ import {
* @notice ZoneInteraction contains logic related to interacting with zones.
*/
contract ReferenceZoneInteraction is ZoneInteractionErrors {
+ function _assertRestrictedBasicOrderAuthorization(
+ bytes32 orderHash,
+ OrderType orderType,
+ BasicOrderParameters calldata basicOrderParameters,
+ ItemType offeredItemType,
+ ItemType receivedItemType
+ ) internal {
+ // Create a new array for the hash.
+ bytes32[] memory orderHashes = new bytes32[](0);
+
+ // Convert the order params and types to spent and received items.
+ (
+ SpentItem[] memory offer,
+ ReceivedItem[] memory consideration
+ ) = _convertToSpentAndReceivedItems(
+ basicOrderParameters,
+ offeredItemType,
+ receivedItemType
+ );
+
+ // Order types 2-3 require zone or offerer be caller or zone to approve.
+ // Note that in cases where fulfiller == zone, the restricted order
+ // validation will be skipped.
+ if (
+ (orderType == OrderType.FULL_RESTRICTED ||
+ orderType == OrderType.PARTIAL_RESTRICTED) &&
+ msg.sender != basicOrderParameters.zone
+ ) {
+ // Validate the order with the zone.
+ if (
+ ZoneInterface(basicOrderParameters.zone).authorizeOrder(
+ ZoneParameters({
+ orderHash: orderHash,
+ fulfiller: msg.sender,
+ offerer: basicOrderParameters.offerer,
+ offer: offer,
+ consideration: consideration,
+ extraData: "",
+ orderHashes: orderHashes,
+ startTime: basicOrderParameters.startTime,
+ endTime: basicOrderParameters.endTime,
+ zoneHash: basicOrderParameters.zoneHash
+ })
+ ) != ZoneInterface.authorizeOrder.selector
+ ) {
+ revert InvalidRestrictedOrder(orderHash);
+ }
+ }
+ }
+
/**
* @dev Internal view function to determine if an order has a restricted
* order type and, if so, to ensure that either the offerer or the zone
@@ -65,7 +115,7 @@ contract ReferenceZoneInteraction is ZoneInteractionErrors {
receivedItemType
);
- // Order type 2-3 require zone or offerer be caller or zone to approve.
+ // Order types 2-3 require zone or offerer be caller or zone to approve.
// Note that in cases where fulfiller == zone, the restricted order
// validation will be skipped.
if (
@@ -95,6 +145,128 @@ contract ReferenceZoneInteraction is ZoneInteractionErrors {
}
}
+ /**
+ * @dev Internal function to check if a restricted advanced order is
+ * authorized by its zone or offerer, in cases where the caller is not
+ * the zone or offerer.
+ *
+ * @param advancedOrder The advanced order in question.
+ * @param orderToExecute The order to execute.
+ * @param orderHashes The order hashes of each order supplied
+ * alongside the current order as part of a
+ "match" or "fulfill available" variety of
+ order fulfillment.
+ * @param orderHash The hash of the order to execute.
+ * @param revertOnUnauthorized A boolean indicating whether the function
+ * should revert if the order is invalid.
+ *
+ * @return authorized A boolean indicating whether the order is
+ * authorized by the zone or offerer.
+ * @return checked A boolean indicating whether the order has
+ * been checked for authorization.
+ */
+ function _checkRestrictedAdvancedOrderAuthorization(
+ AdvancedOrder memory advancedOrder,
+ OrderToExecute memory orderToExecute,
+ bytes32[] memory orderHashes,
+ bytes32 orderHash,
+ bool revertOnUnauthorized
+ ) internal returns (bool authorized, bool checked) {
+ // Order types 2-3 require zone or offerer be caller or zone to approve.
+ if (
+ (advancedOrder.parameters.orderType == OrderType.FULL_RESTRICTED ||
+ advancedOrder.parameters.orderType ==
+ OrderType.PARTIAL_RESTRICTED) &&
+ msg.sender != advancedOrder.parameters.zone
+ ) {
+ // Authorize the order.
+ try
+ ZoneInterface(advancedOrder.parameters.zone).authorizeOrder(
+ ZoneParameters({
+ orderHash: orderHash,
+ fulfiller: msg.sender,
+ offerer: advancedOrder.parameters.offerer,
+ offer: orderToExecute.spentItems,
+ consideration: orderToExecute.receivedItems,
+ extraData: advancedOrder.extraData,
+ orderHashes: orderHashes,
+ startTime: advancedOrder.parameters.startTime,
+ endTime: advancedOrder.parameters.endTime,
+ zoneHash: advancedOrder.parameters.zoneHash
+ })
+ )
+ returns (bytes4 selector) {
+ if (selector != ZoneInterface.authorizeOrder.selector) {
+ revert InvalidRestrictedOrder(orderHash);
+ }
+
+ return (true, true);
+ } catch {
+ if (revertOnUnauthorized) {
+ revert InvalidRestrictedOrder(orderHash);
+ }
+
+ return (false, false);
+ }
+ } else {
+ return (true, false);
+ }
+ }
+
+ /**
+ * @dev Internal function to validate that a restricted advanced order is
+ * authorized by its zone or offerer, in cases where the caller is not
+ * the zone or offerer.
+ *
+ * @param advancedOrder The advanced order in question.
+ * @param orderToExecute The order to execute.
+ * @param orderHashes The order hashes of each order supplied
+ * alongside the current order as part of a
+ "match" or "fulfill available" variety of
+ order fulfillment.
+ * @param orderHash The hash of the order to execute.
+ * @param zoneHash The hash to provide upon calling the zone.
+ * @param orderType The type of the order.
+ * @param offerer The offerer in question.
+ * @param zone The zone in question.
+ */
+ function _assertRestrictedAdvancedOrderAuthorization(
+ AdvancedOrder memory advancedOrder,
+ OrderToExecute memory orderToExecute,
+ bytes32[] memory orderHashes,
+ bytes32 orderHash,
+ bytes32 zoneHash,
+ OrderType orderType,
+ address offerer,
+ address zone
+ ) internal {
+ // Order types 2-3 require zone or offerer be caller or zone to approve.
+ if (
+ (orderType == OrderType.FULL_RESTRICTED ||
+ orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != zone
+ ) {
+ // Authorize the order.
+ if (
+ ZoneInterface(zone).authorizeOrder(
+ ZoneParameters({
+ orderHash: orderHash,
+ fulfiller: msg.sender,
+ offerer: offerer,
+ offer: orderToExecute.spentItems,
+ consideration: orderToExecute.receivedItems,
+ extraData: advancedOrder.extraData,
+ orderHashes: orderHashes,
+ startTime: advancedOrder.parameters.startTime,
+ endTime: advancedOrder.parameters.endTime,
+ zoneHash: zoneHash
+ })
+ ) != ZoneInterface.authorizeOrder.selector
+ ) {
+ revert InvalidRestrictedOrder(orderHash);
+ }
+ }
+ }
+
/**
* @dev Internal view function to determine if a proxy should be utilized
* for a given order and to ensure that the submitter is allowed by the
@@ -120,7 +292,7 @@ contract ReferenceZoneInteraction is ZoneInteractionErrors {
address offerer,
address zone
) internal {
- // Order type 2-3 require zone or offerer be caller or zone to approve.
+ // Order types 2-3 require zone or offerer be caller or zone to approve.
if (
(orderType == OrderType.FULL_RESTRICTED ||
orderType == OrderType.PARTIAL_RESTRICTED) && msg.sender != zone
diff --git a/reference/shim/Shim.sol b/reference/shim/Shim.sol
index f26b4b4af..852807362 100644
--- a/reference/shim/Shim.sol
+++ b/reference/shim/Shim.sol
@@ -45,7 +45,7 @@ import {
import { ConduitMock } from "../../contracts/test/ConduitMock.sol";
import {
ImmutableCreate2FactoryInterface
-} from "../../contracts/interfaces/ImmutableCreate2FactoryInterface.sol";
+} from "seaport-types/src/interfaces/ImmutableCreate2FactoryInterface.sol";
import {
TestTransferValidationZoneOfferer
diff --git a/script/CallNavigator.s.sol b/script/CallNavigator.s.sol
new file mode 100644
index 000000000..826be66c5
--- /dev/null
+++ b/script/CallNavigator.s.sol
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.4;
+
+import "forge-std/Script.sol";
+
+import {
+ ConsiderationInterface,
+ NavigatorRequest,
+ SeaportNavigatorInterface,
+ SeaportValidatorInterface
+} from "../contracts/helpers/navigator/SeaportNavigator.sol";
+
+import {
+ NavigatorAdvancedOrder,
+ NavigatorConsiderationItem,
+ NavigatorOfferItem,
+ NavigatorOrderParameters
+} from "../contracts/helpers/navigator/lib/SeaportNavigatorTypes.sol";
+
+import {
+ AggregationStrategy,
+ FulfillAvailableStrategy,
+ FulfillmentStrategy,
+ MatchStrategy
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
+
+import { OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+contract CallNavigator is Script {
+ address private constant GOERLI_NAVIGATOR =
+ 0x76093Af4C8330D69676d920d550d9901110792D5;
+
+ function run() public view {
+ // Create an empty request.
+ NavigatorRequest memory request;
+
+ // Set Seaport and SeaportValidator addresses.
+ request.seaport = ConsiderationInterface(
+ 0x00000000000000ADc04C56Bf30aC9d3c0aAF14dC
+ );
+ request.validator = SeaportValidatorInterface(
+ 0xBa7a3AD8aDD5D37a89a73d76e9Fb4270aeD264Ad
+ );
+
+ // Set up orders, using navigator order structs.
+ NavigatorAdvancedOrder[] memory orders = new NavigatorAdvancedOrder[](
+ 1
+ );
+ orders[0] = NavigatorAdvancedOrder({
+ parameters: NavigatorOrderParameters({
+ offerer: 0xcc476d5Adc341B31405891E78694186454775926,
+ zone: address(0),
+ offer: new NavigatorOfferItem[](0),
+ consideration: new NavigatorConsiderationItem[](0),
+ orderType: OrderType.FULL_OPEN,
+ startTime: 1686684156,
+ endTime: 1686687756,
+ zoneHash: bytes32(0),
+ salt: uint256(
+ 0x10a16a76000000000000000000000000000000000000000000000000af0f8c13
+ ),
+ conduitKey: bytes32(0),
+ totalOriginalConsiderationItems: 0
+ }),
+ numerator: 1,
+ denominator: 1,
+ signature: (
+ hex"3c792711cff5e3b9ca789b3fc08f345d069ca3f161d0a3b3e2700ad95c"
+ hex"691c6c8079a4c12149a9834797d50a4c0856cc11430bdd28bcf02b0798"
+ hex"7aefb6d21ab2"
+ ),
+ extraData: ""
+ });
+ request.orders = orders;
+
+ // Set up call context data
+ request.caller = 0xcc476d5Adc341B31405891E78694186454775926;
+ request.recipient = 0xcc476d5Adc341B31405891E78694186454775926;
+ request.maximumFulfilled = 1;
+
+ // Set fulfillment parameters
+ request.fulfillmentStrategy = FulfillmentStrategy(
+ AggregationStrategy.MAXIMUM,
+ FulfillAvailableStrategy.KEEP_ALL,
+ MatchStrategy.MAX_INCLUSION
+ );
+ request.preferMatch = true;
+
+ // Call the navigator with the configured request.
+ SeaportNavigatorInterface(GOERLI_NAVIGATOR).prepare(request);
+ }
+}
diff --git a/script/NavigatorDeployer.s.sol b/script/NavigatorDeployer.s.sol
new file mode 100644
index 000000000..b6927d6c1
--- /dev/null
+++ b/script/NavigatorDeployer.s.sol
@@ -0,0 +1,217 @@
+// SPDX-License-Identifier: UNLICENSED
+pragma solidity ^0.8.4;
+
+import "forge-std/Script.sol";
+
+import "forge-std/console.sol";
+
+import { LibString } from "solady/src/utils/LibString.sol";
+
+import {
+ CriteriaHelper
+} from "../contracts/helpers/navigator/lib/CriteriaHelper.sol";
+
+import {
+ ExecutionsHelper
+} from "../contracts/helpers/navigator/lib/ExecutionsHelper.sol";
+
+import {
+ FulfillmentsHelper
+} from "../contracts/helpers/navigator/lib/FulfillmentsHelper.sol";
+
+import {
+ OrderDetailsHelper
+} from "../contracts/helpers/navigator/lib/OrderDetailsHelper.sol";
+
+import {
+ ReadOnlyOrderValidator
+} from "../contracts/helpers/order-validator/lib/ReadOnlyOrderValidator.sol";
+
+import {
+ RequestValidator
+} from "../contracts/helpers/navigator/lib/RequestValidator.sol";
+
+import {
+ SeaportNavigator
+} from "../contracts/helpers/navigator/SeaportNavigator.sol";
+
+import {
+ SeaportValidator
+} from "../contracts/helpers/order-validator/SeaportValidator.sol";
+
+import {
+ SeaportValidatorHelper
+} from "../contracts/helpers/order-validator/lib/SeaportValidatorHelper.sol";
+
+import {
+ SuggestedActionHelper
+} from "../contracts/helpers/navigator/lib/SuggestedActionHelper.sol";
+
+import {
+ ValidatorHelper
+} from "../contracts/helpers/navigator/lib/ValidatorHelper.sol";
+
+interface ImmutableCreate2Factory {
+ function hasBeenDeployed(
+ address deploymentAddress
+ ) external view returns (bool);
+
+ function findCreate2Address(
+ bytes32 salt,
+ bytes calldata initializationCode
+ ) external view returns (address deploymentAddress);
+
+ function safeCreate2(
+ bytes32 salt,
+ bytes calldata initializationCode
+ ) external payable returns (address deploymentAddress);
+}
+
+contract NavigatorDeployer is Script {
+ // Set up the immutable create2 factory and conduit controller addresses.
+ ImmutableCreate2Factory private constant IMMUTABLE_CREATE2_FACTORY =
+ ImmutableCreate2Factory(0x0000000000FFe8B47B3e2130213B802212439497);
+ address private constant CONDUIT_CONTROLLER =
+ 0x00000000F9490004C11Cef243f5400493c00Ad63;
+
+ // Set up the default salt and the salt for the seaport validator and
+ // navigator.
+ bytes32 private constant DEFAULT_SALT = bytes32(uint256(0x1));
+ bytes32 private constant SEAPORT_VALIDATOR_SALT =
+ bytes32(uint256(0x459b42ee5b5e5000d96491ce));
+ bytes32 private constant SEAPORT_NAVIGATOR_SALT =
+ bytes32(uint256(0x9237ec96f90d12013e58e484));
+
+ function run() public {
+ console.log(
+ pad("State", 10),
+ pad("Name", 23),
+ pad("Address", 43),
+ "Initcode hash"
+ );
+
+ // Deploy the helpers, seaport validator, and navigator.
+ vm.startBroadcast();
+ address seaportValidatorHelper = deploy(
+ "SeaportValidatorHelper",
+ type(SeaportValidatorHelper).creationCode
+ );
+ address readOnlyOrderValidator = deploy(
+ "ReadOnlyOrderValidator",
+ type(ReadOnlyOrderValidator).creationCode
+ );
+ deploy(
+ "SeaportValidator",
+ SEAPORT_VALIDATOR_SALT,
+ bytes.concat(
+ type(SeaportValidator).creationCode,
+ abi.encode(
+ readOnlyOrderValidator,
+ seaportValidatorHelper,
+ CONDUIT_CONTROLLER
+ )
+ )
+ );
+
+ address requestValidator = deploy(
+ "RequestValidator",
+ type(RequestValidator).creationCode
+ );
+ address criteriaHelper = deploy(
+ "CriteriaHelper",
+ type(CriteriaHelper).creationCode
+ );
+ address validatorHelper = deploy(
+ "ValidatorHelper",
+ type(ValidatorHelper).creationCode
+ );
+ address orderDetailsHelper = deploy(
+ "OrderDetailsHelper",
+ type(OrderDetailsHelper).creationCode
+ );
+ address fulfillmentsHelper = deploy(
+ "FulfillmentsHelper",
+ type(FulfillmentsHelper).creationCode
+ );
+ address suggestedActionHelper = deploy(
+ "SuggestedActionHelper",
+ type(SuggestedActionHelper).creationCode
+ );
+ address executionsHelper = deploy(
+ "ExecutionsHelper",
+ type(ExecutionsHelper).creationCode
+ );
+
+ deploy(
+ "SeaportNavigator",
+ SEAPORT_NAVIGATOR_SALT,
+ bytes.concat(
+ type(SeaportNavigator).creationCode,
+ abi.encode(
+ requestValidator,
+ criteriaHelper,
+ validatorHelper,
+ orderDetailsHelper,
+ fulfillmentsHelper,
+ suggestedActionHelper,
+ executionsHelper
+ )
+ )
+ );
+ }
+
+ function deploy(
+ string memory name,
+ bytes memory initCode
+ ) internal returns (address) {
+ return deploy(name, DEFAULT_SALT, initCode);
+ }
+
+ function deploy(
+ string memory name,
+ bytes32 salt,
+ bytes memory initCode
+ ) internal returns (address) {
+ bytes32 initCodeHash = keccak256(initCode);
+ address deploymentAddress = address(
+ uint160(
+ uint256(
+ keccak256(
+ abi.encodePacked(
+ hex"ff",
+ address(IMMUTABLE_CREATE2_FACTORY),
+ salt,
+ initCodeHash
+ )
+ )
+ )
+ )
+ );
+ bool deploying;
+ if (!IMMUTABLE_CREATE2_FACTORY.hasBeenDeployed(deploymentAddress)) {
+ deploymentAddress = IMMUTABLE_CREATE2_FACTORY.safeCreate2(
+ salt,
+ initCode
+ );
+ deploying = true;
+ }
+ console.log(
+ pad(deploying ? "Deploying" : "Found", 10),
+ pad(name, 23),
+ pad(LibString.toHexString(deploymentAddress), 43),
+ LibString.toHexString(uint256(initCodeHash))
+ );
+ return deploymentAddress;
+ }
+
+ function pad(
+ string memory name,
+ uint256 n
+ ) internal pure returns (string memory) {
+ string memory padded = name;
+ while (bytes(padded).length < n) {
+ padded = string.concat(padded, " ");
+ }
+ return padded;
+ }
+}
diff --git a/script/SeaportDeployer.s.sol b/script/SeaportDeployer.s.sol
index d9ebbe154..47de26924 100644
--- a/script/SeaportDeployer.s.sol
+++ b/script/SeaportDeployer.s.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.4;
import "forge-std/Script.sol";
-import { Seaport } from "contracts/Seaport.sol";
+import { Seaport } from "seaport-core/src/Seaport.sol";
interface ImmutableCreate2Factory {
function safeCreate2(
diff --git a/test/advanced.spec.ts b/test/advanced.spec.ts
index 45b445ba3..32783c7e7 100644
--- a/test/advanced.spec.ts
+++ b/test/advanced.spec.ts
@@ -1,7 +1,7 @@
import { PANIC_CODES } from "@nomicfoundation/hardhat-chai-matchers/panic";
import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
-import { constants } from "ethers";
+import { BigNumber, constants } from "ethers";
import { ethers, network } from "hardhat";
import { deployContract } from "./utils/contracts";
@@ -577,9 +577,9 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
) as any,
];
- // ERC1155 criteria based item
- offer[0].itemType = 5;
- offer[0].identifier = offer[0].identifierOrCriteria;
+ // ERC1155 criteria based item (resolved)
+ offer[0].itemType = 3;
+ offer[0].identifier = nftId;
offer[0].amount = offer[0].endAmount;
consideration[0].identifier = consideration[0].identifierOrCriteria;
@@ -587,7 +587,11 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
await offererContract
.connect(seller)
- .activateWithCriteria(offer[0], consideration[0], nftId);
+ .activate(offer[0], consideration[0]);
+
+ // ERC1155 criteria based item (unresolved)
+ offer[0].itemType = 5;
+ offer[0].identifier = offer[0].identifierOrCriteria;
const criteriaResolvers = [
buildResolver(0, 0, 0, nftId, proofs[nftId.toString()]),
@@ -1188,87 +1192,6 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
return receipt;
});
});
- it("Reverts on contract orders where offer startAmount doesn't equal offer endAmount", async () => {
- // Seller mints nfts
- const { nftId, amount } = await mintAndApprove1155(
- seller,
- marketplaceContract.address,
- 10000
- );
-
- // seller deploys offererContract and approves it for 1155 token
- const offererContract = await deployContract(
- "TestContractOfferer",
- owner,
- marketplaceContract.address
- );
-
- await set1155ApprovalForAll(seller, offererContract.address, true);
-
- const offer = [
- getTestItem1155(nftId, amount.mul(10), amount.mul(10)) as any,
- ];
-
- const consideration = [
- getItemETH(
- amount.mul(1000),
- amount.mul(1000),
- offererContract.address
- ) as any,
- ];
-
- offer[0].identifier = offer[0].identifierOrCriteria;
- offer[0].amount = offer[0].endAmount;
- offer[0].startAmount = offer[0].endAmount.add(1);
-
- consideration[0].identifier = consideration[0].identifierOrCriteria;
- consideration[0].amount = consideration[0].endAmount;
-
- await offererContract
- .connect(seller)
- .activate(offer[0], consideration[0]);
-
- const { order, value } = await createOrder(
- seller,
- zone,
- offer,
- consideration,
- 4 // CONTRACT
- );
-
- const contractOffererNonce =
- await marketplaceContract.getContractOffererNonce(
- offererContract.address
- );
-
- const orderHash =
- offererContract.address.toLowerCase() +
- contractOffererNonce.toHexString().slice(2).padStart(24, "0");
-
- const orderStatus = await marketplaceContract.getOrderStatus(orderHash);
-
- expect({ ...orderStatus }).to.deep.equal(
- buildOrderStatus(false, false, 0, 0)
- );
-
- order.parameters.offerer = offererContract.address;
- order.numerator = 1;
- order.denominator = 1;
- order.signature = "0x";
-
- await expect(
- marketplaceContract
- .connect(buyer)
- .fulfillAdvancedOrder(order, [], toKey(0), buyer.address, {
- value,
- })
- )
- .to.be.revertedWithCustomError(
- marketplaceContract,
- "InvalidContractOrder"
- )
- .withArgs(orderHash);
- });
it("Reverts on contract orders where offer endAmount is greater than offer amount (branch 2)", async () => {
// Seller mints nfts
const { nftId, amount } = await mintAndApprove1155(
@@ -1600,87 +1523,6 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
)
.withArgs(orderHash);
});
- it("Reverts on contract orders where consideration startAmount doesn't equal consideration endAmount", async () => {
- // Seller mints nfts
- const { nftId, amount } = await mintAndApprove1155(
- seller,
- marketplaceContract.address,
- 10000
- );
-
- // seller deploys offererContract and approves it for 1155 token
- const offererContract = await deployContract(
- "TestContractOfferer",
- owner,
- marketplaceContract.address
- );
-
- await set1155ApprovalForAll(seller, offererContract.address, true);
-
- const offer = [
- getTestItem1155(nftId, amount.mul(10), amount.mul(10)) as any,
- ];
-
- const consideration = [
- getItemETH(
- amount.mul(1000),
- amount.mul(1000),
- offererContract.address
- ) as any,
- ];
-
- offer[0].identifier = offer[0].identifierOrCriteria;
- offer[0].amount = offer[0].endAmount;
-
- consideration[0].identifier = consideration[0].identifierOrCriteria;
- consideration[0].amount = consideration[0].endAmount;
- consideration[0].startAmount = consideration[0].endAmount.add(1);
-
- await offererContract
- .connect(seller)
- .activate(offer[0], consideration[0]);
-
- const { order, value } = await createOrder(
- seller,
- zone,
- offer,
- consideration,
- 4 // CONTRACT
- );
-
- const contractOffererNonce =
- await marketplaceContract.getContractOffererNonce(
- offererContract.address
- );
-
- const orderHash =
- offererContract.address.toLowerCase() +
- contractOffererNonce.toHexString().slice(2).padStart(24, "0");
-
- const orderStatus = await marketplaceContract.getOrderStatus(orderHash);
-
- expect({ ...orderStatus }).to.deep.equal(
- buildOrderStatus(false, false, 0, 0)
- );
-
- order.parameters.offerer = offererContract.address;
- order.numerator = 1;
- order.denominator = 1;
- order.signature = "0x";
-
- await expect(
- marketplaceContract
- .connect(buyer)
- .fulfillAdvancedOrder(order, [], toKey(0), buyer.address, {
- value,
- })
- )
- .to.be.revertedWithCustomError(
- marketplaceContract,
- "InvalidContractOrder"
- )
- .withArgs(orderHash);
- });
it("Reverts on contract orders where consideration itemType is different from generated itemType", async () => {
// Seller mints nfts
const { nftId, amount } = await mintAndApprove1155(
@@ -2783,12 +2625,7 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
.fulfillAdvancedOrder(order, [], toKey(0), buyer.address, {
value,
})
- )
- .to.be.revertedWithCustomError(
- marketplaceContract,
- "InvalidContractOrder"
- )
- .withArgs(orderHash);
+ ).to.be.reverted; // TODO: get revert message bubbled up from the offerer
});
it("Reverts on contract orders where call to generateOrders throws and reverts are skipped", async () => {
// Seller mints nfts
@@ -3633,7 +3470,7 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
orderStatus = await marketplaceContract.getOrderStatus(orderHash);
expect({ ...orderStatus }).to.deep.equal(
- buildOrderStatus(true, false, 14, 20)
+ buildOrderStatus(true, false, 140, 200)
);
// Fill remaining; only 3/10ths will be fillable
@@ -3697,7 +3534,7 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
orderStatus = await marketplaceContract.getOrderStatus(orderHash);
expect({ ...orderStatus }).to.deep.equal(
- buildOrderStatus(true, false, 40, 40)
+ buildOrderStatus(true, false, 80000, 80000)
);
});
it("Partial fills (standard, additional permutations)", async () => {
@@ -4056,8 +3893,8 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
});
it("Simplifies fraction when numerator/denominator would overflow", async () => {
- const numer1 = toBN(2).pow(100);
- const denom1 = toBN(2).pow(101);
+ const numer1 = toBN(2).pow(50);
+ const denom1 = toBN(2).pow(51);
const numer2 = toBN(2).pow(20);
const denom2 = toBN(2).pow(22);
const amt = 8;
@@ -5795,136 +5632,6 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
executions
);
});
- it("Match with fewer executions when one party has multiple orders that coincide", async () => {
- const nftId = await mintAndApprove721(
- seller,
- marketplaceContract.address
- );
- const secondNFTId = await mintAndApprove721(
- buyer,
- marketplaceContract.address
- );
-
- const offerOne = [
- getTestItem721(nftId, toBN(1), toBN(1), undefined, testERC721.address),
- ];
-
- const considerationOne = [
- getTestItem20(parseEther("10"), parseEther("10"), seller.address),
- ];
-
- const { order: orderOne, orderHash: orderHashOne } = await createOrder(
- seller,
- zone,
- offerOne,
- considerationOne,
- 0 // FULL_OPEN
- );
-
- const offerTwo = [getTestItem20(parseEther("10"), parseEther("10"))];
-
- const considerationTwo = [
- getTestItem721(
- secondNFTId,
- toBN(1),
- toBN(1),
- seller.address,
- testERC721.address
- ),
- ];
-
- const { order: orderTwo, orderHash: orderHashTwo } = await createOrder(
- seller,
- zone,
- offerTwo,
- considerationTwo,
- 0 // FULL_OPEN
- );
-
- const offerThree = [
- getTestItem721(
- secondNFTId,
- toBN(1),
- toBN(1),
- undefined,
- testERC721.address
- ),
- ];
-
- const considerationThree = [
- getTestItem721(
- nftId,
- toBN(1),
- toBN(1),
- buyer.address,
- testERC721.address
- ),
- ];
-
- const { order: orderThree, orderHash: orderHashThree } =
- await createOrder(
- buyer,
- zone,
- offerThree,
- considerationThree,
- 0 // FULL_OPEN
- );
-
- const fulfillments = [
- [[[1, 0]], [[0, 0]]],
- [[[0, 0]], [[2, 0]]],
- [[[2, 0]], [[1, 0]]],
- ].map(([offerArr, considerationArr]) =>
- toFulfillment(offerArr, considerationArr)
- );
-
- const executions = await simulateAdvancedMatchOrders(
- marketplaceContract,
- [orderOne, orderTwo, orderThree],
- [], // no criteria resolvers
- fulfillments,
- owner,
- 0 // no value
- );
-
- expect(executions.length).to.equal(fulfillments.length - 1);
-
- const tx = marketplaceContract
- .connect(owner)
- .matchAdvancedOrders(
- [orderOne, orderTwo, orderThree],
- [],
- fulfillments,
- ethers.constants.AddressZero,
- {
- value: 0,
- }
- );
- const receipt = await (await tx).wait();
- await checkExpectedEvents(
- tx,
- receipt,
- [
- {
- order: orderOne,
- orderHash: orderHashOne,
- fulfiller: owner.address,
- },
- {
- order: orderTwo,
- orderHash: orderHashTwo,
- fulfiller: owner.address,
- },
- {
- order: orderThree,
- orderHash: orderHashThree,
- fulfiller: owner.address,
- },
- ],
- executions
- );
- return receipt;
- });
it("Does not filter native tokens", async () => {
const nftId = await mintAndApprove721(
seller,
@@ -6772,7 +6479,7 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
value
);
- expect(executions.length).to.equal(6);
+ expect(executions.length).to.equal(7);
const tx = marketplaceContract
.connect(owner)
@@ -6795,7 +6502,9 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
fulfiller: owner.address,
},
],
- executions
+ executions.filter((execution: any) =>
+ BigNumber.from(execution.item.amount).gt(0)
+ )
);
return receipt;
});
@@ -6860,7 +6569,7 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
value
);
- expect(executions.length).to.equal(6);
+ expect(executions.length).to.equal(8);
const tx = marketplaceContract
.connect(owner)
@@ -6883,7 +6592,9 @@ describe(`Advanced orders (Seaport v${VERSION})`, function () {
fulfiller: owner.address,
},
],
- executions
+ executions.filter((execution: any) =>
+ BigNumber.from(execution.item.amount).gt(0)
+ )
);
return receipt;
});
diff --git a/test/findings/AdditionalRecipientsOffByOne.spec.ts b/test/findings/AdditionalRecipientsOffByOne.spec.ts
index 3e89ee365..8a503173b 100644
--- a/test/findings/AdditionalRecipientsOffByOne.spec.ts
+++ b/test/findings/AdditionalRecipientsOffByOne.spec.ts
@@ -1,5 +1,5 @@
import { expect } from "chai";
-import { constants } from "ethers";
+import { Contract, constants } from "ethers";
import { hexZeroPad } from "ethers/lib/utils";
import { network } from "hardhat";
import { getScuffedContract } from "scuffed-abi";
@@ -175,61 +175,70 @@ describe("Additional recipients off by one error allows skipping second consider
let maliciousCallData: string;
before(async () => {
- // True Parameters
- const basicOrderParameters = getBasicOrderParameters(
- 2, // ERC20ForERC721
- order
- );
+ if (!process.env.REFERENCE) {
+ // True Parameters
+ const basicOrderParameters = getBasicOrderParameters(
+ 2, // ERC20ForERC721
+ order
+ );
- basicOrderParameters.additionalRecipients = [];
- basicOrderParameters.signature = basicOrderParameters.signature
- .slice(0, 66)
- .concat(hexZeroPad("0x", 96).slice(2));
- const scuffedContract = getScuffedContract(marketplaceContract);
- const scuffed = scuffedContract.fulfillBasicOrder({
- parameters: basicOrderParameters,
- });
- scuffed.parameters.signature.length.replace(100);
- scuffed.parameters.signature.tail.replace(carol.address);
-
- maliciousCallData = scuffed.encode();
+ basicOrderParameters.additionalRecipients = [];
+ basicOrderParameters.signature = basicOrderParameters.signature
+ .slice(0, 66)
+ .concat(hexZeroPad("0x", 96).slice(2));
+ const abi =
+ require("../../artifacts/seaport-types/src/interfaces/ConsiderationInterface.sol/ConsiderationInterface.json")
+ .abi as any;
+ const scuffedContract = getScuffedContract(
+ new Contract(marketplaceContract.address, abi, bob)
+ );
+ const scuffed = scuffedContract.fulfillBasicOrder({
+ parameters: basicOrderParameters,
+ });
+ scuffed.parameters.signature.length.replace(100);
+ scuffed.parameters.signature.tail.replace(carol.address);
+
+ maliciousCallData = scuffed.encode();
+ }
});
- if (!IS_FIXED) {
- it("Bob fulfills Alice's order using maliciously constructed calldata", async () => {
- await expect(
- bob.sendTransaction({
- to: marketplaceContract.address,
- data: maliciousCallData,
- })
- ).to.emit(marketplaceContract, "OrderFulfilled");
- });
-
- it("Bob receives Alice's NFT, having paid 1000 DAI", async () => {
- expect(await testERC721.ownerOf(1)).to.equal(bob.address);
- expect(await testERC20.balanceOf(bob.address)).to.equal(100);
- });
-
- it("Alice receives 1000 DAI", async () => {
- expect(await testERC20.balanceOf(alice.address)).to.equal(1000);
- });
-
- it("Carol does not receive her DAI", async () => {
- expect(await testERC20.balanceOf(carol.address)).to.equal(0);
- });
- } else {
- it("Bob attempts to fulfill Alice's order with malicious calldata, but the transaction reverts", async () => {
- await expect(
- bob.sendTransaction({
- to: marketplaceContract.address,
- data: maliciousCallData,
- gasLimit: 29_999_999,
- })
- ).to.be.revertedWithCustomError(
- marketplaceContract,
- "MissingOriginalConsiderationItems"
- );
- });
+ if (!process.env.REFERENCE) {
+ if (!IS_FIXED) {
+ it("Bob fulfills Alice's order using maliciously constructed calldata", async () => {
+ await expect(
+ bob.sendTransaction({
+ to: marketplaceContract.address,
+ data: maliciousCallData,
+ })
+ ).to.emit(marketplaceContract, "OrderFulfilled");
+ });
+
+ it("Bob receives Alice's NFT, having paid 1000 DAI", async () => {
+ expect(await testERC721.ownerOf(1)).to.equal(bob.address);
+ expect(await testERC20.balanceOf(bob.address)).to.equal(100);
+ });
+
+ it("Alice receives 1000 DAI", async () => {
+ expect(await testERC20.balanceOf(alice.address)).to.equal(1000);
+ });
+
+ it("Carol does not receive her DAI", async () => {
+ expect(await testERC20.balanceOf(carol.address)).to.equal(0);
+ });
+ } else {
+ it("Bob attempts to fulfill Alice's order with malicious calldata, but the transaction reverts", async () => {
+ await expect(
+ bob.sendTransaction({
+ to: marketplaceContract.address,
+ data: maliciousCallData,
+ gasLimit: 29_999_999,
+ })
+ ).to.be.revertedWithCustomError(
+ marketplaceContract,
+ "MissingOriginalConsiderationItems"
+ );
+ });
+ }
}
});
});
diff --git a/test/foundry/BulkSignature.t.sol b/test/foundry/BulkSignature.t.sol
index 0e667eff4..3a32dae37 100644
--- a/test/foundry/BulkSignature.t.sol
+++ b/test/foundry/BulkSignature.t.sol
@@ -7,7 +7,7 @@ import { EIP712MerkleTree } from "./utils/EIP712MerkleTree.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
ConsiderationItem,
@@ -16,9 +16,9 @@ import {
OrderComponents,
OrderParameters,
OrderType
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
contract BulkSignatureTest is BaseOrderTest {
OrderComponents private _empty;
diff --git a/test/foundry/ConsiderationErrors.t.sol b/test/foundry/ConsiderationErrors.t.sol
index 35e375d52..f418eea30 100644
--- a/test/foundry/ConsiderationErrors.t.sol
+++ b/test/foundry/ConsiderationErrors.t.sol
@@ -7,7 +7,7 @@ import {
ConsiderationErrorsWrapper
} from "./utils/ConsiderationErrorsWrapper.sol";
-import { Side } from "../../contracts/lib/ConsiderationEnums.sol";
+import { Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
contract ConsiderationErrors is BaseOrderTest, ConsiderationErrorsWrapper {
address someAddress;
@@ -114,18 +114,6 @@ contract ConsiderationErrors is BaseOrderTest, ConsiderationErrorsWrapper {
this.__revertInvalidTime(6, 7);
}
- function test_revertMismatchedFulfillmentOfferAndConsiderationComponents()
- public
- {
- vm.expectRevert(
- abi.encodeWithSignature(
- "MismatchedFulfillmentOfferAndConsiderationComponents(uint256)",
- 8
- )
- );
- this.__revertMismatchedFulfillmentOfferAndConsiderationComponents(8);
- }
-
function test_revertMissingOriginalConsiderationItems() public {
vm.expectRevert(
abi.encodeWithSignature("MissingOriginalConsiderationItems()")
@@ -145,15 +133,6 @@ contract ConsiderationErrors is BaseOrderTest, ConsiderationErrorsWrapper {
this.__revertNoSpecifiedOrdersAvailable();
}
- function test_revertOfferAndConsiderationRequiredOnFulfillment() public {
- vm.expectRevert(
- abi.encodeWithSignature(
- "OfferAndConsiderationRequiredOnFulfillment()"
- )
- );
- this.__revertOfferAndConsiderationRequiredOnFulfillment();
- }
-
function test_revertOrderAlreadyFilled() public {
vm.expectRevert(
abi.encodeWithSignature("OrderAlreadyFilled(bytes32)", someBytes32)
@@ -195,28 +174,6 @@ contract ConsiderationErrors is BaseOrderTest, ConsiderationErrorsWrapper {
this.__revertPartialFillsNotEnabledForOrder();
}
- function test_revertUnresolvedConsiderationCriteria() public {
- vm.expectRevert(
- abi.encodeWithSignature(
- "UnresolvedConsiderationCriteria(uint256,uint256)",
- 9,
- 10
- )
- );
- this.__revertUnresolvedConsiderationCriteria(9, 10);
- }
-
- function test_revertUnresolvedOfferCriteria() public {
- vm.expectRevert(
- abi.encodeWithSignature(
- "UnresolvedOfferCriteria(uint256,uint256)",
- 11,
- 12
- )
- );
- this.__revertUnresolvedOfferCriteria(11, 12);
- }
-
function test_revertUnusedItemParameters() public {
vm.expectRevert(abi.encodeWithSignature("UnusedItemParameters()"));
this.__revertUnusedItemParameters();
diff --git a/test/foundry/ConstantsTest.t.sol b/test/foundry/ConstantsTest.t.sol
index e3706856b..fe01757e8 100644
--- a/test/foundry/ConstantsTest.t.sol
+++ b/test/foundry/ConstantsTest.t.sol
@@ -44,59 +44,59 @@ import {
UnresolvedConsiderationCriteria_error_selector,
UnresolvedOfferCriteria_error_selector,
UnusedItemParameters_error_selector
-} from "../../contracts/lib/ConsiderationErrorConstants.sol";
+} from "seaport-types/src/lib/ConsiderationErrorConstants.sol";
import {
BadReturnValueFromERC20OnTransfer_error_selector,
NoContract_error_selector,
TokenTransferGenericFailure_error_selector
-} from "../../contracts/lib/TokenTransferrerConstants.sol";
+} from "seaport-types/src/lib/TokenTransferrerConstants.sol";
import {
generateOrder_selector,
ratifyOrder_selector,
validateOrder_selector
-} from "../../contracts/lib/ConsiderationConstants.sol";
+} from "seaport-types/src/lib/ConsiderationConstants.sol";
import { BaseConsiderationTest } from "./utils/BaseConsiderationTest.sol";
import {
FulfillmentApplicationErrors
-} from "../../contracts/interfaces/FulfillmentApplicationErrors.sol";
+} from "seaport-types/src/interfaces/FulfillmentApplicationErrors.sol";
import {
AmountDerivationErrors
-} from "../../contracts/interfaces/AmountDerivationErrors.sol";
+} from "seaport-types/src/interfaces/AmountDerivationErrors.sol";
import {
CriteriaResolutionErrors
-} from "../../contracts/interfaces/CriteriaResolutionErrors.sol";
+} from "seaport-types/src/interfaces/CriteriaResolutionErrors.sol";
import {
ZoneInteractionErrors
-} from "../../contracts/interfaces/ZoneInteractionErrors.sol";
+} from "seaport-types/src/interfaces/ZoneInteractionErrors.sol";
import {
SignatureVerificationErrors
-} from "../../contracts/interfaces/SignatureVerificationErrors.sol";
+} from "seaport-types/src/interfaces/SignatureVerificationErrors.sol";
import {
TokenTransferrerErrors
-} from "../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
import {
ReentrancyErrors
-} from "../../contracts/interfaces/ReentrancyErrors.sol";
+} from "seaport-types/src/interfaces/ReentrancyErrors.sol";
import {
ConsiderationEventsAndErrors
-} from "../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import {
ContractOffererInterface
-} from "../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ZoneInterface } from "../../contracts/interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
contract ConstantsTest is BaseConsiderationTest {
function _test(uint256 _constant, bytes4 selector) public {
diff --git a/test/foundry/FulfillAdvancedOrder.t.sol b/test/foundry/FulfillAdvancedOrder.t.sol
index 2c45cdde0..abfccbbfb 100644
--- a/test/foundry/FulfillAdvancedOrder.t.sol
+++ b/test/foundry/FulfillAdvancedOrder.t.sol
@@ -1,28 +1,27 @@
// SPDX-License-Identifier: MIT
-
pragma solidity ^0.8.17;
import {
OrderType,
ItemType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
AdvancedOrder,
OrderParameters,
OrderComponents,
CriteriaResolver
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
import {
ConsiderationEventsAndErrors
-} from "../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import { ArithmeticUtil } from "./utils/ArithmeticUtil.sol";
@@ -33,6 +32,7 @@ contract FulfillAdvancedOrder is BaseOrderTest {
using ArithmeticUtil for uint8;
FuzzInputs empty;
+
struct FuzzInputs {
uint256 tokenId;
address zone;
@@ -532,7 +532,7 @@ contract FulfillAdvancedOrder is BaseOrderTest {
address(0)
);
- // Assert six-tenths of the order has been fulfilled.
+ // Assert three-fifths of the order has been fulfilled.
{
(
bool isValidated,
@@ -542,9 +542,9 @@ contract FulfillAdvancedOrder is BaseOrderTest {
) = context.consideration.getOrderStatus(orderHash);
assertTrue(isValidated);
assertFalse(isCancelled);
- assertEq(totalFilled, 6);
+ assertEq(totalFilled, 3);
- assertEq(totalSize, 10);
+ assertEq(totalSize, 5);
assertEq(60, test1155_1.balanceOf(address(this), 1));
}
}
diff --git a/test/foundry/FulfillAdvancedOrderCriteria.t.sol b/test/foundry/FulfillAdvancedOrderCriteria.t.sol
index 94a60c08f..dfbfd3c23 100644
--- a/test/foundry/FulfillAdvancedOrderCriteria.t.sol
+++ b/test/foundry/FulfillAdvancedOrderCriteria.t.sol
@@ -8,16 +8,16 @@ import { Merkle } from "murky/Merkle.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
CriteriaResolver,
OfferItem,
OrderComponents,
AdvancedOrder
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType, Side } from "../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
contract FulfillAdvancedOrderCriteria is BaseOrderTest {
Merkle merkle = new Merkle();
diff --git a/test/foundry/FulfillAvailableAdvancedOrder.t.sol b/test/foundry/FulfillAvailableAdvancedOrder.t.sol
index 0c036a99d..4efa707e1 100644
--- a/test/foundry/FulfillAvailableAdvancedOrder.t.sol
+++ b/test/foundry/FulfillAvailableAdvancedOrder.t.sol
@@ -5,11 +5,11 @@ pragma solidity ^0.8.17;
import {
OrderType,
ItemType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
AdvancedOrder,
@@ -19,7 +19,7 @@ import {
OrderComponents,
FulfillmentComponent,
CriteriaResolver
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
@@ -1080,7 +1080,7 @@ contract FulfillAvailableAdvancedOrder is BaseOrderTest {
100
);
- // Assert six-tenths of the offer has been fulfilled.
+ // Assert three-fifths of the offer has been fulfilled.
{
(
bool isValidated,
@@ -1090,9 +1090,9 @@ contract FulfillAvailableAdvancedOrder is BaseOrderTest {
) = context.consideration.getOrderStatus(orderHash);
assertTrue(isValidated);
assertFalse(isCancelled);
- assertEq(totalFilled, 6);
+ assertEq(totalFilled, 3);
- assertEq(totalSize, 10);
+ assertEq(totalSize, 5);
assertEq(60, test1155_1.balanceOf(address(this), 1));
}
}
@@ -1185,7 +1185,7 @@ contract FulfillAvailableAdvancedOrder is BaseOrderTest {
100
);
- // Assert six-tenths of the offer has been fulfilled.
+ // Assert three-fifths of the offer has been fulfilled.
{
(
bool isValidated,
@@ -1195,9 +1195,9 @@ contract FulfillAvailableAdvancedOrder is BaseOrderTest {
) = context.consideration.getOrderStatus(orderHash);
assertTrue(isValidated);
assertFalse(isCancelled);
- assertEq(totalFilled, 6);
+ assertEq(totalFilled, 3);
- assertEq(totalSize, 10);
+ assertEq(totalSize, 5);
assertEq(60, test1155_1.balanceOf(address(this), 1));
}
}
diff --git a/test/foundry/FulfillAvailableAdvancedOrderCriteria.t.sol b/test/foundry/FulfillAvailableAdvancedOrderCriteria.t.sol
index 7b77befd4..c20a226fd 100644
--- a/test/foundry/FulfillAvailableAdvancedOrderCriteria.t.sol
+++ b/test/foundry/FulfillAvailableAdvancedOrderCriteria.t.sol
@@ -8,7 +8,7 @@ import { Merkle } from "murky/Merkle.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
CriteriaResolver,
@@ -16,9 +16,9 @@ import {
OrderComponents,
AdvancedOrder,
FulfillmentComponent
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType, Side } from "../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
contract FulfillAdvancedOrderCriteria is BaseOrderTest {
Merkle merkle = new Merkle();
diff --git a/test/foundry/FulfillBasicOrderTest.t.sol b/test/foundry/FulfillBasicOrderTest.t.sol
index 6a3fa1824..32e27503d 100644
--- a/test/foundry/FulfillBasicOrderTest.t.sol
+++ b/test/foundry/FulfillBasicOrderTest.t.sol
@@ -4,18 +4,18 @@ pragma solidity ^0.8.17;
import {
OrderType,
BasicOrderType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
AdditionalRecipient,
Order,
OrderComponents,
BasicOrderParameters
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
@@ -33,7 +33,7 @@ import { ArithmeticUtil } from "./utils/ArithmeticUtil.sol";
import {
ConsiderationEventsAndErrors
-} from "../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
contract FulfillBasicOrderTest is BaseOrderTest, ConsiderationEventsAndErrors {
using ArithmeticUtil for uint128;
@@ -52,6 +52,7 @@ contract FulfillBasicOrderTest is BaseOrderTest, ConsiderationEventsAndErrors {
uint256 salt;
bool useConduit;
}
+
struct Context {
ConsiderationInterface consideration;
FuzzInputsCommon args;
diff --git a/test/foundry/FulfillOrderTest.t.sol b/test/foundry/FulfillOrderTest.t.sol
index ce1aa0eb2..5d89226d5 100644
--- a/test/foundry/FulfillOrderTest.t.sol
+++ b/test/foundry/FulfillOrderTest.t.sol
@@ -3,21 +3,21 @@
pragma solidity ^0.8.17;
import {
- OrderType,
- ItemType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+ ItemType,
+ OrderType
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
- Order,
- OfferItem,
- OrderParameters,
ConsiderationItem,
- OrderComponents
-} from "../../contracts/lib/ConsiderationStructs.sol";
+ OfferItem,
+ Order,
+ OrderComponents,
+ OrderParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
@@ -34,6 +34,7 @@ contract FulfillOrderTest is BaseOrderTest {
uint256 badIdentifier;
address badToken;
+
struct FuzzInputsCommon {
address zone;
uint128 id;
@@ -2551,6 +2552,10 @@ contract FulfillOrderTest is BaseOrderTest {
function fulfillOrderRevertCounterIncremented(
Context memory context
) external stateless {
+ // Roll to a high block to get a blockhash that's high enough to produce
+ // a non-0 value when right shifted by 128 bits.
+ vm.roll(type(uint248).max);
+
test1155_1.mint(bob, 1, 1);
addErc1155OfferItem(1, 1);
addEthConsiderationItem(payable(bob), 1);
diff --git a/test/foundry/FullfillAvailableOrder.t.sol b/test/foundry/FullfillAvailableOrder.t.sol
index 729f97ca7..5ac128d7a 100644
--- a/test/foundry/FullfillAvailableOrder.t.sol
+++ b/test/foundry/FullfillAvailableOrder.t.sol
@@ -5,11 +5,11 @@ pragma solidity ^0.8.17;
import {
OrderType,
ItemType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
Order,
@@ -18,7 +18,7 @@ import {
ConsiderationItem,
OrderComponents,
FulfillmentComponent
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
@@ -33,6 +33,7 @@ contract FulfillAvailableOrder is BaseOrderTest {
using ArithmeticUtil for uint120;
FuzzInputs empty;
+
struct FuzzInputs {
address zone;
uint256 id;
diff --git a/test/foundry/GetterTests.t.sol b/test/foundry/GetterTests.t.sol
index 83563d8aa..8570d4406 100644
--- a/test/foundry/GetterTests.t.sol
+++ b/test/foundry/GetterTests.t.sol
@@ -41,7 +41,7 @@ contract TestGetters is BaseConsiderationTest {
function testGetsCorrectVersion() public {
(string memory version, , ) = consideration.information();
- assertEq(version, "1.5");
+ assertEq(version, "1.6");
}
function testGetCorrectDomainSeparator() public {
diff --git a/test/foundry/MatchAdvancedOrder.t.sol b/test/foundry/MatchAdvancedOrder.t.sol
index b0576a585..a2e3a0de3 100644
--- a/test/foundry/MatchAdvancedOrder.t.sol
+++ b/test/foundry/MatchAdvancedOrder.t.sol
@@ -5,11 +5,11 @@ pragma solidity ^0.8.17;
import {
OrderType,
ItemType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
AdvancedOrder,
@@ -19,7 +19,7 @@ import {
OrderComponents,
CriteriaResolver,
FulfillmentComponent
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
@@ -42,6 +42,7 @@ contract MatchAdvancedOrder is BaseOrderTest {
uint128 amount;
bool useConduit;
}
+
struct FuzzInputsAscendingDescending {
address zone;
uint256 id;
@@ -54,11 +55,13 @@ contract MatchAdvancedOrder is BaseOrderTest {
bool useConduit;
uint256 warp;
}
+
struct Context {
ConsiderationInterface consideration;
FuzzInputs args;
ItemType itemType;
}
+
struct ContextAscendingDescending {
ConsiderationInterface consideration;
FuzzInputsAscendingDescending args;
diff --git a/test/foundry/MatchAdvancedOrderUnspentOffer.t.sol b/test/foundry/MatchAdvancedOrderUnspentOffer.t.sol
index b2e42c293..80f19dad4 100644
--- a/test/foundry/MatchAdvancedOrderUnspentOffer.t.sol
+++ b/test/foundry/MatchAdvancedOrderUnspentOffer.t.sol
@@ -2,13 +2,13 @@
pragma solidity ^0.8.17;
-import { ItemType } from "../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
-import { Order } from "../../contracts/lib/ConsiderationStructs.sol";
+import { Order } from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
AdvancedOrder,
@@ -16,7 +16,7 @@ import {
ConsiderationItem,
CriteriaResolver,
Fulfillment
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
@@ -40,25 +40,6 @@ contract MatchOrderUnspentOfferTest is BaseOrderTest {
}
}
- /**
- * @dev test that specifying the offerer as the recipient of the considerationItem results in
- * execution filtering for items not specified in the matched order(s)
- * ie: offer nft1, nft2 for erc20
- * fulfiller matches to erc20 offer, nft1 consideration
- * specifies original offerer as recipient of unspent considerations
- * fulfilling does not result in nft2 being transferred at all
- */
- function testFilterOfferItemBySpecifyingOffererAsRecipient() public {
- test(
- this.execFilterOfferItemBySpecifyingOffererAsRecipient,
- Context({ seaport: consideration })
- );
- test(
- this.execFilterOfferItemBySpecifyingOffererAsRecipient,
- Context({ seaport: referenceConsideration })
- );
- }
-
function setUpFilterOfferItemBySpecifyingOffererAsRecipient(
Context memory context
) internal returns (AdvancedOrder[] memory, Fulfillment[] memory) {
@@ -170,34 +151,6 @@ contract MatchOrderUnspentOfferTest is BaseOrderTest {
return (orders, _fulfillments);
}
- function execFilterOfferItemBySpecifyingOffererAsRecipient(
- Context memory context
- ) external stateless {
- (
- AdvancedOrder[] memory orders,
- Fulfillment[] memory _fulfillments
- ) = setUpFilterOfferItemBySpecifyingOffererAsRecipient(context);
- vm.recordLogs();
- context.seaport.matchAdvancedOrders({
- orders: orders,
- criteriaResolvers: new CriteriaResolver[](0),
- fulfillments: _fulfillments,
- recipient: makeAddr("offerer")
- });
- Vm.Log[] memory recordedLogs = vm.getRecordedLogs();
- // ensure that token2 was not transferred at any point
- assertEq(recordedLogs.length, 5);
- // first two are OrderFulfilled events
- assertEq(recordedLogs[0].emitter, address(context.seaport));
- assertEq(recordedLogs[1].emitter, address(context.seaport));
- // next is OrdersMatched event
- assertEq(recordedLogs[2].emitter, address(context.seaport));
- // next is 721_1 transfer
- assertEq(recordedLogs[3].emitter, address(test721_1));
- // last is ERC20 transfer
- assertEq(recordedLogs[4].emitter, address(token1));
- }
-
// TODO: look into sporadic failures here
function xtestSweepRemaining() public {
test(this.execSweepRemaining, Context({ seaport: consideration }));
diff --git a/test/foundry/MatchOrders.t.sol b/test/foundry/MatchOrders.t.sol
index dd46422a2..c42f099a7 100644
--- a/test/foundry/MatchOrders.t.sol
+++ b/test/foundry/MatchOrders.t.sol
@@ -5,18 +5,18 @@ pragma solidity ^0.8.17;
import {
OrderType,
ItemType
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
Order,
OrderParameters,
OrderComponents,
FulfillmentComponent
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
@@ -26,6 +26,7 @@ import { stdError } from "forge-std/Test.sol";
contract MatchOrders is BaseOrderTest {
using ArithmeticUtil for uint128;
+
struct FuzzInputsCommon {
address zone;
uint256 id;
diff --git a/test/foundry/NonMatchSelectorTest.t.sol b/test/foundry/NonMatchSelectorTest.t.sol
index 95d90982f..627a58846 100644
--- a/test/foundry/NonMatchSelectorTest.t.sol
+++ b/test/foundry/NonMatchSelectorTest.t.sol
@@ -5,12 +5,12 @@ pragma solidity ^0.8.17;
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
NonMatchSelector_MagicMask,
NonMatchSelector_InvalidErrorValue
-} from "../../contracts/lib/ConsiderationConstants.sol";
+} from "seaport-types/src/lib/ConsiderationConstants.sol";
import { Test } from "forge-std/Test.sol";
diff --git a/test/foundry/NonReentrant.t.sol b/test/foundry/NonReentrant.t.sol
index 8268fd8fd..42b5d397d 100644
--- a/test/foundry/NonReentrant.t.sol
+++ b/test/foundry/NonReentrant.t.sol
@@ -6,11 +6,11 @@ import {
BasicOrderType,
ItemType,
Side
-} from "../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
AdditionalRecipient,
@@ -23,7 +23,7 @@ import {
AdvancedOrder,
BasicOrderParameters,
Order
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
diff --git a/test/foundry/SignatureVerification.t.sol b/test/foundry/SignatureVerification.t.sol
index 46f39af6f..366df3921 100644
--- a/test/foundry/SignatureVerification.t.sol
+++ b/test/foundry/SignatureVerification.t.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.17;
import {
SignatureVerification
-} from "../../contracts/lib/SignatureVerification.sol";
+} from "seaport-core/src/lib/SignatureVerification.sol";
import {
ReferenceSignatureVerification
diff --git a/test/foundry/TestNewHelpers.t.sol b/test/foundry/TestNewHelpers.t.sol
index 6a1efb60a..4a7a3cd57 100644
--- a/test/foundry/TestNewHelpers.t.sol
+++ b/test/foundry/TestNewHelpers.t.sol
@@ -5,7 +5,7 @@ import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
import {
ConsiderationInterface
-} from "../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
BasicOrderParameters,
@@ -14,9 +14,9 @@ import {
Fulfillment,
OrderParameters,
FulfillmentComponent
-} from "../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { BasicOrderType } from "../../contracts/lib/ConsiderationEnums.sol";
+import { BasicOrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
contract TestNewHelpersTest is BaseOrderTest {
struct Context {
diff --git a/test/foundry/TokenTransferrer.t.sol b/test/foundry/TokenTransferrer.t.sol
index a989da498..73d24c3bd 100644
--- a/test/foundry/TokenTransferrer.t.sol
+++ b/test/foundry/TokenTransferrer.t.sol
@@ -5,7 +5,7 @@ import {
ConduitTransfer,
ConduitBatch1155Transfer,
ConduitItemType
-} from "../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
import { TestERC20Revert } from "../../contracts/test/TestERC20Revert.sol";
@@ -17,11 +17,11 @@ import { TestERC1155Revert } from "../../contracts/test/TestERC1155Revert.sol";
import { BaseConduitTest } from "./conduit/BaseConduitTest.sol";
-import { Conduit } from "../../contracts/conduit/Conduit.sol";
+import { Conduit } from "seaport-core/src/conduit/Conduit.sol";
import {
TokenTransferrerErrors
-} from "../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
contract TokenTransferrerTest is BaseConduitTest, TokenTransferrerErrors {
bytes expectedRevert =
diff --git a/test/foundry/TransferHelperMultipleRecipientsTest.sol b/test/foundry/TransferHelperMultipleRecipientsTest.sol
index 26e27147c..ee9c3567f 100644
--- a/test/foundry/TransferHelperMultipleRecipientsTest.sol
+++ b/test/foundry/TransferHelperMultipleRecipientsTest.sol
@@ -5,16 +5,18 @@ import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
import {
ConduitInterface
-} from "../../contracts/interfaces/ConduitInterface.sol";
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
-import { ConduitItemType } from "../../contracts/conduit/lib/ConduitEnums.sol";
+import {
+ ConduitItemType
+} from "seaport-types/src/conduit/lib/ConduitEnums.sol";
import { TransferHelper } from "../../contracts/helpers/TransferHelper.sol";
import {
TransferHelperItem,
TransferHelperItemsWithRecipient
-} from "../../contracts/helpers/TransferHelperStructs.sol";
+} from "seaport-types/src/helpers/TransferHelperStructs.sol";
import { TestERC20 } from "../../contracts/test/TestERC20.sol";
@@ -40,15 +42,15 @@ import {
import {
TokenTransferrerErrors
-} from "../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
import {
TransferHelperErrors
-} from "../../contracts/interfaces/TransferHelperErrors.sol";
+} from "seaport-types/src/interfaces/TransferHelperErrors.sol";
import {
IERC721Receiver
-} from "../../contracts/interfaces/IERC721Receiver.sol";
+} from "seaport-types/src/interfaces/IERC721Receiver.sol";
import {
ERC721ReceiverMock
@@ -62,10 +64,11 @@ import { StubERC721 } from "./token/StubERC721.sol";
import { StubERC1155 } from "./token/StubERC1155.sol";
-import { Strings } from "openzeppelin-contracts/contracts/utils/Strings.sol";
+import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
contract TransferHelperMultipleRecipientsTest is BaseOrderTest {
using Strings for uint256;
+
TransferHelper transferHelper;
// Total supply of fungible tokens to be used in tests for all fungible tokens.
uint256 constant TOTAL_FUNGIBLE_TOKENS = 1e6;
diff --git a/test/foundry/TransferHelperSingleRecipientTest.sol b/test/foundry/TransferHelperSingleRecipientTest.sol
index 1fd8556f1..064a323d4 100644
--- a/test/foundry/TransferHelperSingleRecipientTest.sol
+++ b/test/foundry/TransferHelperSingleRecipientTest.sol
@@ -5,16 +5,18 @@ import { BaseOrderTest } from "./utils/BaseOrderTest.sol";
import {
ConduitInterface
-} from "../../contracts/interfaces/ConduitInterface.sol";
+} from "seaport-types/src/interfaces/ConduitInterface.sol";
-import { ConduitItemType } from "../../contracts/conduit/lib/ConduitEnums.sol";
+import {
+ ConduitItemType
+} from "seaport-types/src/conduit/lib/ConduitEnums.sol";
import { TransferHelper } from "../../contracts/helpers/TransferHelper.sol";
import {
TransferHelperItem,
TransferHelperItemsWithRecipient
-} from "../../contracts/helpers/TransferHelperStructs.sol";
+} from "seaport-types/src/helpers/TransferHelperStructs.sol";
import { TestERC20 } from "../../contracts/test/TestERC20.sol";
@@ -40,15 +42,15 @@ import {
import {
TokenTransferrerErrors
-} from "../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
import {
TransferHelperErrors
-} from "../../contracts/interfaces/TransferHelperErrors.sol";
+} from "seaport-types/src/interfaces/TransferHelperErrors.sol";
import {
IERC721Receiver
-} from "../../contracts/interfaces/IERC721Receiver.sol";
+} from "seaport-types/src/interfaces/IERC721Receiver.sol";
import {
ERC721ReceiverMock
diff --git a/test/foundry/conduit/BaseConduitTest.sol b/test/foundry/conduit/BaseConduitTest.sol
index 8edb4e5ea..7c2d8c52f 100644
--- a/test/foundry/conduit/BaseConduitTest.sol
+++ b/test/foundry/conduit/BaseConduitTest.sol
@@ -6,7 +6,7 @@ import {
ConduitTransfer,
ConduitItemType,
ConduitBatch1155Transfer
-} from "../../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
import { TestERC1155 } from "../../../contracts/test/TestERC1155.sol";
import { TestERC20 } from "../../../contracts/test/TestERC20.sol";
import { TestERC721 } from "../../../contracts/test/TestERC721.sol";
diff --git a/test/foundry/conduit/ConduitExecute.t.sol b/test/foundry/conduit/ConduitExecute.t.sol
index aad0875a2..744a49f20 100644
--- a/test/foundry/conduit/ConduitExecute.t.sol
+++ b/test/foundry/conduit/ConduitExecute.t.sol
@@ -4,12 +4,12 @@ pragma solidity ^0.8.17;
import {
ConduitTransfer,
ConduitItemType
-} from "../../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
import { TestERC1155 } from "../../../contracts/test/TestERC1155.sol";
import { TestERC20 } from "../../../contracts/test/TestERC20.sol";
import { TestERC721 } from "../../../contracts/test/TestERC721.sol";
import { BaseConduitTest } from "./BaseConduitTest.sol";
-import { Conduit } from "../../../contracts/conduit/Conduit.sol";
+import { Conduit } from "seaport-core/src/conduit/Conduit.sol";
contract ConduitExecuteTest is BaseConduitTest {
struct FuzzInputs {
diff --git a/test/foundry/conduit/ConduitExecuteBatch1155.t.sol b/test/foundry/conduit/ConduitExecuteBatch1155.t.sol
index aadc3fcf4..f7f638f5d 100644
--- a/test/foundry/conduit/ConduitExecuteBatch1155.t.sol
+++ b/test/foundry/conduit/ConduitExecuteBatch1155.t.sol
@@ -3,10 +3,10 @@ pragma solidity ^0.8.17;
import {
ConduitBatch1155Transfer
-} from "../../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
import { TestERC1155 } from "../../../contracts/test/TestERC1155.sol";
import { BaseConduitTest } from "./BaseConduitTest.sol";
-import { Conduit } from "../../../contracts/conduit/Conduit.sol";
+import { Conduit } from "seaport-core/src/conduit/Conduit.sol";
contract ConduitExecuteBatch1155Test is BaseConduitTest {
struct FuzzInputs {
diff --git a/test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol b/test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol
index d65b431a0..190ebce0a 100644
--- a/test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol
+++ b/test/foundry/conduit/ConduitExecuteWithBatch1155.t.sol
@@ -2,13 +2,13 @@
pragma solidity ^0.8.17;
-import { Conduit } from "../../../contracts/conduit/Conduit.sol";
+import { Conduit } from "seaport-core/src/conduit/Conduit.sol";
import { BaseConduitTest } from "./BaseConduitTest.sol";
import {
ConduitTransfer,
ConduitBatch1155Transfer,
ConduitItemType
-} from "../../../contracts/conduit/lib/ConduitStructs.sol";
+} from "seaport-types/src/conduit/lib/ConduitStructs.sol";
import { TestERC1155 } from "../../../contracts/test/TestERC1155.sol";
import { TestERC20 } from "../../../contracts/test/TestERC20.sol";
import { TestERC721 } from "../../../contracts/test/TestERC721.sol";
diff --git a/test/foundry/helpers/sol/BaseTest.sol b/test/foundry/helpers/sol/BaseTest.sol
deleted file mode 100644
index 35be61752..000000000
--- a/test/foundry/helpers/sol/BaseTest.sol
+++ /dev/null
@@ -1,413 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { Test } from "forge-std/Test.sol";
-
-import {
- AdditionalRecipient,
- ConsiderationItem,
- CriteriaResolver,
- Execution,
- Fulfillment,
- FulfillmentComponent,
- OfferItem,
- Order,
- OrderComponents,
- OrderParameters,
- ReceivedItem,
- SpentItem
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
-
-import {
- ItemType,
- OrderType
-} from "../../../../contracts/lib/ConsiderationEnums.sol";
-
-import {
- OrderComponentsLib
-} from "../../../../contracts/helpers/sol/lib/OrderComponentsLib.sol";
-
-import {
- OrderParametersLib
-} from "../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
-
-import { OrderLib } from "../../../../contracts/helpers/sol/lib/OrderLib.sol";
-
-contract BaseTest is Test {
- using OrderComponentsLib for OrderComponents;
- using OrderParametersLib for OrderParameters;
- using OrderLib for Order;
-
- struct OrderParametersBlob {
- address offerer; // 0x00
- address zone; // 0x20
- OfferItemBlob[] offer; // 0x40
- ConsiderationItemBlob[] consideration; // 0x60
- uint8 _orderType; // 0x80
- uint256 startTime; // 0xa0
- uint256 endTime; // 0xc0
- bytes32 zoneHash; // 0xe0
- uint256 salt; // 0x100
- bytes32 conduitKey; // 0x120
- uint256 totalOriginalConsiderationItems; // 0x140
- }
-
- struct OrderBlob {
- OrderParametersBlob parameters;
- bytes signature;
- }
-
- function _fromBlob(
- OrderBlob memory orderBlob
- ) internal view returns (Order memory order) {
- order = OrderLib.empty();
- order.parameters = _fromBlob(orderBlob.parameters);
- order.signature = orderBlob.signature;
- }
-
- function assertEq(Order memory a, Order memory b) internal {
- assertEq(a.parameters, b.parameters);
- assertEq(a.signature, b.signature, "signature");
- }
-
- function assertEq(Order[] memory a, Order[] memory b) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function setUp() public virtual {}
-
- function assertEq(OfferItem memory a, OfferItem memory b) internal {
- assertEq(uint8(a.itemType), uint8(b.itemType), "itemType");
- assertEq(a.token, b.token, "token");
- assertEq(
- a.identifierOrCriteria,
- b.identifierOrCriteria,
- "identifierOrCriteria"
- );
- assertEq(a.startAmount, b.startAmount, "startAmount");
- assertEq(a.endAmount, b.endAmount, "endAmount");
- }
-
- function assertEq(
- ConsiderationItem memory a,
- ConsiderationItem memory b
- ) internal {
- assertEq(uint8(a.itemType), uint8(b.itemType), "itemType");
- assertEq(a.token, b.token, "token");
- assertEq(
- a.identifierOrCriteria,
- b.identifierOrCriteria,
- "identifierOrCriteria"
- );
- assertEq(a.startAmount, b.startAmount, "startAmount");
- assertEq(a.endAmount, b.endAmount, "endAmount");
- assertEq(a.recipient, b.recipient, "recipient");
- }
-
- function assertEq(OfferItem[] memory a, OfferItem[] memory b) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(
- ConsiderationItem[] memory a,
- ConsiderationItem[] memory b
- ) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(
- OrderParameters memory a,
- OrderParameters memory b
- ) internal {
- assertEq(a.offerer, b.offerer, "offerer");
- assertEq(a.zone, b.zone, "zone");
- assertEq(a.offer, b.offer);
- assertEq(a.consideration, b.consideration);
- assertEq(uint8(a.orderType), uint8(b.orderType), "orderType");
- assertEq(a.startTime, b.startTime, "startTime");
- assertEq(a.endTime, b.endTime, "endTime");
- assertEq(a.zoneHash, b.zoneHash, "zoneHash");
- assertEq(a.salt, b.salt, "salt");
- assertEq(a.conduitKey, b.conduitKey, "conduitKey");
- assertEq(
- a.totalOriginalConsiderationItems,
- b.totalOriginalConsiderationItems,
- "totalOriginalConsiderationItems"
- );
- }
-
- function assertEq(SpentItem memory a, SpentItem memory b) internal {
- assertEq(uint8(a.itemType), uint8(b.itemType), "itemType");
- assertEq(a.token, b.token, "token");
- assertEq(a.identifier, b.identifier, "identifier");
- assertEq(a.amount, b.amount, "amount");
- }
-
- function assertEq(SpentItem[] memory a, SpentItem[] memory b) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(
- AdditionalRecipient memory a,
- AdditionalRecipient memory b
- ) internal {
- assertEq(a.amount, b.amount, "amount");
- assertEq(a.recipient, b.recipient, "recipient");
- }
-
- function assertEq(
- AdditionalRecipient[] memory a,
- AdditionalRecipient[] memory b
- ) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(ReceivedItem memory a, ReceivedItem memory b) internal {
- assertEq(uint8(a.itemType), uint8(b.itemType), "itemType");
- assertEq(a.token, b.token, "token");
- assertEq(a.identifier, b.identifier, "identifier");
- assertEq(a.amount, b.amount, "amount");
- assertEq(a.recipient, b.recipient, "recipient");
- }
-
- function assertEq(
- ReceivedItem[] memory a,
- ReceivedItem[] memory b
- ) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(
- CriteriaResolver memory a,
- CriteriaResolver memory b
- ) internal {
- assertEq(a.orderIndex, b.orderIndex, "orderIndex");
- assertEq(uint8(a.side), uint8(b.side), "side");
- assertEq(a.index, b.index, "index");
- assertEq(a.identifier, b.identifier, "identifier");
- assertEq(a.criteriaProof, b.criteriaProof);
- }
-
- function assertEq(
- CriteriaResolver[] memory a,
- CriteriaResolver[] memory b
- ) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(bytes32[] memory a, bytes32[] memory b) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(Execution memory a, Execution memory b) internal {
- assertEq(a.item, b.item);
- assertEq(a.offerer, b.offerer, "offerer");
- assertEq(a.conduitKey, b.conduitKey, "conduitKey");
- }
-
- function assertEq(Execution[] memory a, Execution[] memory b) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function toItemType(uint8 _itemType) internal view returns (ItemType) {
- return ItemType(bound(_itemType, 0, 5));
- }
-
- function assertEq(
- FulfillmentComponent memory a,
- FulfillmentComponent memory b
- ) internal {
- assertEq(a.orderIndex, b.orderIndex, "orderIndex");
- assertEq(a.itemIndex, b.itemIndex, "itemIndex");
- }
-
- function assertEq(
- FulfillmentComponent[] memory a,
- FulfillmentComponent[] memory b
- ) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function assertEq(Fulfillment memory a, Fulfillment memory b) internal {
- assertEq(a.offerComponents, b.offerComponents);
- assertEq(a.considerationComponents, b.considerationComponents);
- }
-
- function assertEq(Fulfillment[] memory a, Fulfillment[] memory b) internal {
- assertEq(a.length, b.length, "length");
- for (uint256 i = 0; i < a.length; i++) {
- assertEq(a[i], b[i]);
- }
- }
-
- function toOrderType(uint8 _orderType) internal view returns (OrderType) {
- return OrderType(bound(_orderType, 0, 3));
- }
-
- struct OfferItemBlob {
- uint8 _itemType;
- address token;
- uint256 identifierOrCriteria;
- uint256 startAmount;
- uint256 endAmount;
- }
-
- struct ConsiderationItemBlob {
- uint8 _itemType;
- address token;
- uint256 identifierOrCriteria;
- uint256 startAmount;
- uint256 endAmount;
- address payable recipient;
- }
-
- struct OrderComponentsBlob {
- address offerer;
- address zone;
- OfferItemBlob[] offer;
- ConsiderationItemBlob[] consideration;
- uint8 _orderType;
- uint256 startTime;
- uint256 endTime;
- bytes32 zoneHash;
- uint256 salt;
- bytes32 conduitKey;
- uint256 counter;
- }
-
- function _fromBlob(
- OfferItemBlob memory blob
- ) internal view returns (OfferItem memory) {
- return
- OfferItem(
- toItemType(blob._itemType),
- blob.token,
- blob.identifierOrCriteria,
- blob.startAmount,
- blob.endAmount
- );
- }
-
- function _fromBlob(
- ConsiderationItemBlob memory blob
- ) internal view returns (ConsiderationItem memory) {
- return
- ConsiderationItem(
- toItemType(blob._itemType),
- blob.token,
- blob.identifierOrCriteria,
- blob.startAmount,
- blob.endAmount,
- blob.recipient
- );
- }
-
- function _fromBlobs(
- OfferItemBlob[] memory blob
- ) internal view returns (OfferItem[] memory) {
- OfferItem[] memory items = new OfferItem[](blob.length);
- for (uint256 i = 0; i < blob.length; i++) {
- items[i] = _fromBlob(blob[i]);
- }
- return items;
- }
-
- function _fromBlobs(
- ConsiderationItemBlob[] memory blob
- ) internal view returns (ConsiderationItem[] memory) {
- ConsiderationItem[] memory items = new ConsiderationItem[](blob.length);
- for (uint256 i = 0; i < blob.length; i++) {
- items[i] = _fromBlob(blob[i]);
- }
- return items;
- }
-
- function _fromBlob(
- OrderComponentsBlob memory blob
- ) internal view returns (OrderComponents memory) {
- OrderComponents memory components = OrderComponentsLib.empty();
- components = components.withOfferer(blob.offerer);
- components = components.withZone(blob.zone);
- components = components.withOffer(_fromBlobs(blob.offer));
- components = components.withConsideration(
- _fromBlobs(blob.consideration)
- );
- components = components.withOrderType(toOrderType(blob._orderType));
- components = components.withStartTime(blob.startTime);
- components = components.withEndTime(blob.endTime);
- components = components.withZoneHash(blob.zoneHash);
- components = components.withSalt(blob.salt);
- components = components.withConduitKey(blob.conduitKey);
- components = components.withCounter(blob.counter);
- return components;
- }
-
- function _fromBlob(
- OrderParametersBlob memory blob
- ) internal view returns (OrderParameters memory) {
- OrderParameters memory parameters = OrderParametersLib.empty();
- parameters = parameters.withOfferer(blob.offerer);
- parameters = parameters.withZone(blob.zone);
- parameters = parameters.withOffer(_fromBlobs(blob.offer));
- parameters = parameters.withConsideration(
- _fromBlobs(blob.consideration)
- );
- parameters = parameters.withOrderType(toOrderType(blob._orderType));
- parameters = parameters.withStartTime(blob.startTime);
- parameters = parameters.withEndTime(blob.endTime);
- parameters = parameters.withZoneHash(blob.zoneHash);
- parameters = parameters.withSalt(blob.salt);
- parameters = parameters.withConduitKey(blob.conduitKey);
- parameters = parameters.withTotalOriginalConsiderationItems(
- blob.totalOriginalConsiderationItems
- );
- return parameters;
- }
-
- function assertEq(
- OrderComponents memory a,
- OrderComponents memory b
- ) internal {
- assertEq(a.offerer, b.offerer, "offerer");
- assertEq(a.zone, b.zone, "zone");
- assertEq(a.offer, b.offer);
- assertEq(a.consideration, b.consideration);
- assertEq(uint8(a.orderType), uint8(b.orderType), "orderType");
- assertEq(a.startTime, b.startTime, "startTime");
- assertEq(a.endTime, b.endTime, "endTime");
- assertEq(a.zoneHash, b.zoneHash, "zoneHash");
- assertEq(a.salt, b.salt, "salt");
- assertEq(a.conduitKey, b.conduitKey, "conduitKey");
- assertEq(a.counter, b.counter, "counter");
- }
-}
diff --git a/test/foundry/helpers/sol/lib/AdditionalRecipientLib.t.sol b/test/foundry/helpers/sol/lib/AdditionalRecipientLib.t.sol
deleted file mode 100644
index 2fa6d75bc..000000000
--- a/test/foundry/helpers/sol/lib/AdditionalRecipientLib.t.sol
+++ /dev/null
@@ -1,86 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- AdditionalRecipientLib
-} from "../../../../../contracts/helpers/sol/lib/AdditionalRecipientLib.sol";
-import {
- AdditionalRecipient
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-
-contract AdditionalRecipientLibTest is BaseTest {
- using AdditionalRecipientLib for AdditionalRecipient;
-
- function testRetrieveDefault(
- uint256 amount,
- address payable recipient
- ) public {
- AdditionalRecipient memory additionalRecipient = AdditionalRecipient({
- // Make sure the the amount is not 0, otherwise it will be
- // considered empty and trigger the revert.
- amount: amount == 0 ? 1 : amount,
- recipient: recipient
- });
- AdditionalRecipientLib.saveDefault(additionalRecipient, "default");
- AdditionalRecipient
- memory defaultAdditionalRecipient = AdditionalRecipientLib
- .fromDefault("default");
- assertEq(additionalRecipient, defaultAdditionalRecipient);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty AdditionalRecipient selected.");
- AdditionalRecipientLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty AdditionalRecipient array selected.");
- AdditionalRecipientLib.fromDefaultMany("nonexistent");
- }
-
- function testComposeEmpty(
- uint256 amount,
- address payable recipient
- ) public {
- AdditionalRecipient memory additionalRecipient = AdditionalRecipientLib
- .empty()
- .withAmount(amount)
- .withRecipient(recipient);
- assertEq(
- additionalRecipient,
- AdditionalRecipient({ amount: amount, recipient: recipient })
- );
- }
-
- function testCopy() public {
- AdditionalRecipient memory additionalRecipient = AdditionalRecipient({
- amount: 1,
- recipient: payable(address(1))
- });
- AdditionalRecipient memory copy = additionalRecipient.copy();
- assertEq(additionalRecipient, copy);
- additionalRecipient.amount = 2;
- assertEq(copy.amount, 1);
- }
-
- function testRetrieveDefaultMany(
- uint256[3] memory amount,
- address payable[3] memory recipient
- ) public {
- AdditionalRecipient[]
- memory additionalRecipients = new AdditionalRecipient[](3);
- for (uint256 i = 0; i < 3; i++) {
- additionalRecipients[i] = AdditionalRecipient({
- amount: amount[i],
- recipient: recipient[i]
- });
- }
- AdditionalRecipientLib.saveDefaultMany(additionalRecipients, "default");
- AdditionalRecipient[]
- memory defaultAdditionalRecipients = AdditionalRecipientLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(additionalRecipients[i], defaultAdditionalRecipients[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/AdvancedOrderLib.t.sol b/test/foundry/helpers/sol/lib/AdvancedOrderLib.t.sol
deleted file mode 100644
index b39ed182b..000000000
--- a/test/foundry/helpers/sol/lib/AdvancedOrderLib.t.sol
+++ /dev/null
@@ -1,128 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- AdvancedOrderLib
-} from "../../../../../contracts/helpers/sol/lib/AdvancedOrderLib.sol";
-import {
- AdvancedOrder,
- OrderParameters
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-import {
- OrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
-
-contract AdvancedOrderLibTest is BaseTest {
- using AdvancedOrderLib for AdvancedOrder;
- using OrderParametersLib for OrderParameters;
-
- function testRetrieveDefault(
- uint120 numerator,
- uint120 denominator,
- bytes memory signature,
- bytes memory extraData
- ) public {
- OrderParameters memory orderParameters = OrderParametersLib
- .empty()
- .withOfferer(address(1234));
- AdvancedOrder memory advancedOrder = AdvancedOrder({
- parameters: orderParameters,
- numerator: numerator,
- denominator: denominator,
- signature: signature,
- extraData: extraData
- });
- AdvancedOrderLib.saveDefault(advancedOrder, "default");
- AdvancedOrder memory defaultAdvancedOrder = AdvancedOrderLib
- .fromDefault("default");
- assertEq(advancedOrder, defaultAdvancedOrder);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty AdvancedOrder selected.");
- AdvancedOrderLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty AdvancedOrder array selected.");
- AdvancedOrderLib.fromDefaultMany("nonexistent");
- }
-
- function testComposeEmpty(
- uint120 numerator,
- uint120 denominator,
- bytes memory signature,
- bytes memory extraData
- ) public {
- AdvancedOrder memory advancedOrder = AdvancedOrderLib
- .empty()
- .withParameters(OrderParametersLib.empty())
- .withNumerator(numerator)
- .withDenominator(denominator)
- .withSignature(signature)
- .withExtraData(extraData);
- assertEq(
- advancedOrder,
- AdvancedOrder({
- parameters: OrderParametersLib.empty(),
- numerator: numerator,
- denominator: denominator,
- signature: signature,
- extraData: extraData
- })
- );
- }
-
- function testCopy() public {
- AdvancedOrder memory advancedOrder = AdvancedOrder({
- parameters: OrderParametersLib.empty(),
- numerator: 1,
- denominator: 1,
- signature: "signature",
- extraData: "extraData"
- });
- AdvancedOrder memory copy = advancedOrder.copy();
- assertEq(advancedOrder, copy);
- advancedOrder.numerator = 2;
- assertEq(copy.numerator, 1);
-
- advancedOrder.parameters = OrderParametersLib.empty().withOfferer(
- address(1234)
- );
- assertEq(copy.parameters.offerer, address(0));
- }
-
- function testRetrieveDefaultMany(
- uint120[3] memory numerator,
- uint120[3] memory denominator,
- bytes[3] memory signature,
- bytes[3] memory extraData
- ) public {
- AdvancedOrder[] memory advancedOrders = new AdvancedOrder[](3);
- for (uint256 i = 0; i < 3; i++) {
- advancedOrders[i] = AdvancedOrder({
- parameters: OrderParametersLib.empty().withOfferer(
- address(1234)
- ),
- numerator: numerator[i],
- denominator: denominator[i],
- signature: signature[i],
- extraData: extraData[i]
- });
- }
- AdvancedOrderLib.saveDefaultMany(advancedOrders, "default");
- AdvancedOrder[] memory defaultAdvancedOrders = AdvancedOrderLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(advancedOrders[i], defaultAdvancedOrders[i]);
- }
- }
-
- function assertEq(AdvancedOrder memory a, AdvancedOrder memory b) internal {
- assertEq(a.parameters, b.parameters);
- assertEq(a.numerator, b.numerator, "numerator");
- assertEq(a.denominator, b.denominator, "denominator");
- assertEq(a.signature, b.signature, "signature");
- assertEq(a.extraData, b.extraData, "extraData");
- }
-}
diff --git a/test/foundry/helpers/sol/lib/BasicOrderParametersLib.t.sol b/test/foundry/helpers/sol/lib/BasicOrderParametersLib.t.sol
deleted file mode 100644
index 9eab69301..000000000
--- a/test/foundry/helpers/sol/lib/BasicOrderParametersLib.t.sol
+++ /dev/null
@@ -1,263 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- BasicOrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/BasicOrderParametersLib.sol";
-import {
- AdditionalRecipientLib
-} from "../../../../../contracts/helpers/sol/lib/AdditionalRecipientLib.sol";
-import {
- BasicOrderParameters,
- OrderParameters,
- AdditionalRecipient
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import {
- ItemType,
- BasicOrderType
-} from "../../../../../contracts/lib/ConsiderationEnums.sol";
-import {
- OrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
-import {
- SeaportArrays
-} from "../../../../../contracts/helpers/sol/lib/SeaportArrays.sol";
-
-contract BasicOrderParametersLibTest is BaseTest {
- using BasicOrderParametersLib for BasicOrderParameters;
- using OrderParametersLib for OrderParameters;
-
- struct Blob {
- address considerationToken; // 0x24
- uint256 considerationIdentifier; // 0x44
- uint256 considerationAmount; // 0x64
- address payable offerer; // 0x84
- address zone; // 0xa4
- address offerToken; // 0xc4
- uint256 offerIdentifier; // 0xe4
- uint256 offerAmount; // 0x104
- uint8 basicOrderType;
- uint256 startTime; // 0x144
- uint256 endTime; // 0x164
- bytes32 zoneHash; // 0x184
- uint256 salt; // 0x1a4
- bytes32 offererConduitKey; // 0x1c4
- bytes32 fulfillerConduitKey; // 0x1e4
- uint256 totalOriginalAdditionalRecipients; // 0x204
- AdditionalRecipient[] additionalRecipients; // 0x224
- bytes signature;
- }
-
- function testRetrieveDefault(Blob memory blob) public {
- // assign everything from blob
- BasicOrderParameters
- memory basicOrderParameters = BasicOrderParametersLib.empty();
- basicOrderParameters = basicOrderParameters.withConsiderationToken(
- blob.considerationToken
- );
- basicOrderParameters = basicOrderParameters.withConsiderationIdentifier(
- blob.considerationIdentifier
- );
- basicOrderParameters = basicOrderParameters.withConsiderationAmount(
- blob.considerationAmount
- );
- basicOrderParameters = basicOrderParameters.withOfferer(blob.offerer);
- basicOrderParameters = basicOrderParameters.withZone(blob.zone);
- basicOrderParameters = basicOrderParameters.withOfferToken(
- blob.offerToken
- );
- basicOrderParameters = basicOrderParameters.withOfferIdentifier(
- blob.offerIdentifier
- );
- basicOrderParameters = basicOrderParameters.withOfferAmount(
- blob.offerAmount
- );
- basicOrderParameters = basicOrderParameters.withBasicOrderType(
- BasicOrderType(bound(blob.basicOrderType, 0, 23))
- );
- basicOrderParameters = basicOrderParameters.withStartTime(
- blob.startTime
- );
- basicOrderParameters = basicOrderParameters.withEndTime(blob.endTime);
- basicOrderParameters = basicOrderParameters.withZoneHash(blob.zoneHash);
- basicOrderParameters = basicOrderParameters.withSalt(blob.salt);
- basicOrderParameters = basicOrderParameters.withOffererConduitKey(
- blob.offererConduitKey
- );
- basicOrderParameters = basicOrderParameters.withFulfillerConduitKey(
- blob.fulfillerConduitKey
- );
- basicOrderParameters = basicOrderParameters
- .withTotalOriginalAdditionalRecipients(
- blob.totalOriginalAdditionalRecipients
- );
- basicOrderParameters = basicOrderParameters.withAdditionalRecipients(
- blob.additionalRecipients
- );
- basicOrderParameters = basicOrderParameters.withSignature(
- blob.signature
- );
-
- BasicOrderParametersLib.saveDefault(basicOrderParameters, "default");
- BasicOrderParameters
- memory defaultBasicOrderParameters = BasicOrderParametersLib
- .fromDefault("default");
- assertEq(basicOrderParameters, defaultBasicOrderParameters);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty BasicOrderParameters selected.");
- BasicOrderParametersLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty BasicOrderParameters array selected.");
- BasicOrderParametersLib.fromDefaultMany("nonexistent");
- }
-
- function testCopy() public {
- AdditionalRecipient[] memory additionalRecipients = SeaportArrays
- .AdditionalRecipients(
- AdditionalRecipient({
- amount: 1,
- recipient: payable(address(1234))
- })
- );
- BasicOrderParameters
- memory basicOrderParameters = BasicOrderParametersLib
- .empty()
- .withConsiderationToken(address(1))
- .withConsiderationIdentifier(2)
- .withConsiderationAmount(3)
- .withOfferer(address(4))
- .withZone(address(5))
- .withOfferToken(address(6))
- .withOfferIdentifier(7)
- .withOfferAmount(8)
- .withBasicOrderType(BasicOrderType(9))
- .withStartTime(10)
- .withEndTime(11)
- .withZoneHash(bytes32(uint256(12)))
- .withSalt(13)
- .withOffererConduitKey(bytes32(uint256(14)))
- .withFulfillerConduitKey(bytes32(uint256(15)))
- .withTotalOriginalAdditionalRecipients(16)
- .withAdditionalRecipients(additionalRecipients)
- .withSignature(new bytes(0));
- BasicOrderParameters memory copy = basicOrderParameters.copy();
- assertEq(basicOrderParameters, copy);
- basicOrderParameters.considerationIdentifier = 123;
- assertEq(copy.considerationIdentifier, 2, "copy changed");
-
- additionalRecipients[0].recipient = payable(address(456));
-
- assertEq(
- copy.additionalRecipients[0].recipient,
- address(1234),
- "copy recipient changed"
- );
- }
-
- function testRetrieveDefaultMany(
- uint256[3] memory considerationidentifier,
- uint256[3] memory considerationAmount,
- address payable[3] memory recipient
- ) public {
- BasicOrderParameters[]
- memory basicOrderParameterss = new BasicOrderParameters[](3);
- for (uint256 i = 0; i < 3; i++) {
- AdditionalRecipient[] memory additionalRecipients = SeaportArrays
- .AdditionalRecipients(
- AdditionalRecipient({
- amount: 1,
- recipient: payable(address(recipient[i]))
- })
- );
-
- basicOrderParameterss[i] = BasicOrderParametersLib
- .empty()
- .withConsiderationIdentifier(considerationidentifier[i])
- .withConsiderationAmount(considerationAmount[i])
- .withAdditionalRecipients(additionalRecipients);
- }
- BasicOrderParametersLib.saveDefaultMany(
- basicOrderParameterss,
- "default"
- );
- BasicOrderParameters[]
- memory defaultBasicOrderParameterss = BasicOrderParametersLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(basicOrderParameterss[i], defaultBasicOrderParameterss[i]);
- }
- }
-
- function assertEq(
- BasicOrderParameters memory a,
- BasicOrderParameters memory b
- ) internal {
- /**
- * do all these
- * // calldata offset
- * address considerationToken; // 0x24
- * uint256 considerationIdentifier; // 0x44
- * uint256 considerationAmount; // 0x64
- * address payable offerer; // 0x84
- * address zone; // 0xa4
- * address offerToken; // 0xc4
- * uint256 offerIdentifier; // 0xe4
- * uint256 offerAmount; // 0x104
- * BasicOrderType basicOrderType; // 0x124
- * uint256 startTime; // 0x144
- * uint256 endTime; // 0x164
- * bytes32 zoneHash; // 0x184
- * uint256 salt; // 0x1a4
- * bytes32 offererConduitKey; // 0x1c4
- * bytes32 fulfillerConduitKey; // 0x1e4
- * uint256 totalOriginalAdditionalRecipients; // 0x204
- * AdditionalRecipient[] additionalRecipients; // 0x224
- * bytes signature; // 0x244
- */
- assertEq(
- a.considerationToken,
- b.considerationToken,
- "considerationToken"
- );
- assertEq(
- a.considerationIdentifier,
- b.considerationIdentifier,
- "considerationIdentifier"
- );
- assertEq(
- a.considerationAmount,
- b.considerationAmount,
- "considerationAmount"
- );
- assertEq(a.offerer, b.offerer, "offerer");
- assertEq(a.zone, b.zone, "zone");
- assertEq(a.offerToken, b.offerToken, "offerToken");
- assertEq(a.offerIdentifier, b.offerIdentifier, "offerIdentifier");
- assertEq(a.offerAmount, b.offerAmount, "offerAmount");
- assertEq(
- uint8(a.basicOrderType),
- uint8(b.basicOrderType),
- "basicOrderType"
- );
- assertEq(a.startTime, b.startTime, "startTime");
- assertEq(a.endTime, b.endTime, "endTime");
- assertEq(a.zoneHash, b.zoneHash, "zoneHash");
- assertEq(a.salt, b.salt, "salt");
- assertEq(a.offererConduitKey, b.offererConduitKey, "offererConduitKey");
- assertEq(
- a.fulfillerConduitKey,
- b.fulfillerConduitKey,
- "fulfillerConduitKey"
- );
- assertEq(
- a.totalOriginalAdditionalRecipients,
- b.totalOriginalAdditionalRecipients,
- "totalOriginalAdditionalRecipients"
- );
- assertEq(a.additionalRecipients, b.additionalRecipients);
- assertEq(a.signature, b.signature, "signature");
- }
-}
diff --git a/test/foundry/helpers/sol/lib/ConsiderationItemLib.t.sol b/test/foundry/helpers/sol/lib/ConsiderationItemLib.t.sol
deleted file mode 100644
index ae5effe11..000000000
--- a/test/foundry/helpers/sol/lib/ConsiderationItemLib.t.sol
+++ /dev/null
@@ -1,122 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- ConsiderationItemLib
-} from "../../../../../contracts/helpers/sol/lib/ConsiderationItemLib.sol";
-import {
- ConsiderationItem
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-
-contract ConsiderationItemLibTest is BaseTest {
- using ConsiderationItemLib for ConsiderationItem;
-
- function testRetrieveDefault(
- uint8 itemType,
- address token,
- uint256 identifier,
- uint256 startAmount,
- uint256 endAmount,
- address payable recipient
- ) public {
- itemType = uint8(bound(itemType, 0, 5));
- ConsiderationItem memory considerationItem = ConsiderationItem({
- itemType: ItemType(itemType),
- token: token,
- identifierOrCriteria: identifier,
- startAmount: startAmount,
- endAmount: endAmount == 0 ? 1 : endAmount,
- recipient: recipient
- });
- ConsiderationItemLib.saveDefault(considerationItem, "default");
- ConsiderationItem memory defaultConsiderationItem = ConsiderationItemLib
- .fromDefault("default");
- assertEq(considerationItem, defaultConsiderationItem);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty ConsiderationItem selected.");
- ConsiderationItemLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty ConsiderationItem array selected.");
- ConsiderationItemLib.fromDefaultMany("nonexistent");
- }
-
- function testComposeEmpty(
- uint8 itemType,
- address token,
- uint256 identifier,
- uint256 startAmount,
- uint256 endAmount,
- address payable recipient
- ) public {
- ItemType _itemType = ItemType(bound(itemType, 0, 5));
- ConsiderationItem memory considerationItem = ConsiderationItemLib
- .empty()
- .withRecipient(recipient)
- .withEndAmount(endAmount)
- .withStartAmount(startAmount)
- .withIdentifierOrCriteria(identifier)
- .withToken(token)
- .withItemType(_itemType);
- assertEq(
- considerationItem,
- ConsiderationItem({
- itemType: _itemType,
- token: token,
- identifierOrCriteria: identifier,
- startAmount: startAmount,
- endAmount: endAmount,
- recipient: recipient
- })
- );
- }
-
- function testCopy() public {
- ConsiderationItem memory considerationItem = ConsiderationItem({
- itemType: ItemType(1),
- token: address(1),
- identifierOrCriteria: 1,
- startAmount: 1,
- endAmount: 1,
- recipient: payable(address(1234))
- });
- ConsiderationItem memory copy = considerationItem.copy();
- assertEq(considerationItem, copy);
- considerationItem.itemType = ItemType(2);
- assertEq(uint8(copy.itemType), 1);
- }
-
- function testRetrieveDefaultMany(
- uint8[3] memory itemType,
- address[3] memory token,
- uint256[3] memory identifier,
- uint256[3] memory startAmount,
- uint256[3] memory endAmount,
- address payable[3] memory recipient
- ) public {
- ConsiderationItem[] memory considerationItems = new ConsiderationItem[](
- 3
- );
- for (uint256 i = 0; i < 3; i++) {
- itemType[i] = uint8(bound(itemType[i], 0, 5));
- considerationItems[i] = ConsiderationItem({
- itemType: ItemType(itemType[i]),
- token: token[i],
- identifierOrCriteria: identifier[i],
- startAmount: startAmount[i],
- endAmount: endAmount[i],
- recipient: recipient[i]
- });
- }
- ConsiderationItemLib.saveDefaultMany(considerationItems, "default");
- ConsiderationItem[]
- memory defaultConsiderationItems = ConsiderationItemLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(considerationItems[i], defaultConsiderationItems[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/CriteriaResolverLib.t.sol b/test/foundry/helpers/sol/lib/CriteriaResolverLib.t.sol
deleted file mode 100644
index 2e4bbe4f4..000000000
--- a/test/foundry/helpers/sol/lib/CriteriaResolverLib.t.sol
+++ /dev/null
@@ -1,108 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- CriteriaResolverLib
-} from "../../../../../contracts/helpers/sol/lib/CriteriaResolverLib.sol";
-import {
- CriteriaResolver
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { Side } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-
-contract CriteriaResolverLibTest is BaseTest {
- using CriteriaResolverLib for CriteriaResolver;
-
- function testRetrieveDefault(
- uint256 orderIndex,
- bool side,
- uint256 index,
- uint256 identifier,
- bytes32[] memory criteriaProof
- ) public {
- CriteriaResolver memory criteriaResolver = CriteriaResolver({
- orderIndex: orderIndex == 0 ? 1 : orderIndex,
- side: Side(side ? 1 : 0),
- index: index,
- identifier: identifier,
- criteriaProof: criteriaProof
- });
- CriteriaResolverLib.saveDefault(criteriaResolver, "default");
- CriteriaResolver memory defaultCriteriaResolver = CriteriaResolverLib
- .fromDefault("default");
- assertEq(criteriaResolver, defaultCriteriaResolver);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty CriteriaResolver selected.");
- CriteriaResolverLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty CriteriaResolver array selected.");
- CriteriaResolverLib.fromDefaultMany("nonexistent");
- }
-
- function testComposeEmpty(
- uint256 orderIndex,
- bool side,
- uint256 index,
- uint256 identifier,
- bytes32[] memory criteriaProof
- ) public {
- CriteriaResolver memory criteriaResolver = CriteriaResolverLib
- .empty()
- .withOrderIndex(orderIndex)
- .withSide(Side(side ? 1 : 0))
- .withIndex(index)
- .withIdentifier(identifier)
- .withCriteriaProof(criteriaProof);
- assertEq(
- criteriaResolver,
- CriteriaResolver({
- orderIndex: orderIndex,
- side: Side(side ? 1 : 0),
- index: index,
- identifier: identifier,
- criteriaProof: criteriaProof
- })
- );
- }
-
- function testCopy() public {
- CriteriaResolver memory criteriaResolver = CriteriaResolver({
- orderIndex: 1,
- side: Side(1),
- index: 1,
- identifier: 1,
- criteriaProof: new bytes32[](0)
- });
- CriteriaResolver memory copy = criteriaResolver.copy();
- assertEq(criteriaResolver, copy);
- criteriaResolver.index = 2;
- assertEq(copy.index, 1);
- }
-
- function testRetrieveDefaultMany(
- uint256[3] memory orderIndex,
- bool[3] memory side,
- uint256[3] memory index,
- uint256[3] memory identifier,
- bytes32[][3] memory criteriaProof
- ) public {
- CriteriaResolver[] memory criteriaResolvers = new CriteriaResolver[](3);
- for (uint256 i = 0; i < 3; i++) {
- criteriaResolvers[i] = CriteriaResolver({
- orderIndex: orderIndex[i],
- side: Side(side[i] ? 1 : 0),
- index: index[i],
- identifier: identifier[i],
- criteriaProof: criteriaProof[i]
- });
- }
- CriteriaResolverLib.saveDefaultMany(criteriaResolvers, "default");
- CriteriaResolver[] memory defaultCriteriaResolvers = CriteriaResolverLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(criteriaResolvers[i], defaultCriteriaResolvers[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/ExecutionsLib.t.sol b/test/foundry/helpers/sol/lib/ExecutionsLib.t.sol
deleted file mode 100644
index 52a50b076..000000000
--- a/test/foundry/helpers/sol/lib/ExecutionsLib.t.sol
+++ /dev/null
@@ -1,132 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- ExecutionLib
-} from "../../../../../contracts/helpers/sol/lib/ExecutionLib.sol";
-import {
- Execution,
- ReceivedItem
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-import {
- ReceivedItemLib
-} from "../../../../../contracts/helpers/sol/lib/ReceivedItemLib.sol";
-
-contract ExecutionLibTest is BaseTest {
- using ExecutionLib for Execution;
-
- struct ReceivedItemBlob {
- uint8 itemType;
- address token;
- uint256 identifier;
- uint256 amount;
- address payable recipient;
- }
-
- function testRetrieveDefault(
- ReceivedItemBlob memory blob,
- address offerer,
- bytes32 conduitKey
- ) public {
- ReceivedItem memory receivedItem = ReceivedItem({
- itemType: toItemType(blob.itemType),
- token: blob.token,
- identifier: blob.identifier,
- amount: blob.amount == 0 ? 1 : blob.amount,
- recipient: blob.recipient
- });
- Execution memory execution = Execution({
- item: receivedItem,
- offerer: offerer,
- conduitKey: conduitKey
- });
- ExecutionLib.saveDefault(execution, "default");
- Execution memory defaultExecution = ExecutionLib.fromDefault("default");
- assertEq(execution, defaultExecution);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty Execution selected.");
- ExecutionLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty Execution array selected.");
- ExecutionLib.fromDefaultMany("nonexistent");
- }
-
- function _fromBlob(
- ReceivedItemBlob memory blob
- ) internal view returns (ReceivedItem memory) {
- return
- ReceivedItem({
- itemType: toItemType(blob.itemType),
- token: blob.token,
- identifier: blob.identifier,
- amount: blob.amount,
- recipient: blob.recipient
- });
- }
-
- function testComposeEmpty(
- ReceivedItemBlob memory blob,
- address offerer,
- bytes32 conduitKey
- ) public {
- ReceivedItem memory receivedItem = _fromBlob(blob);
- Execution memory execution = ExecutionLib
- .empty()
- .withItem(receivedItem)
- .withOfferer(offerer)
- .withConduitKey(conduitKey);
- assertEq(
- execution,
- Execution({
- item: receivedItem,
- offerer: offerer,
- conduitKey: conduitKey
- })
- );
- }
-
- function testCopy() public {
- Execution memory execution = Execution({
- item: ReceivedItem({
- itemType: ItemType(1),
- token: address(1),
- identifier: 1,
- amount: 1,
- recipient: payable(address(1234))
- }),
- offerer: address(1),
- conduitKey: bytes32(uint256(1))
- });
- Execution memory copy = execution.copy();
- assertEq(execution, copy);
- execution.offerer = address(2);
- assertEq(copy.offerer, address(1));
- }
-
- function testRetrieveDefaultMany(
- ReceivedItemBlob[3] memory blob,
- address[3] memory offerer,
- bytes32[3] memory conduitKey
- ) public {
- Execution[] memory executions = new Execution[](3);
- for (uint256 i = 0; i < 3; i++) {
- ReceivedItem memory item = _fromBlob(blob[i]);
- executions[i] = Execution({
- item: item,
- offerer: offerer[i],
- conduitKey: conduitKey[i]
- });
- }
- ExecutionLib.saveDefaultMany(executions, "default");
- Execution[] memory defaultExecutions = ExecutionLib.fromDefaultMany(
- "default"
- );
- for (uint256 i = 0; i < 3; i++) {
- assertEq(executions[i], defaultExecutions[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/FulfillmentComponentLib.t.sol b/test/foundry/helpers/sol/lib/FulfillmentComponentLib.t.sol
deleted file mode 100644
index 5d0aa4b7c..000000000
--- a/test/foundry/helpers/sol/lib/FulfillmentComponentLib.t.sol
+++ /dev/null
@@ -1,79 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- FulfillmentComponentLib
-} from "../../../../../contracts/helpers/sol/lib/FulfillmentComponentLib.sol";
-import {
- FulfillmentComponent
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-
-contract FulfillmentComponentLibTest is BaseTest {
- using FulfillmentComponentLib for FulfillmentComponent;
-
- function testRetrieveDefault(uint256 orderIndex, uint256 itemIndex) public {
- FulfillmentComponent
- memory fulfillmentComponent = FulfillmentComponent({
- orderIndex: orderIndex,
- itemIndex: itemIndex
- });
- FulfillmentComponentLib.saveDefault(fulfillmentComponent, "default");
- FulfillmentComponent
- memory defaultFulfillmentComponent = FulfillmentComponentLib
- .fromDefault("default");
- assertEq(fulfillmentComponent, defaultFulfillmentComponent);
- }
-
- function testComposeEmpty(uint256 orderIndex, uint256 itemIndex) public {
- FulfillmentComponent
- memory fulfillmentComponent = FulfillmentComponentLib
- .empty()
- .withOrderIndex(orderIndex)
- .withItemIndex(itemIndex);
- assertEq(
- fulfillmentComponent,
- FulfillmentComponent({
- orderIndex: orderIndex,
- itemIndex: itemIndex
- })
- );
- }
-
- function testCopy() public {
- FulfillmentComponent
- memory fulfillmentComponent = FulfillmentComponent({
- orderIndex: 1,
- itemIndex: 2
- });
- FulfillmentComponent memory copy = fulfillmentComponent.copy();
- assertEq(fulfillmentComponent, copy);
- fulfillmentComponent.orderIndex = 2;
- assertEq(copy.orderIndex, 1);
- }
-
- function testRetrieveDefaultMany(
- uint256[3] memory orderIndex,
- uint256[3] memory itemIndex
- ) public {
- FulfillmentComponent[]
- memory fulfillmentComponents = new FulfillmentComponent[](3);
- for (uint256 i = 0; i < 3; i++) {
- fulfillmentComponents[i] = FulfillmentComponent({
- orderIndex: orderIndex[i],
- itemIndex: itemIndex[i]
- });
- }
- FulfillmentComponentLib.saveDefaultMany(
- fulfillmentComponents,
- "default"
- );
- FulfillmentComponent[]
- memory defaultFulfillmentComponents = FulfillmentComponentLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(fulfillmentComponents[i], defaultFulfillmentComponents[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/FulfillmentLib.t.sol b/test/foundry/helpers/sol/lib/FulfillmentLib.t.sol
deleted file mode 100644
index a4cf7da9c..000000000
--- a/test/foundry/helpers/sol/lib/FulfillmentLib.t.sol
+++ /dev/null
@@ -1,91 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- FulfillmentLib,
- FulfillmentComponentLib
-} from "../../../../../contracts/helpers/sol/lib/FulfillmentLib.sol";
-import {
- Fulfillment,
- FulfillmentComponent
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-import {
- SeaportArrays
-} from "../../../../../contracts/helpers/sol/lib/SeaportArrays.sol";
-
-contract FulfillmentLibTest is BaseTest {
- using FulfillmentLib for Fulfillment;
- using FulfillmentComponentLib for FulfillmentComponent;
-
- function testRetrieveDefault(
- FulfillmentComponent[] memory offerComponents,
- FulfillmentComponent[] memory considerationComponents
- ) public {
- Fulfillment memory fulfillment = Fulfillment({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents
- });
- FulfillmentLib.saveDefault(fulfillment, "default");
- Fulfillment memory defaultFulfillment = FulfillmentLib.fromDefault(
- "default"
- );
- assertEq(fulfillment, defaultFulfillment);
- }
-
- function testComposeEmpty(
- FulfillmentComponent[] memory offerComponents,
- FulfillmentComponent[] memory considerationComponents
- ) public {
- Fulfillment memory fulfillment = FulfillmentLib
- .empty()
- .withOfferComponents(offerComponents)
- .withConsiderationComponents(considerationComponents);
- assertEq(
- fulfillment,
- Fulfillment({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents
- })
- );
- }
-
- function testCopy() public {
- FulfillmentComponent[] memory offerComponents = SeaportArrays
- .FulfillmentComponents(
- FulfillmentComponent({ orderIndex: 1, itemIndex: 1 })
- );
- FulfillmentComponent[] memory considerationComponents = SeaportArrays
- .FulfillmentComponents(
- FulfillmentComponent({ orderIndex: 2, itemIndex: 2 })
- );
- Fulfillment memory fulfillment = Fulfillment({
- offerComponents: offerComponents,
- considerationComponents: considerationComponents
- });
- Fulfillment memory copy = fulfillment.copy();
- assertEq(fulfillment, copy);
- fulfillment.considerationComponents = offerComponents;
- assertEq(copy.considerationComponents, considerationComponents);
- }
-
- function testRetrieveDefaultMany(
- FulfillmentComponent[][3] memory offerComponents,
- FulfillmentComponent[][3] memory considerationComponents
- ) public {
- Fulfillment[] memory fulfillments = new Fulfillment[](3);
- for (uint256 i = 0; i < 3; i++) {
- fulfillments[i] = Fulfillment({
- offerComponents: offerComponents[i],
- considerationComponents: considerationComponents[i]
- });
- }
- FulfillmentLib.saveDefaultMany(fulfillments, "default");
- Fulfillment[] memory defaultFulfillments = FulfillmentLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(fulfillments[i], defaultFulfillments[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/OfferItemLib.t.sol b/test/foundry/helpers/sol/lib/OfferItemLib.t.sol
deleted file mode 100644
index 195e2fa93..000000000
--- a/test/foundry/helpers/sol/lib/OfferItemLib.t.sol
+++ /dev/null
@@ -1,111 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- OfferItemLib
-} from "../../../../../contracts/helpers/sol/lib/OfferItemLib.sol";
-import {
- OfferItem
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-
-contract OfferItemLibTest is BaseTest {
- using OfferItemLib for OfferItem;
-
- function testRetrieveDefault(
- uint8 _itemType,
- address token,
- uint256 identifier,
- uint256 startAmount,
- uint256 endAmount
- ) public {
- ItemType itemType = toItemType(_itemType);
- OfferItem memory offerItem = OfferItem({
- itemType: ItemType(itemType),
- token: token,
- identifierOrCriteria: identifier,
- startAmount: startAmount,
- endAmount: endAmount == 0 ? 1 : endAmount
- });
- OfferItemLib.saveDefault(offerItem, "default");
- OfferItem memory defaultOfferItem = OfferItemLib.fromDefault("default");
- assertEq(offerItem, defaultOfferItem);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty OfferItem selected.");
- OfferItemLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty OfferItem array selected.");
- OfferItemLib.fromDefaultMany("nonexistent");
- }
-
- function testComposeEmpty(
- uint8 itemType,
- address token,
- uint256 identifier,
- uint256 startAmount,
- uint256 endAmount
- ) public {
- ItemType _itemType = ItemType(bound(itemType, 0, 5));
- OfferItem memory offerItem = OfferItemLib
- .empty()
- .withEndAmount(endAmount)
- .withStartAmount(startAmount)
- .withIdentifierOrCriteria(identifier)
- .withToken(token)
- .withItemType(_itemType);
- assertEq(
- offerItem,
- OfferItem({
- itemType: _itemType,
- token: token,
- identifierOrCriteria: identifier,
- startAmount: startAmount,
- endAmount: endAmount
- })
- );
- }
-
- function testCopy() public {
- OfferItem memory offerItem = OfferItem({
- itemType: ItemType(1),
- token: address(1),
- identifierOrCriteria: 1,
- startAmount: 1,
- endAmount: 1
- });
- OfferItem memory copy = offerItem.copy();
- assertEq(offerItem, copy);
- offerItem.itemType = ItemType(2);
- assertEq(uint8(copy.itemType), 1);
- }
-
- function testRetrieveDefaultMany(
- uint8[3] memory itemType,
- address[3] memory token,
- uint256[3] memory identifier,
- uint256[3] memory startAmount,
- uint256[3] memory endAmount
- ) public {
- OfferItem[] memory offerItems = new OfferItem[](3);
- for (uint256 i = 0; i < 3; i++) {
- itemType[i] = uint8(bound(itemType[i], 0, 5));
- offerItems[i] = OfferItem({
- itemType: ItemType(itemType[i]),
- token: token[i],
- identifierOrCriteria: identifier[i],
- startAmount: startAmount[i],
- endAmount: endAmount[i]
- });
- }
- OfferItemLib.saveDefaultMany(offerItems, "default");
- OfferItem[] memory defaultOfferItems = OfferItemLib.fromDefaultMany(
- "default"
- );
- for (uint256 i = 0; i < 3; i++) {
- assertEq(offerItems[i], defaultOfferItems[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/OrderComponentsLib.t.sol b/test/foundry/helpers/sol/lib/OrderComponentsLib.t.sol
deleted file mode 100644
index f8edca61b..000000000
--- a/test/foundry/helpers/sol/lib/OrderComponentsLib.t.sol
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- OrderComponentsLib
-} from "../../../../../contracts/helpers/sol/lib/OrderComponentsLib.sol";
-import {
- AdditionalRecipientLib
-} from "../../../../../contracts/helpers/sol/lib/AdditionalRecipientLib.sol";
-import {
- OrderComponents,
- OrderParameters,
- OfferItem,
- ConsiderationItem,
- AdditionalRecipient
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import {
- ItemType,
- BasicOrderType,
- OrderType
-} from "../../../../../contracts/lib/ConsiderationEnums.sol";
-import {
- OrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
-import {
- SeaportArrays
-} from "../../../../../contracts/helpers/sol/lib/SeaportStructLib.sol";
-
-contract OrderComponentsLibTest is BaseTest {
- using OrderComponentsLib for OrderComponents;
- using OrderParametersLib for OrderParameters;
-
- function testRetrieveDefault(OrderComponentsBlob memory blob) public {
- OrderComponents memory orderComponents = _fromBlob(blob);
- OrderComponents memory dup = OrderComponentsLib.empty();
- dup.offerer = blob.offerer;
- dup.zone = blob.zone;
- dup.offer = _fromBlobs(blob.offer);
- dup.consideration = _fromBlobs(blob.consideration);
- dup.orderType = toOrderType(blob._orderType);
- dup.startTime = blob.startTime;
- dup.endTime = blob.endTime;
- dup.zoneHash = blob.zoneHash;
- dup.salt = blob.salt;
- dup.conduitKey = blob.conduitKey;
- dup.counter = blob.counter;
- assertEq(orderComponents, dup);
-
- OrderComponentsLib.saveDefault(orderComponents, "default");
- OrderComponents memory defaultOrderComponents = OrderComponentsLib
- .fromDefault("default");
- assertEq(orderComponents, defaultOrderComponents);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty OrderComponents selected.");
- OrderComponentsLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty OrderComponents array selected.");
- OrderComponentsLib.fromDefaultMany("nonexistent");
- }
-
- function testCopy() public {
- OrderComponents memory orderComponents = OrderComponentsLib.empty();
- orderComponents = orderComponents.withOfferer(address(1));
- orderComponents = orderComponents.withZone(address(2));
- orderComponents = orderComponents.withOrderType(OrderType(3));
- orderComponents = orderComponents.withStartTime(4);
- orderComponents = orderComponents.withEndTime(5);
- orderComponents = orderComponents.withZoneHash(bytes32(uint256(6)));
- orderComponents = orderComponents.withSalt(7);
- orderComponents = orderComponents.withConduitKey(bytes32(uint256(8)));
- orderComponents = orderComponents.withCounter(9);
- OfferItem[] memory offer;
-
- {
- offer = SeaportArrays.OfferItems(
- OfferItem({
- itemType: ItemType(1),
- token: address(2),
- identifierOrCriteria: 3,
- startAmount: 4,
- endAmount: 5
- })
- );
- ConsiderationItem[] memory consideration = SeaportArrays
- .ConsiderationItems(
- ConsiderationItem({
- itemType: ItemType(2),
- token: address(7),
- identifierOrCriteria: 8,
- startAmount: 9,
- endAmount: 10,
- recipient: payable(address(11))
- })
- );
-
- orderComponents = orderComponents.withOffer(offer);
- orderComponents = orderComponents.withConsideration(consideration);
- }
-
- OrderComponents memory copy = orderComponents.copy();
- assertEq(orderComponents, copy);
- orderComponents.offerer = address(5678);
- assertEq(copy.offerer, address(1), "copy changed");
-
- offer[0].identifierOrCriteria = 123;
- assertEq(
- copy.offer[0].identifierOrCriteria,
- 3,
- "copy offer identifier changed"
- );
- }
-
- function testRetrieveDefaultMany(
- OrderComponentsBlob[3] memory blobs
- ) public {
- OrderComponents[] memory orderComponents = new OrderComponents[](3);
- for (uint256 i = 0; i < 3; i++) {
- orderComponents[i] = _fromBlob(blobs[i]);
- }
- OrderComponentsLib.saveDefaultMany(orderComponents, "default");
- OrderComponents[] memory defaultOrderComponentss = OrderComponentsLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(orderComponents[i], defaultOrderComponentss[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/OrderLib.t.sol b/test/foundry/helpers/sol/lib/OrderLib.t.sol
deleted file mode 100644
index 2240af428..000000000
--- a/test/foundry/helpers/sol/lib/OrderLib.t.sol
+++ /dev/null
@@ -1,68 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- OrderLib
-} from "../../../../../contracts/helpers/sol/lib/OrderLib.sol";
-import {
- Order,
- OrderParameters
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-import {
- OrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
-
-contract OrderLibTest is BaseTest {
- using OrderParametersLib for OrderParameters;
- using OrderLib for Order;
-
- function testRetrieveDefault(OrderBlob memory orderBlob) public {
- Order memory order = _fromBlob(orderBlob);
- Order memory dup = Order({
- parameters: _fromBlob(orderBlob.parameters),
- signature: orderBlob.signature
- });
- assertEq(order, dup);
- OrderLib.saveDefault(order, "default");
- Order memory defaultOrder = OrderLib.fromDefault("default");
- assertEq(order, defaultOrder);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty Order selected.");
- OrderLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty Order array selected.");
- OrderLib.fromDefaultMany("nonexistent");
- }
-
- function testCopy() public {
- OrderParameters memory parameters = OrderParametersLib
- .empty()
- .withOfferer(address(123));
- Order memory order = Order({
- parameters: parameters,
- signature: "abc"
- });
- Order memory copy = order.copy();
- assertEq(order, copy);
- order.signature = "abcd";
- assertEq(copy.signature, "abc");
- order.parameters.offerer = address(5678);
- assertEq(copy.parameters.offerer, address(123));
- }
-
- function testRetrieveDefaultMany(OrderBlob[3] memory blob) public {
- Order[] memory orders = new Order[](3);
- for (uint256 i = 0; i < 3; i++) {
- orders[i] = _fromBlob(blob[i]);
- }
- OrderLib.saveDefaultMany(orders, "default");
- Order[] memory defaultOrders = OrderLib.fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(orders[i], defaultOrders[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/OrderParametersLib.t.sol b/test/foundry/helpers/sol/lib/OrderParametersLib.t.sol
deleted file mode 100644
index 81209751b..000000000
--- a/test/foundry/helpers/sol/lib/OrderParametersLib.t.sol
+++ /dev/null
@@ -1,130 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- OrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
-import {
- AdditionalRecipientLib
-} from "../../../../../contracts/helpers/sol/lib/AdditionalRecipientLib.sol";
-import {
- OrderParameters,
- OrderParameters,
- OfferItem,
- ConsiderationItem,
- AdditionalRecipient
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import {
- ItemType,
- BasicOrderType,
- OrderType
-} from "../../../../../contracts/lib/ConsiderationEnums.sol";
-import {
- OrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
-import {
- SeaportArrays
-} from "../../../../../contracts/helpers/sol/lib/SeaportArrays.sol";
-
-contract OrderParametersLibTest is BaseTest {
- using OrderParametersLib for OrderParameters;
- using OrderParametersLib for OrderParameters;
-
- function testRetrieveDefault(OrderParametersBlob memory blob) public {
- OrderParameters memory orderParameters = _fromBlob(blob);
- OrderParameters memory dup = OrderParametersLib.empty();
- dup.offerer = blob.offerer;
- dup.zone = blob.zone;
- dup.offer = _fromBlobs(blob.offer);
- dup.consideration = _fromBlobs(blob.consideration);
- dup.orderType = toOrderType(blob._orderType);
- dup.startTime = blob.startTime;
- dup.endTime = blob.endTime;
- dup.zoneHash = blob.zoneHash;
- dup.salt = blob.salt;
- dup.conduitKey = blob.conduitKey;
- dup.totalOriginalConsiderationItems = blob
- .totalOriginalConsiderationItems;
- assertEq(orderParameters, dup);
-
- OrderParametersLib.saveDefault(orderParameters, "default");
- OrderParameters memory defaultOrderParameters = OrderParametersLib
- .fromDefault("default");
- assertEq(orderParameters, defaultOrderParameters);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty OrderParameters selected.");
- OrderParametersLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty OrderParameters array selected.");
- OrderParametersLib.fromDefaultMany("nonexistent");
- }
-
- function testCopy() public {
- OrderParameters memory orderParameters = OrderParametersLib.empty();
- orderParameters = orderParameters.withOfferer(address(1));
- orderParameters = orderParameters.withZone(address(2));
- orderParameters = orderParameters.withOrderType(OrderType(3));
- orderParameters = orderParameters.withStartTime(4);
- orderParameters = orderParameters.withEndTime(5);
- orderParameters = orderParameters.withZoneHash(bytes32(uint256(6)));
- orderParameters = orderParameters.withSalt(7);
- orderParameters = orderParameters.withConduitKey(bytes32(uint256(8)));
- OfferItem[] memory offer;
-
- {
- offer = SeaportArrays.OfferItems(
- OfferItem({
- itemType: ItemType(1),
- token: address(2),
- identifierOrCriteria: 3,
- startAmount: 4,
- endAmount: 5
- })
- );
- ConsiderationItem[] memory consideration = SeaportArrays
- .ConsiderationItems(
- ConsiderationItem({
- itemType: ItemType(2),
- token: address(7),
- identifierOrCriteria: 8,
- startAmount: 9,
- endAmount: 10,
- recipient: payable(address(11))
- })
- );
-
- orderParameters = orderParameters.withOffer(offer);
- orderParameters = orderParameters.withConsideration(consideration);
- }
-
- OrderParameters memory copy = orderParameters.copy();
- assertEq(orderParameters, copy);
- orderParameters.offerer = address(5678);
- assertEq(copy.offerer, address(1), "copy changed");
-
- offer[0].identifierOrCriteria = 123;
- assertEq(
- copy.offer[0].identifierOrCriteria,
- 3,
- "copy offer identifier changed"
- );
- }
-
- function testRetrieveDefaultMany(
- OrderParametersBlob[3] memory blobs
- ) public {
- OrderParameters[] memory orderParameters = new OrderParameters[](3);
- for (uint256 i = 0; i < 3; i++) {
- orderParameters[i] = _fromBlob(blobs[i]);
- }
- OrderParametersLib.saveDefaultMany(orderParameters, "default");
- OrderParameters[] memory defaultOrderParameterss = OrderParametersLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(orderParameters[i], defaultOrderParameterss[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/ReceivedItemLib.t.sol b/test/foundry/helpers/sol/lib/ReceivedItemLib.t.sol
deleted file mode 100644
index e76584b70..000000000
--- a/test/foundry/helpers/sol/lib/ReceivedItemLib.t.sol
+++ /dev/null
@@ -1,112 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- ReceivedItemLib
-} from "../../../../../contracts/helpers/sol/lib/ReceivedItemLib.sol";
-import {
- ReceivedItem
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-
-contract ReceivedItemLibTest is BaseTest {
- using ReceivedItemLib for ReceivedItem;
-
- function testRetrieveDefault(
- uint8 itemType,
- address token,
- uint256 identifier,
- uint256 amount,
- address payable recipient
- ) public {
- itemType = uint8(bound(itemType, 0, 5));
- ReceivedItem memory receivedItem = ReceivedItem(
- ItemType(itemType),
- token,
- identifier,
- amount == 0 ? 1 : amount,
- recipient
- );
- ReceivedItemLib.saveDefault(receivedItem, "default");
- ReceivedItem memory defaultReceivedItem = ReceivedItemLib.fromDefault(
- "default"
- );
- assertEq(receivedItem, defaultReceivedItem);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty ReceivedItem selected.");
- ReceivedItemLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty ReceivedItem array selected.");
- ReceivedItemLib.fromDefaultMany("nonexistent");
- }
-
- function testComposeEmpty(
- uint8 itemType,
- address token,
- uint256 identifier,
- uint256 amount,
- address payable recipient
- ) public {
- itemType = uint8(bound(itemType, 0, 5));
- ReceivedItem memory receivedItem = ReceivedItemLib
- .empty()
- .withItemType(ItemType(itemType))
- .withToken(token)
- .withIdentifier(identifier)
- .withAmount(amount)
- .withRecipient(recipient);
- assertEq(
- receivedItem,
- ReceivedItem({
- itemType: ItemType(itemType),
- token: token,
- identifier: identifier,
- amount: amount,
- recipient: recipient
- })
- );
- }
-
- function testCopy() public {
- ReceivedItem memory receivedItem = ReceivedItem(
- ItemType(1),
- address(1),
- 1,
- 1,
- payable(address(1234))
- );
- ReceivedItem memory copy = receivedItem.copy();
- assertEq(receivedItem, copy);
- receivedItem.itemType = ItemType(2);
- assertEq(uint8(copy.itemType), 1);
- }
-
- function testRetrieveDefaultMany(
- uint8[3] memory itemType,
- address[3] memory token,
- uint256[3] memory identifier,
- uint256[3] memory amount,
- address payable[3] memory recipient
- ) public {
- ReceivedItem[] memory receivedItems = new ReceivedItem[](3);
- for (uint256 i = 0; i < 3; i++) {
- itemType[i] = uint8(bound(itemType[i], 0, 5));
- receivedItems[i] = ReceivedItem(
- ItemType(itemType[i]),
- token[i],
- identifier[i],
- amount[i],
- recipient[i]
- );
- }
- ReceivedItemLib.saveDefaultMany(receivedItems, "default");
- ReceivedItem[] memory defaultReceivedItems = ReceivedItemLib
- .fromDefaultMany("default");
- for (uint256 i = 0; i < 3; i++) {
- assertEq(receivedItems[i], defaultReceivedItems[i]);
- }
- }
-}
diff --git a/test/foundry/helpers/sol/lib/SpentItemLib.t.sol b/test/foundry/helpers/sol/lib/SpentItemLib.t.sol
deleted file mode 100644
index e95f456c2..000000000
--- a/test/foundry/helpers/sol/lib/SpentItemLib.t.sol
+++ /dev/null
@@ -1,98 +0,0 @@
-// SPDX-License-Identifier: MIT
-pragma solidity ^0.8.17;
-
-import { BaseTest } from "../BaseTest.sol";
-import {
- SpentItemLib
-} from "../../../../../contracts/helpers/sol/lib/SpentItemLib.sol";
-import {
- SpentItem
-} from "../../../../../contracts/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../../contracts/lib/ConsiderationEnums.sol";
-
-contract SpentItemLibTest is BaseTest {
- using SpentItemLib for SpentItem;
-
- function testRetrieveDefault(
- uint8 itemType,
- address token,
- uint256 identifier,
- uint256 amount
- ) public {
- itemType = uint8(bound(itemType, 0, 5));
- SpentItem memory spentItem = SpentItem(
- ItemType(itemType),
- token,
- identifier,
- amount == 0 ? 1 : amount
- );
- SpentItemLib.saveDefault(spentItem, "default");
- SpentItem memory defaultSpentItem = SpentItemLib.fromDefault("default");
- assertEq(spentItem, defaultSpentItem);
- }
-
- function testRetrieveNonexistentDefault() public {
- vm.expectRevert("Empty SpentItem selected.");
- SpentItemLib.fromDefault("nonexistent");
-
- vm.expectRevert("Empty SpentItem array selected.");
- SpentItemLib.fromDefaultMany("nonexistent");
- }
-
- function testComposeEmpty(
- uint8 itemType,
- address token,
- uint256 identifier,
- uint256 amount
- ) public {
- itemType = uint8(bound(itemType, 0, 5));
- SpentItem memory spentItem = SpentItemLib
- .empty()
- .withItemType(ItemType(itemType))
- .withToken(token)
- .withIdentifier(identifier)
- .withAmount(amount);
- assertEq(
- spentItem,
- SpentItem({
- itemType: ItemType(itemType),
- token: token,
- identifier: identifier,
- amount: amount
- })
- );
- }
-
- function testCopy() public {
- SpentItem memory spentItem = SpentItem(ItemType(1), address(1), 1, 1);
- SpentItem memory copy = spentItem.copy();
- assertEq(spentItem, copy);
- spentItem.itemType = ItemType(2);
- assertEq(uint8(copy.itemType), 1);
- }
-
- function testRetrieveDefaultMany(
- uint8[3] memory itemType,
- address[3] memory token,
- uint256[3] memory identifier,
- uint256[3] memory amount
- ) public {
- SpentItem[] memory spentItems = new SpentItem[](3);
- for (uint256 i = 0; i < 3; i++) {
- itemType[i] = uint8(bound(itemType[i], 0, 5));
- spentItems[i] = SpentItem(
- ItemType(itemType[i]),
- token[i],
- identifier[i],
- amount[i]
- );
- }
- SpentItemLib.saveDefaultMany(spentItems, "default");
- SpentItem[] memory defaultSpentItems = SpentItemLib.fromDefaultMany(
- "default"
- );
- for (uint256 i = 0; i < 3; i++) {
- assertEq(spentItems[i], defaultSpentItems[i]);
- }
- }
-}
diff --git a/test/foundry/new/BaseOrderTest.sol b/test/foundry/new/BaseOrderTest.sol
index 90fac504a..1f93f3286 100644
--- a/test/foundry/new/BaseOrderTest.sol
+++ b/test/foundry/new/BaseOrderTest.sol
@@ -1,17 +1,17 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { Strings } from "openzeppelin-contracts/contracts/utils/Strings.sol";
+import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { LibString } from "solady/src/utils/LibString.sol";
import {
FulfillAvailableHelper
-} from "seaport-sol/fulfillments/available/FulfillAvailableHelper.sol";
+} from "seaport-sol/src/fulfillments/available/FulfillAvailableHelper.sol";
import {
MatchFulfillmentHelper
-} from "seaport-sol/fulfillments/match/MatchFulfillmentHelper.sol";
+} from "seaport-sol/src/fulfillments/match/MatchFulfillmentHelper.sol";
import {
AdvancedOrderLib,
@@ -23,7 +23,7 @@ import {
OrderLib,
OrderParametersLib,
SeaportArrays
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -34,11 +34,11 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType } from "seaport-sol/src/SeaportEnums.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import { setLabel, BaseSeaportTest } from "./helpers/BaseSeaportTest.sol";
@@ -54,7 +54,7 @@ import { ExpectedBalances } from "./helpers/ExpectedBalances.sol";
import { PreapprovedERC721 } from "./helpers/PreapprovedERC721.sol";
-import { AmountDeriver } from "../../../contracts/lib/AmountDeriver.sol";
+import { AmountDeriver } from "seaport-core/src/lib/AmountDeriver.sol";
import { TestERC20 } from "../../../contracts/test/TestERC20.sol";
@@ -62,19 +62,6 @@ import { TestERC721 } from "../../../contracts/test/TestERC721.sol";
import { TestERC1155 } from "../../../contracts/test/TestERC1155.sol";
-import {
- SeaportValidatorHelper,
- SeaportValidator
-} from "../../../contracts/helpers/order-validator/SeaportValidator.sol";
-
-/**
- * @dev used to store address and key outputs from makeAddrAndKey(name)
- */
-struct Account {
- address addr;
- uint256 key;
-}
-
/**
* @dev This is a base test class for cases that depend on pre-deployed token
* contracts. Note that it is different from the BaseOrderTest in the
@@ -117,8 +104,6 @@ contract BaseOrderTest is
SeaportInterface seaport;
}
- SeaportValidatorHelper validatorHelper;
- SeaportValidator validator;
FulfillAvailableHelper fulfill;
MatchFulfillmentHelper matcher;
@@ -180,13 +165,6 @@ contract BaseOrderTest is
_configureStructDefaults();
- validatorHelper = new SeaportValidatorHelper();
-
- validator = new SeaportValidator(
- address(validatorHelper),
- address(getConduitController())
- );
-
fulfill = new FulfillAvailableHelper();
matcher = new MatchFulfillmentHelper();
}
@@ -301,12 +279,14 @@ contract BaseOrderTest is
}
/**
- * @dev convenience wrapper for makeAddrAndKey
+ * @dev Wrapper for forge-std's makeAccount that has public visibility
+ * instead of internal visibility, so that we can access it in
+ * libraries.
*/
- function makeAccount(string memory name) public returns (Account memory) {
- (address addr, uint256 key) = makeAddrAndKey(name);
- setLabel(addr, name);
- return Account(addr, key);
+ function makeAccountWrapper(
+ string memory name
+ ) public returns (Account memory) {
+ return makeAccount(name);
}
/**
@@ -316,7 +296,7 @@ contract BaseOrderTest is
function makeAndAllocateAccount(
string memory name
) internal returns (Account memory) {
- Account memory account = makeAccount(name);
+ Account memory account = makeAccountWrapper(name);
allocateTokensAndApprovals(account.addr, type(uint128).max);
return account;
}
diff --git a/test/foundry/new/CriteriaResolverHelper.t.sol b/test/foundry/new/CriteriaResolverHelper.t.sol
index f1eef99f5..595e11987 100644
--- a/test/foundry/new/CriteriaResolverHelper.t.sol
+++ b/test/foundry/new/CriteriaResolverHelper.t.sol
@@ -11,7 +11,7 @@ import { Test } from "forge-std/Test.sol";
// OfferItemLib,
// OrderParametersLib,
// SeaportArrays
-// } from "seaport-sol/SeaportSol.sol";
+// } from "seaport-sol/src/SeaportSol.sol";
import { CriteriaResolverHelper } from "./helpers/CriteriaResolverHelper.sol";
diff --git a/test/foundry/new/ExpectedBalances.t.sol b/test/foundry/new/ExpectedBalances.t.sol
index db639d61e..be13e4625 100644
--- a/test/foundry/new/ExpectedBalances.t.sol
+++ b/test/foundry/new/ExpectedBalances.t.sol
@@ -3,9 +3,9 @@ pragma solidity ^0.8.17;
import { stdError, Test } from "forge-std/Test.sol";
-import { Execution, ReceivedItem } from "seaport-sol/SeaportStructs.sol";
+import { Execution, ReceivedItem } from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
import {
BalanceErrorMessages,
diff --git a/test/foundry/new/FractionUtil.t.sol b/test/foundry/new/FractionUtil.t.sol
index 53c74706c..16470468e 100644
--- a/test/foundry/new/FractionUtil.t.sol
+++ b/test/foundry/new/FractionUtil.t.sol
@@ -34,13 +34,13 @@ contract FractionUtilTest is Test {
);
assertEq(
results.finalFilledNumerator,
- 11,
- "Final filled numerator should be 11"
+ 33,
+ "Final filled numerator should be 33"
);
assertEq(
results.finalFilledDenominator,
- 12,
- "Final filled denominator should be 12"
+ 36,
+ "Final filled denominator should be 36"
);
assertEq(
uint256(results.status),
@@ -75,13 +75,13 @@ contract FractionUtilTest is Test {
);
assertEq(
results1.finalFilledNumerator,
- 6,
- "Final filled numerator should be 6"
+ 18,
+ "Final filled numerator should be 18"
);
assertEq(
results1.finalFilledDenominator,
- 6,
- "Final filled denominator should be 6"
+ 18,
+ "Final filled denominator should be 18"
);
assertEq(
uint256(results1.status),
@@ -118,13 +118,13 @@ contract FractionUtilTest is Test {
);
assertEq(
results2.finalFilledNumerator,
- 3,
- "Final filled numerator should be 3"
+ 1,
+ "Final filled numerator should be 1"
);
assertEq(
results2.finalFilledDenominator,
- 3,
- "Final filled denominator should be 3"
+ 1,
+ "Final filled denominator should be 1"
);
assertEq(
uint256(results2.status),
@@ -161,13 +161,13 @@ contract FractionUtilTest is Test {
);
assertEq(
results3.finalFilledNumerator,
- 3,
- "Final filled numerator should be 3"
+ 1,
+ "Final filled numerator should be 1"
);
assertEq(
results3.finalFilledDenominator,
- 3,
- "Final filled denominator should be 3"
+ 1,
+ "Final filled denominator should be 1"
);
assertEq(
uint256(results3.status),
diff --git a/test/foundry/new/FuzzEngine.t.sol b/test/foundry/new/FuzzEngine.t.sol
index e0a5631e9..87017a3fd 100644
--- a/test/foundry/new/FuzzEngine.t.sol
+++ b/test/foundry/new/FuzzEngine.t.sol
@@ -12,7 +12,7 @@ import {
OrderParametersLib,
SeaportArrays,
ZoneParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
ConsiderationItem,
@@ -25,11 +25,11 @@ import {
OrderComponents,
OrderParameters,
OrderType
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import {
HashValidationZoneOfferer
@@ -376,8 +376,10 @@ contract FuzzEngineTest is FuzzEngine {
expectedActions[2] = SeaportInterface.matchOrders.selector;
expectedActions[3] = SeaportInterface.matchAdvancedOrders.selector;
// TODO: undo pended actions (cancel, validate)
- /** expectedActions[4] = SeaportInterface.cancel.selector;
- expectedActions[5] = SeaportInterface.validate.selector; */
+ /**
+ * expectedActions[4] = SeaportInterface.cancel.selector;
+ * expectedActions[5] = SeaportInterface.validate.selector;
+ */
FuzzTestContext memory context = FuzzTestContextLib
.from({
@@ -519,21 +521,23 @@ contract FuzzEngineTest is FuzzEngine {
);
// TODO: undo pended actions (match, cancel, validate)
- /** context = FuzzTestContextLib.from({
- orders: orders,
- seaport: getSeaport(),
- caller: address(this),
- fuzzParams: FuzzParams({ seed: 4 })
- });
- assertEq(context.action(), SeaportInterface.cancel.selector);
-
- context = FuzzTestContextLib.from({
- orders: orders,
- seaport: getSeaport(),
- caller: address(this),
- fuzzParams: FuzzParams({ seed: 5 })
- });
- assertEq(context.action(), SeaportInterface.validate.selector); */
+ /**
+ * context = FuzzTestContextLib.from({
+ * orders: orders,
+ * seaport: getSeaport(),
+ * caller: address(this),
+ * fuzzParams: FuzzParams({ seed: 4 })
+ * });
+ * assertEq(context.action(), SeaportInterface.cancel.selector);
+ *
+ * context = FuzzTestContextLib.from({
+ * orders: orders,
+ * seaport: getSeaport(),
+ * caller: address(this),
+ * fuzzParams: FuzzParams({ seed: 5 })
+ * });
+ * assertEq(context.action(), SeaportInterface.validate.selector);
+ */
}
/// @dev Call exec for a single standard order.
@@ -1723,8 +1727,8 @@ contract FuzzEngineTest is FuzzEngine {
.withChecks(checks)
.withMaximumFulfilled(2);
- context.expectations.expectedZoneCalldataHash = advancedOrders
- .getExpectedZoneCalldataHash(
+ context.expectations.expectedZoneValidateCalldataHashes = advancedOrders
+ .getExpectedZoneValidateCalldataHash(
address(getSeaport()),
address(this),
new CriteriaResolver[](0),
diff --git a/test/foundry/new/FuzzGenerators.t.sol b/test/foundry/new/FuzzGenerators.t.sol
index 82ce643d8..399c13bc4 100644
--- a/test/foundry/new/FuzzGenerators.t.sol
+++ b/test/foundry/new/FuzzGenerators.t.sol
@@ -8,9 +8,9 @@ import {
ConsiderationItemSpace,
OfferItemSpace,
OrderComponentsSpace
-} from "seaport-sol/StructSpace.sol";
+} from "seaport-sol/src/StructSpace.sol";
-import { AdvancedOrder, ItemType } from "seaport-sol/SeaportStructs.sol";
+import { AdvancedOrder, ItemType } from "seaport-sol/src/SeaportStructs.sol";
import {
Amount,
@@ -32,7 +32,7 @@ import {
UnavailableReason,
Zone,
ZoneHash
-} from "seaport-sol/SpaceEnums.sol";
+} from "seaport-sol/src/SpaceEnums.sol";
import { BaseOrderTest } from "./BaseOrderTest.sol";
@@ -56,8 +56,9 @@ import {
} from "../../../contracts/test/HashCalldataContractOfferer.sol";
import {
+ DefaultFulfillmentGeneratorLib,
FulfillmentGeneratorLib
-} from "seaport-sol/fulfillments/lib/FulfillmentLib.sol";
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
contract FuzzGeneratorsTest is BaseOrderTest {
using LibPRNG for LibPRNG.PRNG;
@@ -90,12 +91,12 @@ contract FuzzGeneratorsTest is BaseOrderTest {
erc1155s: erc1155s,
self: address(this),
caller: address(this),
- alice: makeAccount("alice"),
- bob: makeAccount("bob"),
- carol: makeAccount("carol"),
- dillon: makeAccount("dillon"),
- eve: makeAccount("eve"),
- frank: makeAccount("frank"),
+ alice: makeAccountWrapper("alice"),
+ bob: makeAccountWrapper("bob"),
+ carol: makeAccountWrapper("carol"),
+ dillon: makeAccountWrapper("dillon"),
+ eve: makeAccountWrapper("eve"),
+ frank: makeAccountWrapper("frank"),
starting721offerIndex: 1,
starting721considerationIndex: 1,
potential1155TokenIds: potential1155TokenIds,
@@ -122,7 +123,8 @@ contract FuzzGeneratorsTest is BaseOrderTest {
recipient: FulfillmentRecipient.ZERO,
conduit: ConduitChoice.NONE,
caller: Caller.TEST_CONTRACT,
- strategy: FulfillmentGeneratorLib.getDefaultFulfillmentStrategy()
+ strategy: DefaultFulfillmentGeneratorLib
+ .getDefaultFulfillmentStrategy()
});
AdvancedOrder[] memory orders = AdvancedOrdersSpaceGenerator.generate(
space,
@@ -168,7 +170,8 @@ contract FuzzGeneratorsTest is BaseOrderTest {
recipient: FulfillmentRecipient.ZERO,
conduit: ConduitChoice.NONE,
caller: Caller.TEST_CONTRACT,
- strategy: FulfillmentGeneratorLib.getDefaultFulfillmentStrategy()
+ strategy: DefaultFulfillmentGeneratorLib
+ .getDefaultFulfillmentStrategy()
});
AdvancedOrder[] memory orders = AdvancedOrdersSpaceGenerator.generate(
space,
@@ -223,7 +226,8 @@ contract FuzzGeneratorsTest is BaseOrderTest {
recipient: FulfillmentRecipient.ZERO,
conduit: ConduitChoice.NONE,
caller: Caller.TEST_CONTRACT,
- strategy: FulfillmentGeneratorLib.getDefaultFulfillmentStrategy()
+ strategy: DefaultFulfillmentGeneratorLib
+ .getDefaultFulfillmentStrategy()
});
AdvancedOrder[] memory orders = AdvancedOrdersSpaceGenerator.generate(
space,
@@ -289,7 +293,8 @@ contract FuzzGeneratorsTest is BaseOrderTest {
recipient: FulfillmentRecipient.ZERO,
conduit: ConduitChoice.NONE,
caller: Caller.TEST_CONTRACT,
- strategy: FulfillmentGeneratorLib.getDefaultFulfillmentStrategy()
+ strategy: DefaultFulfillmentGeneratorLib
+ .getDefaultFulfillmentStrategy()
});
AdvancedOrder[] memory orders = AdvancedOrdersSpaceGenerator.generate(
space,
diff --git a/test/foundry/new/FuzzHelpers.t.sol b/test/foundry/new/FuzzHelpers.t.sol
index d5288f091..c26bb617a 100644
--- a/test/foundry/new/FuzzHelpers.t.sol
+++ b/test/foundry/new/FuzzHelpers.t.sol
@@ -10,7 +10,7 @@ import {
OrderComponentsLib,
OrderLib,
OrderParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
ConsiderationItem,
@@ -20,13 +20,13 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import {
BasicOrderType,
ItemType,
OrderType
-} from "seaport-sol/SeaportEnums.sol";
+} from "seaport-sol/src/SeaportEnums.sol";
import { BaseOrderTest } from "./BaseOrderTest.sol";
diff --git a/test/foundry/new/FuzzInscribers.t.sol b/test/foundry/new/FuzzInscribers.t.sol
index 685fafcbe..a0304b9a0 100644
--- a/test/foundry/new/FuzzInscribers.t.sol
+++ b/test/foundry/new/FuzzInscribers.t.sol
@@ -8,7 +8,7 @@ import {
OfferItemLib,
OrderComponentsLib,
OrderLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -16,9 +16,9 @@ import {
CriteriaResolver,
OfferItem,
OrderComponents
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType } from "seaport-sol/src/SeaportEnums.sol";
import { BaseOrderTest } from "./BaseOrderTest.sol";
@@ -390,7 +390,9 @@ contract FuzzHelpersTest is BaseOrderTest {
keccak256(abi.encodePacked(profile)) ==
keccak256(abi.encodePacked("test")) ||
keccak256(abi.encodePacked(profile)) ==
- keccak256(abi.encodePacked("lite"))
+ keccak256(abi.encodePacked("lite")) ||
+ keccak256(abi.encodePacked(profile)) ==
+ keccak256(abi.encodePacked("reference"))
) {
expectedReadAccessCount = 1;
}
diff --git a/test/foundry/new/FuzzSetup.t.sol b/test/foundry/new/FuzzSetup.t.sol
index 276ebf7df..ae73add96 100644
--- a/test/foundry/new/FuzzSetup.t.sol
+++ b/test/foundry/new/FuzzSetup.t.sol
@@ -10,13 +10,16 @@ import {
OrderComponentsLib,
OrderLib,
OrderParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
-import { OrderComponentsSpace } from "seaport-sol/StructSpace.sol";
+import { OrderComponentsSpace } from "seaport-sol/src/StructSpace.sol";
-import { OrderDetails } from "seaport-sol/fulfillments/lib/Structs.sol";
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
-import { OrderStatusEnum, UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import {
+ OrderStatusEnum,
+ UnavailableReason
+} from "seaport-sol/src/SpaceEnums.sol";
import {
AdvancedOrder,
@@ -27,11 +30,11 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
-import { Account, BaseOrderTest } from "./BaseOrderTest.sol";
+import { BaseOrderTest } from "./BaseOrderTest.sol";
import {
FuzzParams,
@@ -62,7 +65,7 @@ contract FuzzSetupTest is BaseOrderTest, FuzzSetup {
using FuzzEngineLib for FuzzTestContext;
using FuzzDerivers for FuzzTestContext;
- Account charlie = makeAccount("charlie");
+ Account charlie = makeAccountWrapper("charlie");
function test_setUpOfferItems_erc20() public {
assertEq(erc20s[0].balanceOf(charlie.addr), 0);
diff --git a/test/foundry/new/SeaportNavigator.t.sol b/test/foundry/new/SeaportNavigator.t.sol
new file mode 100644
index 000000000..631765263
--- /dev/null
+++ b/test/foundry/new/SeaportNavigator.t.sol
@@ -0,0 +1,678 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ AdvancedOrderLib,
+ ConsiderationInterface,
+ ConsiderationItemLib,
+ CriteriaResolver,
+ OfferItemLib,
+ OrderComponentsLib,
+ OrderLib,
+ OrderParametersLib
+} from "seaport-sol/src/SeaportSol.sol";
+
+import {
+ ConsiderationItem,
+ OfferItem,
+ OrderParameters,
+ OrderComponents,
+ Order,
+ AdvancedOrder
+} from "seaport-sol/src/SeaportStructs.sol";
+
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
+
+import {
+ AggregationStrategy,
+ FulfillAvailableStrategy,
+ FulfillmentStrategy,
+ MatchStrategy
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
+
+import {
+ NavigatorRequest,
+ NavigatorResponse,
+ SeaportNavigator
+} from "../../../contracts/helpers/navigator/SeaportNavigator.sol";
+
+import {
+ TokenIdNotFound
+} from "../../../contracts/helpers/navigator/lib/CriteriaHelperLib.sol";
+
+import {
+ NavigatorAdvancedOrder,
+ NavigatorAdvancedOrderLib
+} from "../../../contracts/helpers/navigator/lib/NavigatorAdvancedOrderLib.sol";
+
+import {
+ OrderStructureLib
+} from "../../../contracts/helpers/navigator/lib/OrderStructureLib.sol";
+
+import { BaseOrderTest } from "./BaseOrderTest.sol";
+
+import { SeaportValidatorTest } from "./SeaportValidatorTest.sol";
+
+import { SeaportNavigatorTest } from "./SeaportNavigatorTest.sol";
+
+import { TestERC721 } from "../../../contracts/test/TestERC721.sol";
+
+contract SeaportNavigatorTestSuite is
+ BaseOrderTest,
+ SeaportValidatorTest,
+ SeaportNavigatorTest
+{
+ using AdvancedOrderLib for AdvancedOrder;
+ using ConsiderationItemLib for ConsiderationItem;
+ using NavigatorAdvancedOrderLib for NavigatorAdvancedOrder;
+ using OfferItemLib for OfferItem;
+ using OrderComponentsLib for OrderComponents;
+ using OrderLib for Order;
+ using OrderParametersLib for OrderParameters;
+ using OrderStructureLib for AdvancedOrder;
+
+ string constant SINGLE_ERC721_SINGLE_ERC20 = "SINGLE_ERC721_SINGLE_ERC20";
+ string constant SINGLE_ERC721_WITH_CRITERIA_SINGLE_ERC721_WITH_CRITERIA =
+ "SINGLE_ERC721_WITH_CRITERIA_SINGLE_ERC721_WITH_CRITERIA";
+
+ function setUp() public override(BaseOrderTest, SeaportValidatorTest) {
+ super.setUp();
+
+ OrderLib
+ .empty()
+ .withParameters(
+ OrderComponentsLib.fromDefault(STANDARD).toOrderParameters()
+ )
+ .saveDefault(STANDARD);
+
+ // Set up and store order with single ERC721 offer item
+ OfferItem[] memory offer = new OfferItem[](1);
+ offer[0] = OfferItemLib
+ .empty()
+ .withItemType(ItemType.ERC721)
+ .withToken(address(erc721s[0]))
+ .withIdentifierOrCriteria(1)
+ .withAmount(1);
+ OrderParameters memory parameters = OrderComponentsLib
+ .fromDefault(STANDARD)
+ .withStartTime(block.timestamp)
+ .withEndTime(block.timestamp + 1)
+ .toOrderParameters()
+ .withOffer(offer);
+ parameters.saveDefault(SINGLE_ERC721);
+ OrderLib.empty().withParameters(parameters).saveDefault(SINGLE_ERC721);
+
+ ConsiderationItem[] memory _consideration = new ConsiderationItem[](1);
+ _consideration[0] = ConsiderationItemLib
+ .empty()
+ .withItemType(ItemType.ERC20)
+ .withToken(address(erc20s[0]))
+ .withAmount(1);
+ parameters = OrderParametersLib
+ .fromDefault(SINGLE_ERC721)
+ .withConsideration(_consideration)
+ .withTotalOriginalConsiderationItems(1);
+ OrderLib.empty().withParameters(parameters).saveDefault(
+ SINGLE_ERC721_SINGLE_ERC20
+ );
+
+ offer[0] = OfferItemLib
+ .empty()
+ .withItemType(ItemType.ERC721_WITH_CRITERIA)
+ .withToken(address(erc721s[0]))
+ .withAmount(1);
+ _consideration[0] = ConsiderationItemLib
+ .empty()
+ .withItemType(ItemType.ERC721_WITH_CRITERIA)
+ .withToken(address(erc721s[0]))
+ .withAmount(1);
+ parameters = OrderParametersLib
+ .fromDefault(SINGLE_ERC721)
+ .withOffer(offer)
+ .withConsideration(_consideration)
+ .withTotalOriginalConsiderationItems(1);
+ parameters.saveDefault(
+ SINGLE_ERC721_WITH_CRITERIA_SINGLE_ERC721_WITH_CRITERIA
+ );
+ OrderLib.empty().withParameters(parameters).saveDefault(
+ SINGLE_ERC721_WITH_CRITERIA_SINGLE_ERC721_WITH_CRITERIA
+ );
+ }
+
+ function test_basicOrder() public {
+ NavigatorAdvancedOrder[] memory orders = new NavigatorAdvancedOrder[](
+ 1
+ );
+ AdvancedOrder memory advancedOrder = OrderLib
+ .fromDefault(SINGLE_ERC721_SINGLE_ERC20)
+ .toAdvancedOrder(1, 1, "");
+ orders[0] = NavigatorAdvancedOrderLib.fromAdvancedOrder(advancedOrder);
+
+ FulfillmentStrategy memory fulfillmentStrategy = FulfillmentStrategy({
+ aggregationStrategy: AggregationStrategy.MAXIMUM,
+ fulfillAvailableStrategy: FulfillAvailableStrategy.KEEP_ALL,
+ matchStrategy: MatchStrategy.MAX_INCLUSION
+ });
+ NavigatorResponse memory res = navigator.prepare(
+ NavigatorRequest({
+ seaport: seaport,
+ validator: validator,
+ orders: orders,
+ caller: offerer1.addr,
+ nativeTokensSupplied: 0,
+ fulfillerConduitKey: bytes32(0),
+ recipient: address(this),
+ maximumFulfilled: type(uint256).max,
+ seed: 0,
+ fulfillmentStrategy: fulfillmentStrategy,
+ criteriaResolvers: new CriteriaResolver[](0),
+ preferMatch: false
+ })
+ );
+ assertEq(
+ res.suggestedActionName,
+ "fulfillBasicOrder_efficient_6GL6yc",
+ "unexpected actionName selected"
+ );
+ assertEq(
+ res.suggestedCallData,
+ abi.encodeCall(
+ ConsiderationInterface.fulfillBasicOrder_efficient_6GL6yc,
+ (
+ advancedOrder.toBasicOrderParameters(
+ advancedOrder.getBasicOrderType()
+ )
+ )
+ ),
+ "unexpected suggested calldata"
+ );
+
+ assertEq(
+ res.validationErrors.length,
+ 1,
+ "unexpected validationErrors length"
+ );
+ assertEq(
+ res.validationErrors[0].errors.length,
+ 4,
+ "unexpected validationErrors[0].errors length"
+ );
+
+ assertEq(
+ res.validationErrors[0].warnings.length,
+ 1,
+ "unexpected validationErrors[0].warnings length"
+ );
+ assertEq(res.orderDetails.length, 1, "unexpected orderDetails length");
+ assertEq(
+ res.offerFulfillments.length,
+ 1,
+ "unexpected offerFulfillments length"
+ );
+ assertEq(
+ res.considerationFulfillments.length,
+ 1,
+ "unexpected considerationFulfillments length"
+ );
+ assertEq(res.fulfillments.length, 0, "unexpected fulfillments length");
+ assertEq(
+ res.unspentOfferComponents.length,
+ 1,
+ "unexpected unspentOfferComponents length"
+ );
+ assertEq(
+ res.unmetConsiderationComponents.length,
+ 1,
+ "unexpected unmetConsiderationComponents length"
+ );
+ assertEq(
+ res.explicitExecutions.length,
+ 0,
+ "unexpected explicitExecutions length"
+ );
+ assertEq(
+ res.implicitExecutions.length,
+ 2,
+ "unexpected implicitExecutions length"
+ );
+ assertEq(
+ res.implicitExecutionsPre.length,
+ 0,
+ "unexpected implicitExecutionsPre length"
+ );
+ assertEq(
+ res.implicitExecutionsPost.length,
+ 0,
+ "unexpected implicitExecutionsPost length"
+ );
+ assertEq(
+ res.nativeTokensReturned,
+ 0,
+ "unexpected nativeTokensReturned amount"
+ );
+ }
+
+ function test_simpleOrder() public {
+ NavigatorAdvancedOrder[] memory orders = new NavigatorAdvancedOrder[](
+ 1
+ );
+ AdvancedOrder memory advancedOrder = OrderLib
+ .fromDefault(SINGLE_ERC721)
+ .toAdvancedOrder(1, 1, "");
+ orders[0] = NavigatorAdvancedOrderLib.fromAdvancedOrder(advancedOrder);
+
+ FulfillmentStrategy memory fulfillmentStrategy = FulfillmentStrategy({
+ aggregationStrategy: AggregationStrategy.MAXIMUM,
+ fulfillAvailableStrategy: FulfillAvailableStrategy.KEEP_ALL,
+ matchStrategy: MatchStrategy.MAX_INCLUSION
+ });
+ NavigatorResponse memory res = navigator.prepare(
+ NavigatorRequest({
+ seaport: seaport,
+ validator: validator,
+ orders: orders,
+ caller: offerer1.addr,
+ nativeTokensSupplied: 0,
+ fulfillerConduitKey: bytes32(0),
+ recipient: address(this),
+ maximumFulfilled: type(uint256).max,
+ seed: 0,
+ fulfillmentStrategy: fulfillmentStrategy,
+ criteriaResolvers: new CriteriaResolver[](0),
+ preferMatch: false
+ })
+ );
+ assertEq(
+ res.suggestedActionName,
+ "fulfillOrder",
+ "unexpected actionName selected"
+ );
+ assertEq(
+ res.suggestedCallData,
+ abi.encodeCall(
+ ConsiderationInterface.fulfillOrder,
+ (advancedOrder.toOrder(), bytes32(0))
+ ),
+ "unexpected suggested calldata"
+ );
+ assertEq(
+ res.validationErrors.length,
+ 1,
+ "unexpected validationErrors length"
+ );
+ assertEq(
+ res.validationErrors[0].errors.length,
+ 4,
+ "unexpected validationErrors[0].errors length"
+ );
+ assertEq(
+ res.validationErrors[0].warnings.length,
+ 2,
+ "unexpected validationErrors[0].warnings length"
+ );
+ assertEq(res.orderDetails.length, 1, "unexpected orderDetails length");
+ assertEq(
+ res.offerFulfillments.length,
+ 1,
+ "unexpected offerFulfillments length"
+ );
+ assertEq(
+ res.considerationFulfillments.length,
+ 0,
+ "unexpected considerationFulfillments length"
+ );
+ assertEq(res.fulfillments.length, 0, "unexpected fulfillments length");
+ assertEq(
+ res.unspentOfferComponents.length,
+ 1,
+ "unexpected unspentOfferComponents length"
+ );
+ assertEq(
+ res.unmetConsiderationComponents.length,
+ 0,
+ "unexpected unmetConsiderationComponents length"
+ );
+ assertEq(
+ res.explicitExecutions.length,
+ 0,
+ "unexpected explicitExecutions length"
+ );
+ assertEq(
+ res.implicitExecutions.length,
+ 1,
+ "unexpected implicitExecutions length"
+ );
+ assertEq(
+ res.implicitExecutionsPre.length,
+ 0,
+ "unexpected implicitExecutionsPre length"
+ );
+ assertEq(
+ res.implicitExecutionsPost.length,
+ 0,
+ "unexpected implicitExecutionsPost length"
+ );
+ assertEq(
+ res.nativeTokensReturned,
+ 0,
+ "unexpected nativeTokensReturned amount"
+ );
+ }
+
+ function test_simpleOrderWithNativeReturned() public {
+ NavigatorAdvancedOrder[] memory orders = new NavigatorAdvancedOrder[](
+ 1
+ );
+
+ Order memory order = OrderLib.fromDefault(SINGLE_ERC721).copy();
+ AdvancedOrder memory advancedOrder = order.toAdvancedOrder(
+ 1,
+ 1,
+ "dummy"
+ );
+
+ address offerer = offerer1.addr;
+ OfferItem memory item = advancedOrder.parameters.offer[0];
+ TestERC721(item.token).mint(offerer, item.identifierOrCriteria);
+ vm.prank(offerer);
+ TestERC721(item.token).setApprovalForAll(address(seaport), true);
+
+ ConsiderationItem[] memory consideration = new ConsiderationItem[](1);
+ consideration[0] = ConsiderationItemLib
+ .empty()
+ .withItemType(ItemType.NATIVE)
+ .withToken(address(0))
+ .withAmount(1 ether)
+ .withRecipient(offerer);
+
+ advancedOrder.parameters = advancedOrder
+ .parameters
+ .withTotalConsideration(consideration)
+ .withOfferer(offerer);
+
+ uint256 counter = getSeaport().getCounter(offerer1.addr);
+ bytes32 orderHash = getSeaport().getOrderHash(
+ advancedOrder.parameters.toOrderComponents(counter)
+ );
+ advancedOrder = advancedOrder.withSignature(
+ signOrder(getSeaport(), offerer1.key, orderHash)
+ );
+
+ orders[0] = NavigatorAdvancedOrderLib.fromAdvancedOrder(advancedOrder);
+
+ FulfillmentStrategy memory fulfillmentStrategy = FulfillmentStrategy({
+ aggregationStrategy: AggregationStrategy.MAXIMUM,
+ fulfillAvailableStrategy: FulfillAvailableStrategy.KEEP_ALL,
+ matchStrategy: MatchStrategy.MAX_INCLUSION
+ });
+
+ NavigatorResponse memory res = navigator.prepare(
+ NavigatorRequest({
+ seaport: seaport,
+ validator: validator,
+ orders: orders,
+ caller: address(this),
+ nativeTokensSupplied: 2 ether,
+ fulfillerConduitKey: bytes32(0),
+ recipient: address(this),
+ maximumFulfilled: 1,
+ seed: 0,
+ fulfillmentStrategy: fulfillmentStrategy,
+ criteriaResolvers: new CriteriaResolver[](0),
+ preferMatch: false
+ })
+ );
+
+ assertEq(
+ res.suggestedActionName,
+ "fulfillAdvancedOrder",
+ "unexpected actionName selected"
+ );
+ assertEq(
+ res.suggestedCallData,
+ abi.encodeCall(
+ ConsiderationInterface.fulfillAdvancedOrder,
+ (
+ advancedOrder,
+ new CriteriaResolver[](0),
+ bytes32(0),
+ address(this)
+ )
+ ),
+ "unexpected suggested calldata"
+ );
+
+ if (
+ keccak256(bytes(vm.envOr("FOUNDRY_PROFILE", string("test")))) !=
+ keccak256(bytes(string("reference")))
+ ) {
+ assertEq(
+ res.validationErrors.length,
+ 1,
+ "unexpected validationErrors length"
+ );
+ assertEq(
+ res.validationErrors[0].errors.length,
+ 0,
+ "unexpected validationErrors[0].errors length"
+ );
+ }
+
+ assertEq(res.orderDetails.length, 1, "unexpected orderDetails length");
+ assertEq(
+ res.offerFulfillments.length,
+ 1,
+ "unexpected offerFulfillments length"
+ );
+ assertEq(
+ res.considerationFulfillments.length,
+ 1,
+ "unexpected considerationFulfillments length"
+ );
+ assertEq(res.fulfillments.length, 0, "unexpected fulfillments length");
+ // Specific to match* methods.
+ assertEq(
+ res.unspentOfferComponents.length,
+ 1,
+ "unexpected unspentOfferComponents length"
+ );
+ // Specific to match* methods.
+ assertEq(
+ res.unmetConsiderationComponents.length,
+ 1,
+ "unexpected unmetConsiderationComponents length"
+ );
+ // No fulfillment related stuff in this case, so no explicit executions.
+ assertEq(
+ res.explicitExecutions.length,
+ 0,
+ "unexpected explicitExecutions length"
+ );
+
+ // 2 ether to seaport
+ // ERC721 from seller to buyer
+ // 1 ether from seaport to buyer
+ // 1 ether from buyer to seller
+ assertEq(
+ res.implicitExecutions.length,
+ 4,
+ "unexpected implicitExecutions length"
+ );
+
+ assertEq(
+ res.implicitExecutionsPre.length,
+ 0,
+ "unexpected implicitExecutionsPre length"
+ );
+ assertEq(
+ res.implicitExecutionsPost.length,
+ 0,
+ "unexpected implicitExecutionsPost length"
+ );
+ assertEq(
+ res.nativeTokensReturned,
+ 1 ether,
+ "unexpected nativeTokensReturned amount"
+ );
+ }
+
+ function test_inferredCriteria() public {
+ NavigatorAdvancedOrder[] memory orders = new NavigatorAdvancedOrder[](
+ 1
+ );
+ AdvancedOrder memory advancedOrder = OrderLib
+ .fromDefault(
+ SINGLE_ERC721_WITH_CRITERIA_SINGLE_ERC721_WITH_CRITERIA
+ )
+ .toAdvancedOrder(1, 1, "");
+ orders[0] = NavigatorAdvancedOrderLib.fromAdvancedOrder(advancedOrder);
+
+ uint256[] memory offerIds = new uint256[](3);
+ offerIds[0] = 1;
+ offerIds[1] = 2;
+ offerIds[2] = 3;
+ orders[0].parameters.offer[0].candidateIdentifiers = offerIds;
+ orders[0].parameters.offer[0].identifier = 1;
+
+ uint256[] memory considerationIds = new uint256[](3);
+ considerationIds[0] = 4;
+ considerationIds[1] = 5;
+ considerationIds[2] = 6;
+ orders[0]
+ .parameters
+ .consideration[0]
+ .candidateIdentifiers = considerationIds;
+ orders[0].parameters.consideration[0].identifier = 4;
+
+ FulfillmentStrategy memory fulfillmentStrategy = FulfillmentStrategy({
+ aggregationStrategy: AggregationStrategy.MAXIMUM,
+ fulfillAvailableStrategy: FulfillAvailableStrategy.KEEP_ALL,
+ matchStrategy: MatchStrategy.MAX_INCLUSION
+ });
+ NavigatorResponse memory res = navigator.prepare(
+ NavigatorRequest({
+ seaport: seaport,
+ validator: validator,
+ orders: orders,
+ caller: offerer1.addr,
+ nativeTokensSupplied: 0,
+ fulfillerConduitKey: bytes32(0),
+ recipient: address(this),
+ maximumFulfilled: type(uint256).max,
+ seed: 0,
+ fulfillmentStrategy: fulfillmentStrategy,
+ criteriaResolvers: new CriteriaResolver[](0),
+ preferMatch: false
+ })
+ );
+
+ assertEq(
+ res.orders[0].parameters.offer[0].identifierOrCriteria,
+ uint256(navigator.criteriaRoot(offerIds))
+ );
+ assertEq(
+ res.orders[0].parameters.consideration[0].identifierOrCriteria,
+ uint256(navigator.criteriaRoot(considerationIds))
+ );
+
+ assertEq(
+ res.criteriaResolvers.length,
+ 2,
+ "unexpected criteria resolvers length"
+ );
+ // offer
+ assertEq(
+ res.criteriaResolvers[0].criteriaProof.length,
+ 2,
+ "unexpected criteria proof length"
+ );
+ assertEq(
+ res.criteriaResolvers[0].criteriaProof[0],
+ bytes32(
+ 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace
+ )
+ );
+ assertEq(
+ res.criteriaResolvers[0].criteriaProof[1],
+ bytes32(
+ 0x428a6bbf587e6f3339e6162c6b1772e06c62ca82f784b9af8a31028560d0d717
+ )
+ );
+ // consideration
+ assertEq(
+ res.criteriaResolvers[1].criteriaProof.length,
+ 2,
+ "unexpected criteria proof length"
+ );
+ assertEq(
+ res.criteriaResolvers[1].criteriaProof[0],
+ bytes32(
+ 0x036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db0
+ )
+ );
+ assertEq(
+ res.criteriaResolvers[1].criteriaProof[1],
+ bytes32(
+ 0x54d86c808646efdd2ca89e32f5a89bf6f7318cf8d10627e2f001c99fb9fa90dd
+ )
+ );
+ }
+
+ /**
+ * @dev Workaround for Foundry issues with custom errors + libraries.
+ * See: https://github.com/foundry-rs/foundry/issues/4405
+ */
+ function runHelper(NavigatorRequest memory request) public view {
+ navigator.prepare(request);
+ }
+
+ function test_criteriaRoot() public {
+ bytes32 expectedRoot = bytes32(
+ 0x11572c83a2c0fe92ff78bbe3be1013bdef0b1eca44bb67f468dbd31f46237097
+ );
+ uint256[] memory tokenIds = new uint256[](3);
+ tokenIds[0] = 2;
+ tokenIds[1] = 5;
+ tokenIds[2] = 3;
+ assertEq(navigator.criteriaRoot(tokenIds), expectedRoot);
+
+ // TokenIds are sorted before hashing
+ tokenIds[0] = 5;
+ tokenIds[1] = 3;
+ tokenIds[2] = 2;
+ assertEq(navigator.criteriaRoot(tokenIds), expectedRoot);
+ }
+
+ function test_criteriaProof() public {
+ uint256[] memory tokenIds = new uint256[](3);
+ tokenIds[0] = 2;
+ tokenIds[1] = 5;
+ tokenIds[2] = 3;
+
+ bytes32[] memory proof = navigator.criteriaProof(tokenIds, 5);
+
+ assertEq(proof.length, 2);
+ assertEq(
+ proof[0],
+ bytes32(
+ 0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace
+ )
+ );
+ assertEq(
+ proof[1],
+ bytes32(
+ 0x428a6bbf587e6f3339e6162c6b1772e06c62ca82f784b9af8a31028560d0d717
+ )
+ );
+ }
+
+ function test_criteriaProof_revertsTokenNotFound() public {
+ uint256[] memory tokenIds = new uint256[](3);
+ tokenIds[0] = 2;
+ tokenIds[1] = 5;
+ tokenIds[2] = 3;
+
+ vm.expectRevert(TokenIdNotFound.selector);
+ navigator.criteriaProof(tokenIds, 7);
+ }
+}
diff --git a/test/foundry/new/SeaportNavigatorTest.sol b/test/foundry/new/SeaportNavigatorTest.sol
new file mode 100644
index 000000000..bc00f11fa
--- /dev/null
+++ b/test/foundry/new/SeaportNavigatorTest.sol
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ CriteriaHelper
+} from "../../../contracts/helpers/navigator/lib/CriteriaHelper.sol";
+
+import {
+ ExecutionsHelper
+} from "../../../contracts/helpers/navigator/lib/ExecutionsHelper.sol";
+
+import {
+ FulfillmentsHelper
+} from "../../../contracts/helpers/navigator/lib/FulfillmentsHelper.sol";
+
+import {
+ HelperInterface
+} from "../../../contracts/helpers/navigator/lib/HelperInterface.sol";
+
+import {
+ OrderDetailsHelper
+} from "../../../contracts/helpers/navigator/lib/OrderDetailsHelper.sol";
+
+import {
+ RequestValidator
+} from "../../../contracts/helpers/navigator/lib/RequestValidator.sol";
+
+import {
+ SeaportNavigator
+} from "../../../contracts/helpers/navigator/SeaportNavigator.sol";
+
+import {
+ SuggestedActionHelper
+} from "../../../contracts/helpers/navigator/lib/SuggestedActionHelper.sol";
+
+import {
+ ValidatorHelper
+} from "../../../contracts/helpers/navigator/lib/ValidatorHelper.sol";
+
+contract SeaportNavigatorTest {
+ HelperInterface internal requestValidator = new RequestValidator();
+ HelperInterface internal criteriaHelper = new CriteriaHelper();
+ HelperInterface internal validatorHelper = new ValidatorHelper();
+ HelperInterface internal orderDetailsHelper = new OrderDetailsHelper();
+ HelperInterface internal fulfillmentsHelper = new FulfillmentsHelper();
+ HelperInterface internal suggestedActionHelper =
+ new SuggestedActionHelper();
+ HelperInterface internal executionsHelper = new ExecutionsHelper();
+
+ // Initialize the navigator with all its constituent helpers.
+ SeaportNavigator internal navigator =
+ new SeaportNavigator(
+ address(requestValidator),
+ address(criteriaHelper),
+ address(validatorHelper),
+ address(orderDetailsHelper),
+ address(fulfillmentsHelper),
+ address(suggestedActionHelper),
+ address(executionsHelper)
+ );
+}
diff --git a/test/foundry/new/SeaportValidator.t.sol b/test/foundry/new/SeaportValidator.t.sol
index 4caad7caa..f412d704f 100644
--- a/test/foundry/new/SeaportValidator.t.sol
+++ b/test/foundry/new/SeaportValidator.t.sol
@@ -19,6 +19,10 @@ import {
NativeIssue
} from "../../../contracts/helpers/order-validator/SeaportValidator.sol";
+import {
+ ConduitControllerInterface
+} from "seaport-sol/src/ConduitControllerInterface.sol";
+
import {
SeaportValidatorHelper
} from "../../../contracts/helpers/order-validator/lib/SeaportValidatorHelper.sol";
@@ -36,7 +40,7 @@ import {
OrderType,
AdvancedOrderLib,
ItemType
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
ConsiderationItem,
@@ -45,11 +49,12 @@ import {
OrderComponents,
Order,
AdvancedOrder
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import { BaseOrderTest } from "./BaseOrderTest.sol";
+import { SeaportValidatorTest } from "./SeaportValidatorTest.sol";
-contract SeaportValidatorTest is BaseOrderTest {
+contract SeaportValidatorTestSuite is BaseOrderTest, SeaportValidatorTest {
using ConsiderationItemLib for ConsiderationItem;
using OfferItemLib for OfferItem;
using OrderParametersLib for OrderParameters;
@@ -79,7 +84,7 @@ contract SeaportValidatorTest is BaseOrderTest {
address internal noTokens = makeAddr("no tokens/approvals");
- function setUp() public override {
+ function setUp() public override(BaseOrderTest, SeaportValidatorTest) {
super.setUp();
OrderLib
@@ -212,22 +217,6 @@ contract SeaportValidatorTest is BaseOrderTest {
assertEq(actual, expected);
}
- function test_empty_isValidOrderReadOnly() public {
- ErrorsAndWarnings memory actual = validator.isValidOrderReadOnly(
- OrderLib.empty(),
- address(seaport)
- );
-
- ErrorsAndWarnings memory expected = ErrorsAndWarningsLib
- .empty()
- .addError(TimeIssue.EndTimeBeforeStartTime)
- .addError(GenericIssue.InvalidOrderFormat)
- .addWarning(OfferIssue.ZeroItems)
- .addWarning(ConsiderationIssue.ZeroItems);
-
- assertEq(actual, expected);
- }
-
function test_default_full_isValidOrder() public {
ErrorsAndWarnings memory actual = validator.isValidOrder(
OrderLib.fromDefault(STANDARD),
@@ -896,25 +885,6 @@ contract SeaportValidatorTest is BaseOrderTest {
assertEq(actual, expected);
}
- function test_default_full_isValidOrderReadOnly() public {
- Order memory order = OrderLib.empty().withParameters(
- OrderComponentsLib.fromDefault(STANDARD).toOrderParameters()
- );
- ErrorsAndWarnings memory actual = validator.isValidOrderReadOnly(
- order,
- address(seaport)
- );
-
- ErrorsAndWarnings memory expected = ErrorsAndWarningsLib
- .empty()
- .addError(GenericIssue.InvalidOrderFormat)
- .addWarning(TimeIssue.ShortOrder)
- .addWarning(OfferIssue.ZeroItems)
- .addWarning(ConsiderationIssue.ZeroItems);
-
- assertEq(actual, expected);
- }
-
function assertEq(
ErrorsAndWarnings memory left,
ErrorsAndWarnings memory right
@@ -929,14 +899,14 @@ contract SeaportValidatorTest is BaseOrderTest {
right.warnings.length,
"Unexpected number of warnings"
);
- for (uint i = 0; i < left.errors.length; i++) {
+ for (uint256 i = 0; i < left.errors.length; i++) {
assertEq(
left.errors[i].toIssueString(),
right.errors[i].toIssueString(),
"Unexpected error"
);
}
- for (uint i = 0; i < left.warnings.length; i++) {
+ for (uint256 i = 0; i < left.warnings.length; i++) {
assertEq(
left.warnings[i].toIssueString(),
right.warnings[i].toIssueString(),
diff --git a/test/foundry/new/SeaportValidatorTest.sol b/test/foundry/new/SeaportValidatorTest.sol
new file mode 100644
index 000000000..77e9762a8
--- /dev/null
+++ b/test/foundry/new/SeaportValidatorTest.sol
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import { BaseSeaportTest } from "./helpers/BaseSeaportTest.sol";
+
+import {
+ ReadOnlyOrderValidator,
+ SeaportValidator,
+ SeaportValidatorHelper
+} from "../../../contracts/helpers/order-validator/SeaportValidator.sol";
+
+contract SeaportValidatorTest is BaseSeaportTest {
+ SeaportValidatorHelper internal seaportValidatorHelper;
+ SeaportValidator internal validator;
+
+ function setUp() public virtual override {
+ super.setUp();
+
+ // Note: this chainId hack prevents the validator from calling a
+ // hardcoded royalty registry.
+ uint256 chainId = block.chainid;
+ vm.chainId(2);
+ seaportValidatorHelper = new SeaportValidatorHelper();
+ vm.chainId(chainId);
+
+ // Initialize the validator.
+ validator = new SeaportValidator(
+ address(new ReadOnlyOrderValidator()),
+ address(seaportValidatorHelper),
+ address(getConduitController())
+ );
+ }
+}
diff --git a/test/foundry/new/SelfRestricted.t.sol b/test/foundry/new/SelfRestricted.t.sol
index 0a3613d08..38e36a8a2 100644
--- a/test/foundry/new/SelfRestricted.t.sol
+++ b/test/foundry/new/SelfRestricted.t.sol
@@ -10,9 +10,9 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType } from "seaport-sol/src/SeaportEnums.sol";
import {
AdvancedOrderLib,
@@ -25,11 +25,11 @@ import {
OrderLib,
OrderParametersLib,
SeaportArrays
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
-import { Account, BaseOrderTest } from "./BaseOrderTest.sol";
+import { BaseOrderTest } from "./BaseOrderTest.sol";
import { ValidationOffererZone } from "./zones/ValidationOffererZone.sol";
diff --git a/test/foundry/new/SelfRestrictedContractOfferer.t.sol b/test/foundry/new/SelfRestrictedContractOfferer.t.sol
index eba5e1590..5e0ca978b 100644
--- a/test/foundry/new/SelfRestrictedContractOfferer.t.sol
+++ b/test/foundry/new/SelfRestrictedContractOfferer.t.sol
@@ -9,9 +9,9 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType } from "seaport-sol/src/SeaportEnums.sol";
import {
AdvancedOrderLib,
@@ -23,9 +23,9 @@ import {
OrderLib,
OrderParametersLib,
SeaportArrays
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import { BaseOrderTest } from "./BaseOrderTest.sol";
@@ -34,7 +34,7 @@ import { ValidationOffererZone } from "./zones/ValidationOffererZone.sol";
import {
ERC20Interface,
ERC721Interface
-} from "seaport-core/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
contract SelfRestrictedContractOffererTest is BaseOrderTest {
using AdvancedOrderLib for AdvancedOrder;
@@ -155,8 +155,6 @@ contract SelfRestrictedContractOffererTest is BaseOrderTest {
Fulfillment[] memory fulfillments
)
{
- erc721s[0].mint(offerer1.addr, 1);
-
AdvancedOrder memory advancedOrder;
OfferItem[] memory offer;
ConsiderationItem[] memory consideration;
@@ -168,6 +166,8 @@ contract SelfRestrictedContractOffererTest is BaseOrderTest {
uint256 considerAmount = 10;
offerer = new ValidationOffererZone(considerAmount + 1);
+ erc721s[0].mint(address(offerer), 1);
+
allocateTokensAndApprovals(address(offerer), type(uint128).max);
uint256 matchAmount = context.exactAmount
diff --git a/test/foundry/new/helpers/BaseSeaportTest.sol b/test/foundry/new/helpers/BaseSeaportTest.sol
index 34ebcb95a..c7cbbdec2 100644
--- a/test/foundry/new/helpers/BaseSeaportTest.sol
+++ b/test/foundry/new/helpers/BaseSeaportTest.sol
@@ -7,11 +7,11 @@ import { DifferentialTest } from "./DifferentialTest.sol";
import {
ConduitControllerInterface
-} from "seaport-sol/ConduitControllerInterface.sol";
+} from "seaport-sol/src/ConduitControllerInterface.sol";
import {
ConduitController
-} from "../../../../contracts/conduit/ConduitController.sol";
+} from "seaport-core/src/conduit/ConduitController.sol";
import {
ReferenceConduitController
@@ -19,15 +19,15 @@ import {
import {
ConsiderationInterface
-} from "../../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
-import { Consideration } from "../../../../contracts/lib/Consideration.sol";
+import { Consideration } from "seaport-core/src/lib/Consideration.sol";
import {
ReferenceConsideration
} from "../../../../reference/ReferenceConsideration.sol";
-import { Conduit } from "../../../../contracts/conduit/Conduit.sol";
+import { Conduit } from "seaport-core/src/conduit/Conduit.sol";
import { setLabel } from "./Labeler.sol";
diff --git a/test/foundry/new/helpers/CriteriaResolverHelper.sol b/test/foundry/new/helpers/CriteriaResolverHelper.sol
index 101bf3967..0fd358293 100644
--- a/test/foundry/new/helpers/CriteriaResolverHelper.sol
+++ b/test/foundry/new/helpers/CriteriaResolverHelper.sol
@@ -12,9 +12,9 @@ import {
ConsiderationItem,
CriteriaResolver,
OfferItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, Side } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, Side } from "seaport-sol/src/SeaportEnums.sol";
struct CriteriaMetadata {
uint256 resolvedIdentifier;
diff --git a/test/foundry/new/helpers/DebugUtil.sol b/test/foundry/new/helpers/DebugUtil.sol
index 94a4ade46..77bc39233 100644
--- a/test/foundry/new/helpers/DebugUtil.sol
+++ b/test/foundry/new/helpers/DebugUtil.sol
@@ -11,9 +11,12 @@ import { FuzzEngineLib } from "./FuzzEngineLib.sol";
import { console2 } from "forge-std/console2.sol";
-import { ArrayHelpers, MemoryPointer } from "seaport-sol/../ArrayHelpers.sol";
+import { ArrayHelpers, MemoryPointer } from "seaport/helpers/ArrayHelpers.sol";
-import { OrderStatusEnum, UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import {
+ OrderStatusEnum,
+ UnavailableReason
+} from "seaport-sol/src/SpaceEnums.sol";
import { ForgeEventsLib } from "./event-utils/ForgeEventsLib.sol";
@@ -40,7 +43,8 @@ struct ContextOutputSelection {
bool basicOrderParameters;
bool testHelpers;
bool checks;
- bool expectedZoneCalldataHash;
+ bool expectedZoneAuthorizeCalldataHashes;
+ bool expectedZoneValidateCalldataHashes;
bool expectedContractOrderCalldataHashes;
bool expectedResults;
bool expectedImplicitExecutions;
@@ -71,7 +75,7 @@ using ExecutionFilterCast for Execution[];
*
* @param context the FuzzTestContext to serialize.
* @param outputSelection a ContextOutputSelection struct containing flags
- that define which FuzzTestContext fields to serialize.
+ * that define which FuzzTestContext fields to serialize.
*/
function dumpContext(
FuzzTestContext memory context,
@@ -233,11 +237,11 @@ function dumpContext(
cast(context.executionState.preExecOrderStatuses)
);
}
- // if (outputSelection.expectedZoneCalldataHash) {
+ // if (outputSelection.expectedZoneValidateCalldataHash) {
// jsonOut = Searializer.tojsonDynArrayBytes32(
// "root",
- // "expectedZoneCalldataHash",
- // context.expectations.expectedZoneCalldataHash
+ // "expectedZoneValidateCalldataHash",
+ // context.expectations.expectedZoneValidateCalldataHash
// );
// }
// if (outputSelection.expectedContractOrderCalldataHashes) {
diff --git a/test/foundry/new/helpers/EIP1271Offerer.sol b/test/foundry/new/helpers/EIP1271Offerer.sol
index 9345db15e..abc9424ce 100644
--- a/test/foundry/new/helpers/EIP1271Offerer.sol
+++ b/test/foundry/new/helpers/EIP1271Offerer.sol
@@ -1,9 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
+
import { ERC1155Recipient } from "../../utils/ERC1155Recipient.sol";
contract EIP1271Offerer is ERC1155Recipient {
error EIP1271OffererInvalidSignature(bytes32 digest, bytes signature);
+
bytes4 private constant _EIP_1271_MAGIC_VALUE = 0x1626ba7e;
mapping(bytes32 => bytes32) public digestToSignatureHash;
diff --git a/test/foundry/new/helpers/EIP712MerkleTree.sol b/test/foundry/new/helpers/EIP712MerkleTree.sol
index f554303c8..3946c9ae3 100644
--- a/test/foundry/new/helpers/EIP712MerkleTree.sol
+++ b/test/foundry/new/helpers/EIP712MerkleTree.sol
@@ -3,13 +3,13 @@ pragma solidity ^0.8.17;
import { MurkyBase } from "murky/common/MurkyBase.sol";
-import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol";
+import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
import { Test } from "forge-std/Test.sol";
-import { OrderComponents } from "seaport-sol/SeaportStructs.sol";
+import { OrderComponents } from "seaport-sol/src/SeaportStructs.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import {
TypehashDirectory
diff --git a/test/foundry/new/helpers/ExpectedBalances.sol b/test/foundry/new/helpers/ExpectedBalances.sol
index 72fb487a7..49cccb188 100644
--- a/test/foundry/new/helpers/ExpectedBalances.sol
+++ b/test/foundry/new/helpers/ExpectedBalances.sol
@@ -3,28 +3,24 @@ pragma solidity >=0.8.17;
import {
EnumerableSet
-} from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol";
+} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
import {
EnumerableMap
-} from "openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol";
+} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol";
-import { IERC20 } from "openzeppelin-contracts/contracts/interfaces/IERC20.sol";
+import { IERC20 } from "@openzeppelin/contracts/interfaces/IERC20.sol";
-import {
- IERC721
-} from "openzeppelin-contracts/contracts/interfaces/IERC721.sol";
+import { IERC721 } from "@openzeppelin/contracts/interfaces/IERC721.sol";
-import {
- IERC1155
-} from "openzeppelin-contracts/contracts/interfaces/IERC1155.sol";
+import { IERC1155 } from "@openzeppelin/contracts/interfaces/IERC1155.sol";
import { LibString } from "solady/src/utils/LibString.sol";
import { withLabel } from "./Labeler.sol";
-import { Execution, ReceivedItem } from "seaport-sol/SeaportStructs.sol";
+import { Execution, ReceivedItem } from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
struct NativeAccountDump {
address account;
@@ -63,17 +59,17 @@ struct ERC1155AccountDump {
address account;
uint256[] identifiers;
uint256[] balances;
- // ERC1155IdentifierDump[] identifiers;
}
+// ERC1155IdentifierDump[] identifiers;
struct ERC1155TokenDump {
address token;
ERC1155AccountDump[] accounts;
- // address[] accounts;
- // uint256[][] accountIdentifiers;
- // uint256[][] accountBalances;
- // ERC1155AccountDump[] accounts;
}
+// address[] accounts;
+// uint256[][] accountIdentifiers;
+// uint256[][] accountBalances;
+// ERC1155AccountDump[] accounts;
struct ExpectedBalancesDump {
ERC20TokenDump[] erc20;
@@ -502,6 +498,7 @@ contract ERC721Balances {
EnumerableSet.UintSet touchedIdentifiers;
EnumerableMap.AddressToUintMap accountBalances;
}
+
EnumerableSet.AddressSet private tokens;
mapping(address => TokenData721) private tokenDatas;
diff --git a/test/foundry/new/helpers/FractionUtil.sol b/test/foundry/new/helpers/FractionUtil.sol
index c635b84a7..ae0857f39 100644
--- a/test/foundry/new/helpers/FractionUtil.sol
+++ b/test/foundry/new/helpers/FractionUtil.sol
@@ -119,10 +119,41 @@ library FractionUtil {
status = FractionStatus.WHOLE_FILL;
}
+ uint120 realizedNumerator = uint120(numerator);
+ uint120 realizedDenominator = uint120(denominator);
+
+ filledNumerator = currentStatusNumerator;
+
+ // if supplied denominator differs from current one...
+ if (currentStatusDenominator != denominator) {
+ // scale current numerator by the supplied denominator, then...
+ filledNumerator *= denominator;
+
+ // the supplied numerator & denominator by current denominator.
+ numerator *= currentStatusDenominator;
+ denominator *= currentStatusDenominator;
+ }
+
+ // Increment the filled numerator by the new numerator.
+ filledNumerator += numerator;
+
+ // Ensure fractional amounts are below max uint120.
+ if (
+ filledNumerator > type(uint120).max ||
+ denominator > type(uint120).max
+ ) {
+ // Derive greatest common divisor using euclidean algorithm.
+ uint256 scaleDown = _gcd(filledNumerator, denominator);
+
+ // Scale new filled fractional values down by gcd.
+ filledNumerator = filledNumerator / scaleDown;
+ denominator = denominator / scaleDown;
+ }
+
return
FractionResults({
- realizedNumerator: uint120(numerator),
- realizedDenominator: uint120(denominator),
+ realizedNumerator: realizedNumerator,
+ realizedDenominator: realizedDenominator,
finalFilledNumerator: uint120(filledNumerator),
finalFilledDenominator: uint120(denominator),
originalStatusNumerator: currentStatusNumerator,
diff --git a/test/foundry/new/helpers/FuzzAmendments.sol b/test/foundry/new/helpers/FuzzAmendments.sol
index 6cf12fa28..44c817352 100644
--- a/test/foundry/new/helpers/FuzzAmendments.sol
+++ b/test/foundry/new/helpers/FuzzAmendments.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.17;
import { Test } from "forge-std/Test.sol";
-import { AdvancedOrderLib } from "seaport-sol/SeaportSol.sol";
+import { AdvancedOrderLib } from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -12,9 +12,9 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType, Side } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType, Side } from "seaport-sol/src/SeaportEnums.sol";
import { FuzzChecks } from "./FuzzChecks.sol";
@@ -31,7 +31,7 @@ import { CheckHelpers } from "./FuzzSetup.sol";
import {
OrderStatusEnum,
ContractOrderRebate
-} from "seaport-sol/SpaceEnums.sol";
+} from "seaport-sol/src/SpaceEnums.sol";
import {
HashCalldataContractOfferer
diff --git a/test/foundry/new/helpers/FuzzChecks.sol b/test/foundry/new/helpers/FuzzChecks.sol
index 4ae9a481a..67482c192 100644
--- a/test/foundry/new/helpers/FuzzChecks.sol
+++ b/test/foundry/new/helpers/FuzzChecks.sol
@@ -5,16 +5,19 @@ import { Test } from "forge-std/Test.sol";
import { ExpectedEventsUtil } from "./event-utils/ExpectedEventsUtil.sol";
-import { OrderParametersLib } from "seaport-sol/SeaportSol.sol";
+import { OrderParametersLib } from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
Execution,
OrderParameters,
OrderType
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { OrderStatusEnum, UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import {
+ OrderStatusEnum,
+ UnavailableReason
+} from "seaport-sol/src/SpaceEnums.sol";
import { FuzzHelpers } from "./FuzzHelpers.sol";
@@ -113,6 +116,56 @@ abstract contract FuzzChecks is Test {
}
}
+ /**
+ * @dev Check that the zone is getting the right calldata in authorizeOrder.
+ *
+ * @param context A Fuzz test context.
+ */
+ function check_authorizeOrderExpectedDataHash(
+ FuzzTestContext memory context
+ ) public {
+ // Iterate over the orders.
+ for (uint256 i; i < context.executionState.orders.length; i++) {
+ OrderParameters memory order = context
+ .executionState
+ .orders[i]
+ .parameters;
+
+ // If the order is restricted, check the calldata.
+ if (
+ order.orderType == OrderType.FULL_RESTRICTED ||
+ order.orderType == OrderType.PARTIAL_RESTRICTED
+ ) {
+ testZone = payable(order.zone);
+
+ // Each order has a calldata hash, indexed to orders, that is
+ // expected to be returned by the zone.
+ bytes32 expectedCalldataHash = context
+ .expectations
+ .expectedZoneAuthorizeCalldataHashes[i];
+
+ bytes32 orderHash = context
+ .executionState
+ .orderDetails[i]
+ .orderHash;
+
+ // Use order hash to get the expected calldata hash from zone.
+ // TODO: fix this in cases where contract orders are part of
+ // orderHashes (the hash calculation is most likely incorrect).
+ bytes32 actualCalldataHash = HashValidationZoneOfferer(testZone)
+ .orderHashToAuthorizeOrderDataHash(orderHash);
+
+ // Check that the expected calldata hash matches the actual
+ // calldata hash.
+ assertEq(
+ actualCalldataHash,
+ expectedCalldataHash,
+ "check_authorizeOrderExpectedDataHash: actualCalldataHash != expectedCalldataHash"
+ );
+ }
+ }
+ }
+
/**
* @dev Check that the zone is getting the right calldata.
*
@@ -139,7 +192,7 @@ abstract contract FuzzChecks is Test {
// expected to be returned by the zone.
bytes32 expectedCalldataHash = context
.expectations
- .expectedZoneCalldataHash[i];
+ .expectedZoneValidateCalldataHashes[i];
bytes32 orderHash = context
.executionState
diff --git a/test/foundry/new/helpers/FuzzDerivers.sol b/test/foundry/new/helpers/FuzzDerivers.sol
index 8c10b79cb..45e62b8aa 100644
--- a/test/foundry/new/helpers/FuzzDerivers.sol
+++ b/test/foundry/new/helpers/FuzzDerivers.sol
@@ -9,7 +9,7 @@ import {
AdvancedOrderLib,
MatchComponent,
MatchComponentType
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -21,20 +21,25 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType } from "seaport-sol/src/SeaportEnums.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
-import { OrderStatusEnum, UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import {
+ OrderStatusEnum,
+ UnavailableReason
+} from "seaport-sol/src/SpaceEnums.sol";
-import { ExecutionHelper } from "seaport-sol/executions/ExecutionHelper.sol";
+import {
+ ExecutionHelper
+} from "seaport-sol/src/executions/ExecutionHelper.sol";
import {
FulfillmentDetails,
OrderDetails
-} from "seaport-sol/fulfillments/lib/Structs.sol";
+} from "seaport-sol/src/fulfillments/lib/Structs.sol";
import { FuzzEngineLib } from "./FuzzEngineLib.sol";
@@ -46,7 +51,7 @@ import { CriteriaResolverHelper } from "./CriteriaResolverHelper.sol";
import {
FulfillmentGeneratorLib
-} from "seaport-sol/fulfillments/lib/FulfillmentLib.sol";
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
/**
* @dev "Derivers" examine generated orders and calculate additional
diff --git a/test/foundry/new/helpers/FuzzEngine.sol b/test/foundry/new/helpers/FuzzEngine.sol
index 96ce46cb2..7a89f2e37 100644
--- a/test/foundry/new/helpers/FuzzEngine.sol
+++ b/test/foundry/new/helpers/FuzzEngine.sol
@@ -11,8 +11,12 @@ import {
MatchFulfillmentHelper,
OrderComponentsLib,
OrderLib,
- OrderParametersLib
-} from "seaport-sol/SeaportSol.sol";
+ OrderParametersLib,
+ OfferItem,
+ ConsiderationItem,
+ ItemType,
+ OrderType
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -21,19 +25,21 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import {
ConduitControllerInterface
-} from "seaport-sol/ConduitControllerInterface.sol";
+} from "seaport-sol/src/ConduitControllerInterface.sol";
import {
ConduitControllerInterface
-} from "seaport-sol/ConduitControllerInterface.sol";
+} from "seaport-sol/src/ConduitControllerInterface.sol";
import { BaseOrderTest } from "../BaseOrderTest.sol";
+import { SeaportValidatorTest } from "../SeaportValidatorTest.sol";
+import { SeaportNavigatorTest } from "../SeaportNavigatorTest.sol";
import {
FuzzGeneratorContext,
@@ -86,6 +92,21 @@ import {
IssueStringHelpers
} from "../../../../contracts/helpers/order-validator/lib/SeaportValidatorTypes.sol";
+import {
+ NavigatorRequest
+} from "../../../../contracts/helpers/navigator/lib/SeaportNavigatorTypes.sol";
+
+import {
+ NavigatorAdvancedOrderLib
+} from "../../../../contracts/helpers/navigator/lib/NavigatorAdvancedOrderLib.sol";
+
+import {
+ FulfillmentStrategy,
+ AggregationStrategy,
+ FulfillAvailableStrategy,
+ MatchStrategy
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
+
/**
* @notice Base test contract for FuzzEngine. Fuzz tests should inherit this.
* Includes the setup and helper functions from BaseOrderTest.
@@ -177,6 +198,8 @@ import {
*/
contract FuzzEngine is
BaseOrderTest,
+ SeaportValidatorTest,
+ SeaportNavigatorTest,
FuzzAmendments,
FuzzSetup,
FuzzChecks,
@@ -220,7 +243,11 @@ contract FuzzEngine is
}
}
- function setUp() public virtual override {
+ function setUp()
+ public
+ virtual
+ override(BaseOrderTest, SeaportValidatorTest)
+ {
super.setUp();
mutations = new FuzzMutations();
}
@@ -256,6 +283,7 @@ contract FuzzEngine is
runSetup(context);
runCheckRegistration(context);
validate(context);
+ runNavigator(context);
execFailure(context);
execSuccess(context);
checkAll(context);
@@ -319,13 +347,14 @@ contract FuzzEngine is
.from({ orders: orders, seaport: getSeaport() })
.withConduitController(conduitController_)
.withSeaportValidator(validator)
+ .withSeaportNavigator(navigator)
.withFuzzParams(fuzzParams)
.withMaximumFulfilled(space.maximumFulfilled)
- .withPreExecOrderStatuses(space)
- .withCounter(generatorContext.counter);
+ .withPreExecOrderStatuses(space);
// This is on a separate line to avoid stack too deep.
context = context
+ .withCounter(generatorContext.counter)
.withContractOffererNonce(generatorContext.contractOffererNonce)
.withCaller(generatorContext.caller)
.withFulfillerConduitKey(
@@ -502,22 +531,79 @@ contract FuzzEngine is
* @param context A Fuzz test context.
*/
function validate(FuzzTestContext memory context) internal {
- for (uint256 i; i < context.executionState.orders.length; ++i) {
- Order memory order = context.executionState.orders[i].toOrder();
- context.executionState.validationErrors[i] = context
- .seaportValidator
- .isValidOrderWithConfiguration(
- ValidationConfiguration({
- seaport: address(context.seaport),
- primaryFeeRecipient: address(0),
- primaryFeeBips: 0,
- checkCreatorFee: false,
- skipStrictValidation: true,
- shortOrderDuration: 30 minutes,
- distantOrderExpiration: 26 weeks
- }),
- order
+ if (vm.envOr("SEAPORT_FUZZ_VALIDATOR", false)) {
+ for (uint256 i; i < context.executionState.orders.length; ++i) {
+ Order memory order = context.executionState.orders[i].toOrder();
+ context.executionState.validationErrors[i] = context
+ .seaportValidator
+ .isValidOrderWithConfiguration(
+ ValidationConfiguration({
+ seaport: address(context.seaport),
+ primaryFeeRecipient: address(0),
+ primaryFeeBips: 0,
+ checkCreatorFee: false,
+ skipStrictValidation: true,
+ shortOrderDuration: 30 minutes,
+ distantOrderExpiration: 26 weeks
+ }),
+ order
+ );
+ }
+ }
+ }
+
+ /**
+ * @dev Call SeaportNavigator.run with generated order.
+ *
+ * @param context A Fuzz test context.
+ */
+ function runNavigator(FuzzTestContext memory context) internal {
+ if (vm.envOr("SEAPORT_FUZZ_NAVIGATOR", false)) {
+ // Skip contract orders, which are not supported by the helper.
+ bool isContractOrder;
+ for (uint256 i; i < context.executionState.orders.length; i++) {
+ if (
+ context.executionState.orders[i].parameters.orderType ==
+ OrderType.CONTRACT
+ ) {
+ isContractOrder = true;
+ break;
+ }
+ }
+
+ if (!isContractOrder) {
+ FulfillmentStrategy
+ memory fulfillmentStrategy = FulfillmentStrategy({
+ aggregationStrategy: AggregationStrategy.RANDOM,
+ fulfillAvailableStrategy: FulfillAvailableStrategy
+ .DROP_RANDOM_OFFER,
+ matchStrategy: MatchStrategy.MAX_INCLUSION
+ });
+ context.seaportNavigator.prepare(
+ NavigatorRequest({
+ seaport: context.seaport,
+ validator: context.seaportValidator,
+ orders: NavigatorAdvancedOrderLib.fromAdvancedOrders(
+ context.executionState.orders
+ ),
+ caller: context.executionState.caller,
+ nativeTokensSupplied: context.executionState.value,
+ fulfillerConduitKey: context
+ .executionState
+ .fulfillerConduitKey,
+ recipient: context.executionState.recipient,
+ maximumFulfilled: context
+ .executionState
+ .maximumFulfilled,
+ seed: context.fuzzParams.seed,
+ fulfillmentStrategy: fulfillmentStrategy,
+ criteriaResolvers: context
+ .executionState
+ .criteriaResolvers,
+ preferMatch: true
+ })
);
+ }
}
}
diff --git a/test/foundry/new/helpers/FuzzEngineLib.sol b/test/foundry/new/helpers/FuzzEngineLib.sol
index cbfcba325..816fb5ed9 100644
--- a/test/foundry/new/helpers/FuzzEngineLib.sol
+++ b/test/foundry/new/helpers/FuzzEngineLib.sol
@@ -7,7 +7,7 @@ import {
OrderComponentsLib,
OrderLib,
OrderParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -19,13 +19,13 @@ import {
OrderParameters,
SpentItem,
ReceivedItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { OrderDetails } from "seaport-sol/fulfillments/lib/Structs.sol";
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
-import { ItemType, Side, OrderType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, Side, OrderType } from "seaport-sol/src/SeaportEnums.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
import {
_locateCurrentAmount,
@@ -39,8 +39,8 @@ import { FuzzTestContext } from "./FuzzTestContextLib.sol";
import { FuzzDerivers } from "./FuzzDerivers.sol";
import {
- FulfillmentGeneratorLib
-} from "seaport-sol/fulfillments/lib/FulfillmentLib.sol";
+ DefaultFulfillmentGeneratorLib
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
/**
* @notice Stateless helpers for FuzzEngine. The FuzzEngine uses functions in
@@ -52,7 +52,7 @@ library FuzzEngineLib {
using OrderComponentsLib for OrderComponents;
using OrderLib for Order;
using OrderParametersLib for OrderParameters;
- using FulfillmentGeneratorLib for OrderDetails[];
+ using DefaultFulfillmentGeneratorLib for OrderDetails[];
using FuzzHelpers for AdvancedOrder;
using FuzzHelpers for AdvancedOrder[];
@@ -113,7 +113,7 @@ library FuzzEngineLib {
) internal view returns (bytes4[] memory) {
Family family = context.executionState.orders.getFamily();
- bool invalidOfferItemsLocated = mustUseMatch(context);
+ bool containsOrderThatDemandsMatch = mustUseMatch(context);
Structure structure = context.executionState.orders.getStructure(
address(context.seaport)
@@ -136,7 +136,7 @@ library FuzzEngineLib {
}
if (hasUnavailable) {
- if (invalidOfferItemsLocated) {
+ if (containsOrderThatDemandsMatch) {
revert(
"FuzzEngineLib: invalid native token + unavailable combination"
);
@@ -160,7 +160,7 @@ library FuzzEngineLib {
}
}
- if (family == Family.SINGLE && !invalidOfferItemsLocated) {
+ if (family == Family.SINGLE && !containsOrderThatDemandsMatch) {
if (structure == Structure.BASIC) {
bytes4[] memory selectors = new bytes4[](6);
selectors[0] = context.seaport.fulfillOrder.selector;
@@ -204,7 +204,7 @@ library FuzzEngineLib {
bool cannotMatch = (context.executionState.hasRemainders ||
hasUnavailable);
- if (cannotMatch && invalidOfferItemsLocated) {
+ if (cannotMatch && containsOrderThatDemandsMatch) {
revert("FuzzEngineLib: cannot fulfill provided combined order");
}
@@ -227,7 +227,7 @@ library FuzzEngineLib {
//selectors[3] = context.seaport.validate.selector;
return selectors;
}
- } else if (invalidOfferItemsLocated) {
+ } else if (containsOrderThatDemandsMatch) {
if (structure == Structure.ADVANCED) {
bytes4[] memory selectors = new bytes4[](1);
selectors[0] = context.seaport.matchAdvancedOrders.selector;
diff --git a/test/foundry/new/helpers/FuzzExecutor.sol b/test/foundry/new/helpers/FuzzExecutor.sol
index ac4956246..cf449d061 100644
--- a/test/foundry/new/helpers/FuzzExecutor.sol
+++ b/test/foundry/new/helpers/FuzzExecutor.sol
@@ -10,7 +10,7 @@ import {
OrderComponentsLib,
OrderLib,
OrderParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -19,7 +19,7 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import {
FuzzTestContext,
@@ -78,8 +78,9 @@ abstract contract FuzzExecutor is Test {
logCall("fulfillOrder", logCalls);
AdvancedOrder memory order = context.executionState.orders[0];
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
context.returnValues.fulfilled = context.seaport.fulfillOrder{
value: context.executionState.value
}(order.toOrder(), context.executionState.fulfillerConduitKey);
@@ -87,8 +88,9 @@ abstract contract FuzzExecutor is Test {
logCall("fulfillAdvancedOrder", logCalls);
AdvancedOrder memory order = context.executionState.orders[0];
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
context.returnValues.fulfilled = context
.seaport
.fulfillAdvancedOrder{ value: context.executionState.value }(
@@ -111,8 +113,9 @@ abstract contract FuzzExecutor is Test {
.executionState
.fulfillerConduitKey;
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
context.returnValues.fulfilled = context.seaport.fulfillBasicOrder{
value: context.executionState.value
}(basicOrderParameters);
@@ -133,8 +136,9 @@ abstract contract FuzzExecutor is Test {
.executionState
.fulfillerConduitKey;
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
context.returnValues.fulfilled = context
.seaport
.fulfillBasicOrder_efficient_6GL6yc{
@@ -142,8 +146,9 @@ abstract contract FuzzExecutor is Test {
}(basicOrderParameters);
} else if (_action == context.seaport.fulfillAvailableOrders.selector) {
logCall("fulfillAvailableOrders", logCalls);
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
(
bool[] memory availableOrders,
Execution[] memory executions
@@ -163,8 +168,9 @@ abstract contract FuzzExecutor is Test {
_action == context.seaport.fulfillAvailableAdvancedOrders.selector
) {
logCall("fulfillAvailableAdvancedOrders", logCalls);
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
(
bool[] memory availableOrders,
Execution[] memory executions
@@ -184,8 +190,9 @@ abstract contract FuzzExecutor is Test {
context.returnValues.executions = executions;
} else if (_action == context.seaport.matchOrders.selector) {
logCall("matchOrders", logCalls);
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
Execution[] memory executions = context.seaport.matchOrders{
value: context.executionState.value
}(
@@ -196,8 +203,9 @@ abstract contract FuzzExecutor is Test {
context.returnValues.executions = executions;
} else if (_action == context.seaport.matchAdvancedOrders.selector) {
logCall("matchAdvancedOrders", logCalls);
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
Execution[] memory executions = context.seaport.matchAdvancedOrders{
value: context.executionState.value
}(
@@ -223,15 +231,17 @@ abstract contract FuzzExecutor is Test {
.toOrderComponents(context.executionState.counter);
}
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
context.returnValues.cancelled = context.seaport.cancel(
orderComponents
);
} else if (_action == context.seaport.validate.selector) {
logCall("validate", logCalls);
- if (context.executionState.caller != address(0))
+ if (context.executionState.caller != address(0)) {
vm.prank(context.executionState.caller);
+ }
context.returnValues.validated = context.seaport.validate(
context.executionState.orders.toOrders()
);
diff --git a/test/foundry/new/helpers/FuzzGeneratorContextLib.sol b/test/foundry/new/helpers/FuzzGeneratorContextLib.sol
index 4d37c732c..00f0672b4 100644
--- a/test/foundry/new/helpers/FuzzGeneratorContextLib.sol
+++ b/test/foundry/new/helpers/FuzzGeneratorContextLib.sol
@@ -3,30 +3,30 @@ pragma solidity ^0.8.17;
import { Vm } from "forge-std/Vm.sol";
+import { StdCheats } from "forge-std/StdCheats.sol";
+
import { LibPRNG } from "solady/src/utils/LibPRNG.sol";
-import { MatchComponent } from "seaport-sol/SeaportSol.sol";
+import { MatchComponent } from "seaport-sol/src/SeaportSol.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
import {
Amount,
BasicOrderCategory,
Criteria,
TokenIndex
-} from "seaport-sol/SpaceEnums.sol";
+} from "seaport-sol/src/SpaceEnums.sol";
-import { OfferItemSpace } from "seaport-sol/StructSpace.sol";
+import { OfferItemSpace } from "seaport-sol/src/StructSpace.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import { EIP1271Offerer } from "./EIP1271Offerer.sol";
import {
ConduitControllerInterface
-} from "seaport-sol/ConduitControllerInterface.sol";
-
-import { Account } from "../BaseOrderTest.sol";
+} from "seaport-sol/src/ConduitControllerInterface.sol";
import { TestHelpers } from "./FuzzTestContextLib.sol";
@@ -44,7 +44,7 @@ import {
HashCalldataContractOfferer
} from "../../../../contracts/test/HashCalldataContractOfferer.sol";
-import { Conduit } from "../../../../contracts/conduit/Conduit.sol";
+import { Conduit } from "seaport-core/src/conduit/Conduit.sol";
import {
HashValidationZoneOfferer
@@ -72,12 +72,12 @@ struct FuzzGeneratorContext {
TestERC1155[] erc1155s;
address self;
address caller;
- Account alice;
- Account bob;
- Account carol;
- Account dillon;
- Account eve;
- Account frank;
+ StdCheats.Account alice;
+ StdCheats.Account bob;
+ StdCheats.Account carol;
+ StdCheats.Account dillon;
+ StdCheats.Account eve;
+ StdCheats.Account frank;
TestConduit[] conduits;
uint256 starting721offerIndex;
uint256 starting721considerationIndex;
@@ -119,12 +119,12 @@ library FuzzGeneratorContextLib {
eip1271Offerer: new EIP1271Offerer(),
self: address(this),
caller: address(this),
- alice: testHelpers.makeAccount("alice"),
- bob: testHelpers.makeAccount("bob"),
- carol: testHelpers.makeAccount("carol"),
- dillon: testHelpers.makeAccount("dillon"),
- eve: testHelpers.makeAccount("eve"),
- frank: testHelpers.makeAccount("frank"),
+ alice: testHelpers.makeAccountWrapper("alice"),
+ bob: testHelpers.makeAccountWrapper("bob"),
+ carol: testHelpers.makeAccountWrapper("carol"),
+ dillon: testHelpers.makeAccountWrapper("dillon"),
+ eve: testHelpers.makeAccountWrapper("eve"),
+ frank: testHelpers.makeAccountWrapper("frank"),
conduits: new TestConduit[](2),
starting721offerIndex: 0,
starting721considerationIndex: 0,
@@ -198,12 +198,12 @@ library FuzzGeneratorContextLib {
eip1271Offerer: eip1271Offerer,
self: address(this),
caller: address(this),
- alice: testHelpers.makeAccount("alice"),
- bob: testHelpers.makeAccount("bob"),
- carol: testHelpers.makeAccount("carol"),
- dillon: testHelpers.makeAccount("dillon"),
- eve: testHelpers.makeAccount("eve"),
- frank: testHelpers.makeAccount("frank"),
+ alice: testHelpers.makeAccountWrapper("alice"),
+ bob: testHelpers.makeAccountWrapper("bob"),
+ carol: testHelpers.makeAccountWrapper("carol"),
+ dillon: testHelpers.makeAccountWrapper("dillon"),
+ eve: testHelpers.makeAccountWrapper("eve"),
+ frank: testHelpers.makeAccountWrapper("frank"),
conduits: conduits,
starting721offerIndex: 0,
starting721considerationIndex: 0,
diff --git a/test/foundry/new/helpers/FuzzGenerators.sol b/test/foundry/new/helpers/FuzzGenerators.sol
index 66ad58d75..54581094b 100644
--- a/test/foundry/new/helpers/FuzzGenerators.sol
+++ b/test/foundry/new/helpers/FuzzGenerators.sol
@@ -11,7 +11,7 @@ import {
OfferItemLib,
OrderLib,
OrderParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -24,11 +24,11 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType, Side } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType, Side } from "seaport-sol/src/SeaportEnums.sol";
-import { OrderDetails } from "seaport-sol/fulfillments/lib/Structs.sol";
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
import { Solarray } from "solarray/Solarray.sol";
import {
Amount,
@@ -50,20 +50,20 @@ import {
UnavailableReason,
Zone,
ZoneHash
-} from "seaport-sol/SpaceEnums.sol";
+} from "seaport-sol/src/SpaceEnums.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import {
ConduitControllerInterface
-} from "seaport-sol/ConduitControllerInterface.sol";
+} from "seaport-sol/src/ConduitControllerInterface.sol";
import {
AdvancedOrdersSpace,
ConsiderationItemSpace,
OfferItemSpace,
OrderComponentsSpace
-} from "seaport-sol/StructSpace.sol";
+} from "seaport-sol/src/StructSpace.sol";
import { EIP712MerkleTree } from "../../utils/EIP712MerkleTree.sol";
@@ -87,8 +87,9 @@ import {
FulfillAvailableStrategy,
MatchStrategy,
FulfillmentGeneratorLib,
- FulfillmentStrategy
-} from "seaport-sol/fulfillments/lib/FulfillmentLib.sol";
+ FulfillmentStrategy,
+ DefaultFulfillmentGeneratorLib
+} from "seaport-sol/src/fulfillments/lib/FulfillmentLib.sol";
/**
* @dev Generators are responsible for creating guided, random order data for
@@ -160,11 +161,10 @@ library TestStateGenerator {
for (uint256 i; i < totalOrders; ++i) {
UnavailableReason reason = (
context.randRange(0, 1) == 0
- ? UnavailableReason.AVAILABLE
- // Don't fuzz 5 (maxfulfilled satisfied), since it's a more
- // of a consequence (to be handled in derivers) than a
- // target.
- : UnavailableReason(context.choice(Solarray.uint256s(1, 2, 3, 4, 6)))
+ ? UnavailableReason.AVAILABLE // Don't fuzz 5 (maxfulfilled satisfied), since it's a more // of a consequence (to be handled in derivers) than a // target.
+ : UnavailableReason(
+ context.choice(Solarray.uint256s(1, 2, 3, 4, 6))
+ )
);
if (reason == UnavailableReason.AVAILABLE) {
@@ -343,7 +343,7 @@ library TestStateGenerator {
}
FulfillmentStrategy memory strategy = (
- FulfillmentGeneratorLib.getDefaultFulfillmentStrategy()
+ DefaultFulfillmentGeneratorLib.getDefaultFulfillmentStrategy()
);
{
@@ -487,7 +487,7 @@ library TestStateGenerator {
recipient: FulfillmentRecipient.ZERO,
conduit: ConduitChoice.NONE,
caller: Caller.TEST_CONTRACT,
- strategy: FulfillmentGeneratorLib
+ strategy: DefaultFulfillmentGeneratorLib
.getDefaultFulfillmentStrategy()
});
}
@@ -504,7 +504,7 @@ library AdvancedOrdersSpaceGenerator {
using OrderLib for Order;
using OrderParametersLib for OrderParameters;
- using FulfillmentGeneratorLib for OrderDetails[];
+ using DefaultFulfillmentGeneratorLib for OrderDetails[];
using BroadOrderTypeGenerator for AdvancedOrder;
using ConduitGenerator for ConduitChoice;
@@ -818,7 +818,9 @@ library AdvancedOrdersSpaceGenerator {
.criteriaResolverHelper()
.deriveCriteriaResolvers(orders);
- bytes32[] memory orderHashes = orders.getOrderHashes(address(context.seaport));
+ bytes32[] memory orderHashes = orders.getOrderHashes(
+ address(context.seaport)
+ );
OrderDetails[] memory details = orders.getOrderDetails(
infra.resolvers,
@@ -837,10 +839,14 @@ library AdvancedOrdersSpaceGenerator {
// Unpack the remainder from the MatchComponent into its
// constituent parts.
- (infra.amount, orderIndex, itemIndex) = infra.remainders[i].unpack();
+ (infra.amount, orderIndex, itemIndex) = infra
+ .remainders[i]
+ .unpack();
// Get the consideration item with the remainder.
- infra.item = orders[orderIndex].parameters.consideration[itemIndex];
+ infra.item = orders[orderIndex].parameters.consideration[
+ itemIndex
+ ];
infra.resolvedIdentifier = infra.item.identifierOrCriteria;
infra.resolvedItemType = infra.item.itemType;
@@ -848,7 +854,9 @@ library AdvancedOrdersSpaceGenerator {
infra.item.itemType == ItemType.ERC721_WITH_CRITERIA ||
infra.item.itemType == ItemType.ERC1155_WITH_CRITERIA
) {
- infra.resolvedItemType = _convertCriteriaItemType(infra.item.itemType);
+ infra.resolvedItemType = _convertCriteriaItemType(
+ infra.item.itemType
+ );
if (infra.item.identifierOrCriteria == 0) {
bytes32 itemHash = keccak256(
abi.encodePacked(
@@ -972,7 +980,9 @@ library AdvancedOrdersSpaceGenerator {
.testHelpers
.criteriaResolverHelper()
.deriveCriteriaResolvers(orders);
- bytes32[] memory orderHashes = orders.getOrderHashes(address(context.seaport));
+ bytes32[] memory orderHashes = orders.getOrderHashes(
+ address(context.seaport)
+ );
OrderDetails[] memory details = orders.getOrderDetails(
infra.resolvers,
orderHashes,
@@ -2423,8 +2433,9 @@ function bound(
// Similarly for the UINT256_MAX side. This helps ensure coverage of the
// min/max values.
if (x <= 3 && size > x) return min + x;
- if (x >= type(uint256).max - 3 && size > type(uint256).max - x)
+ if (x >= type(uint256).max - 3 && size > type(uint256).max - x) {
return max - (type(uint256).max - x);
+ }
// Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.
if (x > max) {
diff --git a/test/foundry/new/helpers/FuzzHelpers.sol b/test/foundry/new/helpers/FuzzHelpers.sol
index eea3fb7d6..afdb59d79 100644
--- a/test/foundry/new/helpers/FuzzHelpers.sol
+++ b/test/foundry/new/helpers/FuzzHelpers.sol
@@ -12,7 +12,7 @@ import {
OrderParametersLib,
SeaportArrays,
ZoneParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -26,7 +26,7 @@ import {
ReceivedItem,
SpentItem,
ZoneParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import {
BasicOrderRouteType,
@@ -34,17 +34,17 @@ import {
ItemType,
OrderType,
Side
-} from "seaport-sol/SeaportEnums.sol";
+} from "seaport-sol/src/SeaportEnums.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
import {
ContractOffererInterface
-} from "seaport-sol/ContractOffererInterface.sol";
+} from "seaport-sol/src/ContractOffererInterface.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
-import { ZoneInterface } from "seaport-sol/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-sol/src/ZoneInterface.sol";
import { FuzzTestContext } from "./FuzzTestContextLib.sol";
@@ -355,8 +355,9 @@ library FuzzHelpers {
uint256 totalSize
) = seaport.getOrderStatus(orderHash);
- if (totalFilled != 0 && totalSize != 0 && totalFilled == totalSize)
+ if (totalFilled != 0 && totalSize != 0 && totalFilled == totalSize) {
return State.FULLY_FILLED;
+ }
if (totalFilled != 0 && totalSize != 0) return State.PARTIALLY_FILLED;
if (isCancelled) return State.CANCELLED;
if (isValidated) return State.VALIDATED;
@@ -722,6 +723,50 @@ library FuzzHelpers {
}
}
+ /**
+ * @dev Derive ZoneParameters from a given restricted order and return
+ * the expected calldata hash for the call to authorizeOrder.
+ *
+ * @param orders The restricted orders.
+ * @param seaport The Seaport address.
+ * @param fulfiller The fulfiller.
+ * @param maximumFulfilled The maximum number of orders to fulfill.
+ * @param criteriaResolvers The criteria resolvers.
+ * @param maximumFulfilled The maximum number of orders to fulfill.
+ * @param unavailableReasons The availability status.
+ *
+ * @return calldataHashes The derived calldata hashes.
+ */
+ function getExpectedZoneAuthorizeCalldataHash(
+ AdvancedOrder[] memory orders,
+ address seaport,
+ address fulfiller,
+ CriteriaResolver[] memory criteriaResolvers,
+ uint256 maximumFulfilled,
+ UnavailableReason[] memory unavailableReasons
+ ) internal view returns (bytes32[] memory calldataHashes) {
+ calldataHashes = new bytes32[](orders.length);
+
+ ZoneParameters[] memory zoneParameters = orders
+ .getZoneAuthorizeParameters(
+ fulfiller,
+ maximumFulfilled,
+ seaport,
+ criteriaResolvers,
+ unavailableReasons
+ );
+
+ for (uint256 i; i < zoneParameters.length; ++i) {
+ // Derive the expected calldata hash for the call to authorizeOrder
+ calldataHashes[i] = keccak256(
+ abi.encodeCall(
+ ZoneInterface.authorizeOrder,
+ (zoneParameters[i])
+ )
+ );
+ }
+ }
+
/**
* @dev Derive ZoneParameters from a given restricted order and return
* the expected calldata hash for the call to validateOrder.
@@ -736,7 +781,7 @@ library FuzzHelpers {
*
* @return calldataHashes The derived calldata hashes.
*/
- function getExpectedZoneCalldataHash(
+ function getExpectedZoneValidateCalldataHash(
AdvancedOrder[] memory orders,
address seaport,
address fulfiller,
@@ -746,13 +791,14 @@ library FuzzHelpers {
) internal view returns (bytes32[] memory calldataHashes) {
calldataHashes = new bytes32[](orders.length);
- ZoneParameters[] memory zoneParameters = orders.getZoneParameters(
- fulfiller,
- maximumFulfilled,
- seaport,
- criteriaResolvers,
- unavailableReasons
- );
+ ZoneParameters[] memory zoneParameters = orders
+ .getZoneValidateParameters(
+ fulfiller,
+ maximumFulfilled,
+ seaport,
+ criteriaResolvers,
+ unavailableReasons
+ );
for (uint256 i; i < zoneParameters.length; ++i) {
// Derive the expected calldata hash for the call to validateOrder
@@ -808,6 +854,36 @@ library FuzzHelpers {
.consideration
.toSpentItemArray();
+ // apply criteria resolvers before hashing
+ for (
+ uint256 j = 0;
+ j < context.executionState.criteriaResolvers.length;
+ ++j
+ ) {
+ CriteriaResolver memory resolver = context
+ .executionState
+ .criteriaResolvers[j];
+
+ if (resolver.orderIndex != i) {
+ continue;
+ }
+
+ // NOTE: assumes that all provided resolvers are valid
+ if (resolver.side == Side.OFFER) {
+ minimumReceived[resolver.index].itemType = ItemType(
+ uint256(minimumReceived[resolver.index].itemType) - 2
+ );
+ minimumReceived[resolver.index].identifier = resolver
+ .identifier;
+ } else {
+ maximumSpent[resolver.index].itemType = ItemType(
+ uint256(maximumSpent[resolver.index].itemType) - 2
+ );
+ maximumSpent[resolver.index].identifier = resolver
+ .identifier;
+ }
+ }
+
// Derive the expected calldata hash for the call to generateOrder
calldataHashes[i][0] = keccak256(
abi.encodeCall(
diff --git a/test/foundry/new/helpers/FuzzInscribers.sol b/test/foundry/new/helpers/FuzzInscribers.sol
index 136ce896b..1ddd2b273 100644
--- a/test/foundry/new/helpers/FuzzInscribers.sol
+++ b/test/foundry/new/helpers/FuzzInscribers.sol
@@ -3,11 +3,11 @@ pragma solidity ^0.8.17;
import { vm } from "./VmUtils.sol";
-import { AdvancedOrder, OrderStatus } from "seaport-sol/SeaportStructs.sol";
+import { AdvancedOrder, OrderStatus } from "seaport-sol/src/SeaportStructs.sol";
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
-import { AdvancedOrderLib } from "seaport-sol/SeaportSol.sol";
+import { AdvancedOrderLib } from "seaport-sol/src/SeaportSol.sol";
/**
* @notice "Inscribers" are helpers that set Seaport state directly by modifying
@@ -332,7 +332,9 @@ library FuzzInscribers {
keccak256(abi.encodePacked(profile)) ==
keccak256(abi.encodePacked("test")) ||
keccak256(abi.encodePacked(profile)) ==
- keccak256(abi.encodePacked("lite"))
+ keccak256(abi.encodePacked("lite")) ||
+ keccak256(abi.encodePacked(profile)) ==
+ keccak256(abi.encodePacked("reference"))
) {
expectedReadAccessCount = 1;
}
diff --git a/test/foundry/new/helpers/FuzzMutationHelpers.sol b/test/foundry/new/helpers/FuzzMutationHelpers.sol
index 2c45ed18e..79866c05a 100644
--- a/test/foundry/new/helpers/FuzzMutationHelpers.sol
+++ b/test/foundry/new/helpers/FuzzMutationHelpers.sol
@@ -1,9 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { AdvancedOrder } from "seaport-sol/SeaportStructs.sol";
+import { AdvancedOrder } from "seaport-sol/src/SeaportStructs.sol";
-import { Side } from "seaport-sol/SeaportEnums.sol";
+import { Side } from "seaport-sol/src/SeaportEnums.sol";
import { FuzzGeneratorContext } from "./FuzzGeneratorContextLib.sol";
@@ -23,9 +23,9 @@ import {
CriteriaResolver,
Execution,
OfferItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
enum MutationContextDerivation {
GENERIC, // No specific selection
@@ -648,7 +648,8 @@ library MutationContextDeriverLib {
mutationState.selectedOrderIndex = orderIndex;
mutationState.selectedOrderHash = context
.executionState
- .orderDetails[orderIndex].orderHash;
+ .orderDetails[orderIndex]
+ .orderHash;
mutationState.side = Side(context.generatorContext.randEnum(0, 1));
mutationState.selectedArbitraryAddress = address(
uint160(
diff --git a/test/foundry/new/helpers/FuzzMutationSelectorLib.sol b/test/foundry/new/helpers/FuzzMutationSelectorLib.sol
index 6972295dd..7d044afc2 100644
--- a/test/foundry/new/helpers/FuzzMutationSelectorLib.sol
+++ b/test/foundry/new/helpers/FuzzMutationSelectorLib.sol
@@ -5,9 +5,9 @@ import {
AdvancedOrder,
CriteriaResolver,
ReceivedItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
import { FuzzTestContext, MutationState } from "./FuzzTestContextLib.sol";
import { FuzzMutations, MutationFilters } from "./FuzzMutations.sol";
@@ -28,31 +28,31 @@ import { LibPRNG } from "solady/src/utils/LibPRNG.sol";
import {
SignatureVerificationErrors
-} from "../../../../contracts/interfaces/SignatureVerificationErrors.sol";
+} from "seaport-types/src/interfaces/SignatureVerificationErrors.sol";
import {
ConsiderationEventsAndErrors
-} from "../../../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import {
FulfillmentApplicationErrors
-} from "../../../../contracts/interfaces/FulfillmentApplicationErrors.sol";
+} from "seaport-types/src/interfaces/FulfillmentApplicationErrors.sol";
import {
CriteriaResolutionErrors
-} from "../../../../contracts/interfaces/CriteriaResolutionErrors.sol";
+} from "seaport-types/src/interfaces/CriteriaResolutionErrors.sol";
import {
TokenTransferrerErrors
-} from "../../../../contracts/interfaces/TokenTransferrerErrors.sol";
+} from "seaport-types/src/interfaces/TokenTransferrerErrors.sol";
import {
ZoneInteractionErrors
-} from "../../../../contracts/interfaces/ZoneInteractionErrors.sol";
+} from "seaport-types/src/interfaces/ZoneInteractionErrors.sol";
import {
AmountDerivationErrors
-} from "../../../../contracts/interfaces/AmountDerivationErrors.sol";
+} from "seaport-types/src/interfaces/AmountDerivationErrors.sol";
import {
HashCalldataContractOfferer
@@ -112,10 +112,10 @@ enum Failure {
InvalidContractOrder_ExcessMaximumSpent, // too many maximum spent items
InvalidContractOrder_IncorrectMaximumSpent, // incorrect (too many, wrong token, etc.) maximum spent items
InvalidContractOrder_InvalidMagicValue, // Offerer did not return correct magic value
- InvalidContractOrder_OfferAmountMismatch, // startAmount != endAmount on contract order offer item
- InvalidContractOrder_ConsiderationAmountMismatch, // startAmount != endAmount on contract order consideration item
- InvalidRestrictedOrder_reverts, // Zone validateOrder call reverts
- InvalidRestrictedOrder_InvalidMagicValue, // Zone validateOrder call returns invalid magic value
+ InvalidRestrictedOrder_authorizeReverts_matchReverts, // Zone authorizeOrder call reverts and triggers a top level match* revert
+ InvalidRestrictedOrder_validateReverts, // Zone validateOrder call reverts
+ InvalidRestrictedOrder_authorizeInvalidMagicValue, // Zone authorizeOrder call returns invalid magic value
+ InvalidRestrictedOrder_validateInvalidMagicValue, // Zone validateOrder call returns invalid magic value
NoContract, // Trying to transfer a token at an address that has no contract
UnusedItemParameters_Token, // Native item with non-zero token
UnusedItemParameters_Identifier, // Native or ERC20 item with non-zero identifier
@@ -347,7 +347,6 @@ library FuzzMutationSelectorLib {
failuresAndFilters[i++] = Failure
.InvalidContractOrder_InsufficientMinimumReceived
.and(Failure.InvalidContractOrder_IncorrectMinimumReceived)
- .and(Failure.InvalidContractOrder_OfferAmountMismatch)
.withOrder(
MutationFilters
.ineligibleWhenNotActiveTimeOrNotContractOrderOrNoOffer
@@ -361,15 +360,22 @@ library FuzzMutationSelectorLib {
failuresAndFilters[i++] = Failure
.InvalidContractOrder_IncorrectMaximumSpent
- .and(Failure.InvalidContractOrder_ConsiderationAmountMismatch)
.withOrder(
MutationFilters
.ineligibleWhenNotActiveTimeOrNotContractOrderOrNoConsideration
);
failuresAndFilters[i++] = Failure
- .InvalidRestrictedOrder_reverts
- .and(Failure.InvalidRestrictedOrder_InvalidMagicValue)
+ .InvalidRestrictedOrder_authorizeReverts_matchReverts
+ .withOrder(
+ MutationFilters
+ .ineligibleWhenFulfillAvailableOrNotAvailableOrNotRestricted
+ );
+
+ failuresAndFilters[i++] = Failure
+ .InvalidRestrictedOrder_authorizeInvalidMagicValue
+ .and(Failure.InvalidRestrictedOrder_validateReverts)
+ .and(Failure.InvalidRestrictedOrder_validateInvalidMagicValue)
.withOrder(
MutationFilters.ineligibleWhenNotAvailableOrNotRestrictedOrder
);
@@ -841,15 +847,14 @@ library FailureDetailsLib {
details_withOrderHash
);
- failureDetailsArray[i++] = ZoneInteractionErrors
- .InvalidContractOrder
+ failureDetailsArray[i++] = HashCalldataContractOfferer
+ .HashCalldataContractOffererGenerateOrderReverts
.selector
.withOrder(
"InvalidContractOrder_generateReverts",
FuzzMutations
- .mutation_invalidContractOrderGenerateReturnsInvalidEncoding
- .selector,
- details_withOrderHash
+ .mutation_invalidContractOrderGenerateReverts
+ .selector
);
failureDetailsArray[i++] = HashCalldataContractOfferer
@@ -917,46 +922,46 @@ library FailureDetailsLib {
details_withOrderHash
);
- failureDetailsArray[i++] = ZoneInteractionErrors
- .InvalidContractOrder
+ failureDetailsArray[i++] = HashValidationZoneOfferer
+ .HashValidationZoneOffererAuthorizeOrderReverts
.selector
.withOrder(
- "InvalidContractOrder_OfferAmountMismatch",
+ "InvalidRestrictedOrder_authorizeReverts_matchReverts",
FuzzMutations
- .mutation_invalidContractOrderOfferAmountMismatch
- .selector,
- details_withOrderHash
+ .mutation_invalidRestrictedOrderAuthorizeRevertsMatchReverts
+ .selector
);
- failureDetailsArray[i++] = ZoneInteractionErrors
- .InvalidContractOrder
+ failureDetailsArray[i++] = HashValidationZoneOfferer
+ .HashValidationZoneOffererValidateOrderReverts
.selector
.withOrder(
- "InvalidContractOrder_ConsiderationAmountMismatch",
- FuzzMutations
- .mutation_invalidContractOrderConsiderationAmountMismatch
- .selector,
- details_withOrderHash
+ "InvalidRestrictedOrder_validateReverts",
+ FuzzMutations.mutation_invalidRestrictedOrderReverts.selector
);
- failureDetailsArray[i++] = HashValidationZoneOfferer
- .HashValidationZoneOffererValidateOrderReverts
+ failureDetailsArray[i++] = ZoneInteractionErrors
+ .InvalidRestrictedOrder
.selector
.withOrder(
- "InvalidRestrictedOrder_reverts",
- FuzzMutations.mutation_invalidRestrictedOrderReverts.selector
+ "InvalidRestrictedOrder_authorizeInvalidMagicValue",
+ FuzzMutations
+ .mutation_invalidRestrictedOrderAuthorizeInvalidMagicValue
+ .selector,
+ details_withOrderHash
);
failureDetailsArray[i++] = ZoneInteractionErrors
.InvalidRestrictedOrder
.selector
.withOrder(
- "InvalidRestrictedOrder_InvalidMagicValue",
+ "InvalidRestrictedOrder_validateInvalidMagicValue",
FuzzMutations
- .mutation_invalidRestrictedOrderInvalidMagicValue
+ .mutation_invalidRestrictedOrderValidateInvalidMagicValue
.selector,
details_withOrderHash
);
+
failureDetailsArray[i++] = TokenTransferrerErrors
.NoContract
.selector
@@ -1128,7 +1133,10 @@ library FailureDetailsLib {
) internal pure returns (bytes memory expectedRevertReason) {
expectedRevertReason = abi.encodeWithSelector(
errorSelector,
- context.executionState.orderDetails[mutationState.selectedOrderIndex].orderHash
+ context
+ .executionState
+ .orderDetails[mutationState.selectedOrderIndex]
+ .orderHash
);
}
diff --git a/test/foundry/new/helpers/FuzzMutations.sol b/test/foundry/new/helpers/FuzzMutations.sol
index 91329f9c9..def2e2f85 100644
--- a/test/foundry/new/helpers/FuzzMutations.sol
+++ b/test/foundry/new/helpers/FuzzMutations.sol
@@ -14,9 +14,9 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType, Side } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType, Side } from "seaport-sol/src/SeaportEnums.sol";
import {
AdvancedOrderLib,
@@ -25,17 +25,17 @@ import {
ItemType,
BasicOrderType,
ConsiderationItemLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
FulfillmentDetails,
OrderDetails
-} from "seaport-sol/fulfillments/lib/Structs.sol";
+} from "seaport-sol/src/fulfillments/lib/Structs.sol";
import {
ContractOrderRebate,
UnavailableReason
-} from "seaport-sol/SpaceEnums.sol";
+} from "seaport-sol/src/SpaceEnums.sol";
import { FractionStatus, FractionUtil } from "./FractionUtil.sol";
@@ -265,6 +265,22 @@ library MutationFilters {
return ineligibleWhenUnavailable(context, orderIndex);
}
+ function ineligibleWhenFulfillAvailableOrNotAvailableOrNotRestricted(
+ AdvancedOrder memory order,
+ uint256 orderIndex,
+ FuzzTestContext memory context
+ ) internal view returns (bool) {
+ if (ineligibleWhenNotRestrictedOrder(order)) {
+ return true;
+ }
+
+ if (ineligibleWhenFulfillAvailable(context)) {
+ return true;
+ }
+
+ return ineligibleWhenUnavailable(context, orderIndex);
+ }
+
function ineligibleWhenNotActiveTime(
AdvancedOrder memory order
) internal view returns (bool) {
@@ -636,11 +652,11 @@ library MutationFilters {
continue;
}
- AdvancedOrder memory order = context.executionState.previewedOrders[
- i
- ];
+ AdvancedOrder memory order = context.executionState.orders[i];
+
uint256 items = order.parameters.offer.length +
order.parameters.consideration.length;
+
if (items != 0) {
locatedItem = true;
break;
@@ -735,6 +751,26 @@ library MutationFilters {
return true;
}
+ // The target failure can't be triggered if the criteria resolver is
+ // referring to a collection-level criteria item on a contract order.
+ if (
+ context
+ .executionState
+ .orders[criteriaResolver.orderIndex]
+ .parameters
+ .orderType ==
+ OrderType.CONTRACT &&
+ context
+ .executionState
+ .orders[criteriaResolver.orderIndex]
+ .parameters
+ .offer[criteriaResolver.index]
+ .identifierOrCriteria ==
+ 0
+ ) {
+ return true;
+ }
+
return false;
}
@@ -762,6 +798,26 @@ library MutationFilters {
return true;
}
+ // The target failure can't be triggered if the criteria resolver is
+ // referring to a collection-level criteria item on a contract order.
+ if (
+ context
+ .executionState
+ .orders[criteriaResolver.orderIndex]
+ .parameters
+ .orderType ==
+ OrderType.CONTRACT &&
+ context
+ .executionState
+ .orders[criteriaResolver.orderIndex]
+ .parameters
+ .consideration[criteriaResolver.index]
+ .identifierOrCriteria ==
+ 0
+ ) {
+ return true;
+ }
+
return false;
}
@@ -1406,10 +1462,9 @@ library MutationFilters {
// part of paying out additional recipient items.
if (
ineligibleWhenBasic(context) &&
- order.parameters.consideration.length > 1 && (
- order.parameters.consideration[0].itemType == ItemType.ERC721 ||
- order.parameters.consideration[0].itemType == ItemType.ERC1155
- )
+ order.parameters.consideration.length > 1 &&
+ (order.parameters.consideration[0].itemType == ItemType.ERC721 ||
+ order.parameters.consideration[0].itemType == ItemType.ERC1155)
) {
return true;
}
@@ -1544,14 +1599,24 @@ library MutationFilters {
uint256 orderIndex,
FuzzTestContext memory context
) internal view returns (bool) {
- // The target failure cannot be triggered in the fulfillAvailable cases
- // because it gets skipped instead. And the match cases cause a
- // MismatchedFulfillmentOfferAndConsiderationComponents(uint256)
- // instead.
- if (
- ineligibleWhenFulfillAvailable(context) ||
- ineligibleWhenMatch(context)
- ) {
+ // The target failure can't be triggered if the order isn't available.
+ if (ineligibleWhenUnavailable(context, orderIndex)) {
+ return true;
+ }
+
+ // The target failure cannot be triggered in fulfillAvailable cases —
+ // they trip a InvalidFulfillmentComponentData error instead. TODO:
+ // perform the mutation on all items that are part of a single
+ // fulfillment element.
+ if (ineligibleWhenFulfillAvailable(context)) {
+ return true;
+ }
+
+ // The target failure cannot be triggered in match cases — they trip a
+ // MismatchedFulfillmentOfferAndConsiderationComponents(uint256) error
+ // instead. TODO: perform the mutation on all items that are part of a
+ // single fulfillment element.
+ if (ineligibleWhenMatch(context)) {
return true;
}
@@ -1587,14 +1652,24 @@ library MutationFilters {
uint256 orderIndex,
FuzzTestContext memory context
) internal view returns (bool) {
- // The target failure cannot be triggered in the fulfillAvailable cases
- // because it gets skipped instead. And the match cases cause a
- // MismatchedFulfillmentOfferAndConsiderationComponents(uint256)
- // instead.
- if (
- ineligibleWhenFulfillAvailable(context) ||
- ineligibleWhenMatch(context)
- ) {
+ // The target failure can't be triggered if the order isn't available.
+ if (ineligibleWhenUnavailable(context, orderIndex)) {
+ return true;
+ }
+
+ // The target failure cannot be triggered in fulfillAvailable cases —
+ // they trip a InvalidFulfillmentComponentData error instead. TODO:
+ // perform the mutation on all items that are part of a single
+ // fulfillment element.
+ if (ineligibleWhenFulfillAvailable(context)) {
+ return true;
+ }
+
+ // The target failure cannot be triggered in match cases — they trip a
+ // MismatchedFulfillmentOfferAndConsiderationComponents(uint256) error
+ // instead. TODO: perform the mutation on all items that are part of a
+ // single fulfillment element.
+ if (ineligibleWhenMatch(context)) {
return true;
}
@@ -1941,6 +2016,26 @@ contract FuzzMutations is Test, FuzzExecutor {
exec(context);
}
+ function mutation_invalidRestrictedOrderAuthorizeRevertsMatchReverts(
+ FuzzTestContext memory context,
+ MutationState memory mutationState
+ ) external {
+ AdvancedOrder memory order = mutationState.selectedOrder;
+ bytes32 orderHash = mutationState.selectedOrderHash;
+
+ // This mutation triggers a revert by setting a failure reason that gets
+ // stored in the HashValidationZone. Note that only
+ // non-fulfillAvailable* functions revert at the seaport level when the
+ // zone reverts on authorize.
+ HashValidationZoneOfferer(payable(order.parameters.zone))
+ .setAuthorizeFailureReason(
+ orderHash,
+ OffererZoneFailureReason.Zone_authorizeRevertsMatchReverts
+ );
+
+ exec(context);
+ }
+
function mutation_invalidRestrictedOrderReverts(
FuzzTestContext memory context,
MutationState memory mutationState
@@ -1949,14 +2044,17 @@ contract FuzzMutations is Test, FuzzExecutor {
bytes32 orderHash = mutationState.selectedOrderHash;
// This mutation triggers a revert by setting a failure reason that gets
- // stored in the HashCalldataContractOfferer.
+ // stored in the HashValidationZoneOfferer.
HashValidationZoneOfferer(payable(order.parameters.zone))
- .setFailureReason(orderHash, OffererZoneFailureReason.Zone_reverts);
+ .setValidateFailureReason(
+ orderHash,
+ OffererZoneFailureReason.Zone_validateReverts
+ );
exec(context);
}
- function mutation_invalidRestrictedOrderInvalidMagicValue(
+ function mutation_invalidRestrictedOrderAuthorizeInvalidMagicValue(
FuzzTestContext memory context,
MutationState memory mutationState
) external {
@@ -1964,11 +2062,29 @@ contract FuzzMutations is Test, FuzzExecutor {
bytes32 orderHash = mutationState.selectedOrderHash;
// This mutation triggers a revert by setting a failure reason that gets
- // stored in the HashCalldataContractOfferer.
+ // stored in the HashValidationZone.
HashValidationZoneOfferer(payable(order.parameters.zone))
- .setFailureReason(
+ .setAuthorizeFailureReason(
orderHash,
- OffererZoneFailureReason.Zone_InvalidMagicValue
+ OffererZoneFailureReason.Zone_authorizeInvalidMagicValue
+ );
+
+ exec(context);
+ }
+
+ function mutation_invalidRestrictedOrderValidateInvalidMagicValue(
+ FuzzTestContext memory context,
+ MutationState memory mutationState
+ ) external {
+ AdvancedOrder memory order = mutationState.selectedOrder;
+ bytes32 orderHash = mutationState.selectedOrderHash;
+
+ // This mutation triggers a revert by setting a failure reason that gets
+ // stored in the HashValidationZone.
+ HashValidationZoneOfferer(payable(order.parameters.zone))
+ .setValidateFailureReason(
+ orderHash,
+ OffererZoneFailureReason.Zone_validateInvalidMagicValue
);
exec(context);
@@ -2280,7 +2396,7 @@ contract FuzzMutations is Test, FuzzExecutor {
}
// Grab the order at the current index.
- AdvancedOrder memory order = context.executionState.previewedOrders[
+ AdvancedOrder memory order = context.executionState.orders[
orderIndex
];
@@ -3023,10 +3139,10 @@ contract FuzzMutations is Test, FuzzExecutor {
.executionState
.criteriaResolvers[criteriaResolverIndex];
- OrderDetails memory order = context.executionState.orderDetails[
+ AdvancedOrder memory order = context.executionState.orders[
resolver.orderIndex
];
- resolver.index = order.consideration.length;
+ resolver.index = order.parameters.consideration.length;
exec(context);
}
@@ -3324,6 +3440,29 @@ contract FuzzMutations is Test, FuzzExecutor {
}
}
+ // For basic orders, the additional recipient items also need to be
+ // modified.
+ bytes4 action = context.action();
+ if (
+ action == context.seaport.fulfillBasicOrder.selector ||
+ action ==
+ context.seaport.fulfillBasicOrder_efficient_6GL6yc.selector
+ ) {
+ for (
+ uint256 i = 1;
+ i < order.parameters.consideration.length;
+ i++
+ ) {
+ ConsiderationItem memory item = order.parameters.consideration[
+ i
+ ];
+
+ if (item.itemType == ItemType.NATIVE) {
+ item.token = address(1);
+ }
+ }
+ }
+
_signOrValidateMutatedOrder(context, orderIndex);
exec(context);
@@ -3370,6 +3509,9 @@ contract FuzzMutations is Test, FuzzExecutor {
}
}
+ // Note that additional recipients do not need to be modified as
+ // identifiers for them are automatically set to 0.
+
_signOrValidateMutatedOrder(context, orderIndex);
exec(context);
@@ -3543,22 +3685,14 @@ contract FuzzMutations is Test, FuzzExecutor {
MutationState memory /* mutationState */
) external {
// This mutation works by wiping out all the orders. Seaport reverts if
- // `_executeAvailableFulfillments` finishes its loop and produces no
- // executions.
-
+ // `_validateOrdersAndPrepareToFulfill` finishes its loop and produces
+ // no unskipped orders.
for (uint256 i; i < context.executionState.orders.length; i++) {
AdvancedOrder memory order = context.executionState.orders[i];
- order.parameters.consideration = new ConsiderationItem[](0);
- order.parameters.totalOriginalConsiderationItems = 0;
+ order.parameters.endTime = 0;
_signOrValidateMutatedOrder(context, i);
}
- context.executionState.offerFulfillments = new FulfillmentComponent[][](
- 0
- );
- context
- .executionState
- .considerationFulfillments = new FulfillmentComponent[][](0);
exec(context);
}
diff --git a/test/foundry/new/helpers/FuzzSetup.sol b/test/foundry/new/helpers/FuzzSetup.sol
index b52f51fe5..886f8021c 100644
--- a/test/foundry/new/helpers/FuzzSetup.sol
+++ b/test/foundry/new/helpers/FuzzSetup.sol
@@ -3,7 +3,10 @@ pragma solidity ^0.8.17;
import { Test } from "forge-std/Test.sol";
-import { ExecutionLib, ZoneParametersLib } from "seaport-sol/SeaportSol.sol";
+import {
+ ExecutionLib,
+ ZoneParametersLib
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -12,13 +15,13 @@ import {
OrderParameters,
ReceivedItem,
SpentItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { OrderDetails } from "seaport-sol/fulfillments/lib/Structs.sol";
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
-import { ItemType, OrderType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType } from "seaport-sol/src/SeaportEnums.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
import { FuzzTestContext } from "./FuzzTestContextLib.sol";
@@ -26,7 +29,7 @@ import { CriteriaResolverHelper } from "./CriteriaResolverHelper.sol";
import {
AmountDeriverHelper
-} from "seaport-sol/lib/fulfillment/AmountDeriverHelper.sol";
+} from "seaport-sol/src/lib/fulfillment/AmountDeriverHelper.sol";
import { ExpectedEventsUtil } from "./event-utils/ExpectedEventsUtil.sol";
@@ -196,10 +199,21 @@ abstract contract FuzzSetup is Test, AmountDeriverHelper {
}
// Get the expected zone calldata hashes for each order.
- bytes32[] memory calldataHashes = context
+ bytes32[] memory authorizeCalldataHashes = context
+ .executionState
+ .orders
+ .getExpectedZoneAuthorizeCalldataHash(
+ address(context.seaport),
+ context.executionState.caller,
+ context.executionState.criteriaResolvers,
+ context.executionState.maximumFulfilled,
+ unavailableReasons
+ );
+
+ bytes32[] memory validateCalldataHashes = context
.executionState
.orders
- .getExpectedZoneCalldataHash(
+ .getExpectedZoneValidateCalldataHash(
address(context.seaport),
context.executionState.caller,
context.executionState.criteriaResolvers,
@@ -207,8 +221,11 @@ abstract contract FuzzSetup is Test, AmountDeriverHelper {
unavailableReasons
);
- // Provision the expected zone calldata hash array.
- bytes32[] memory expectedZoneCalldataHash = new bytes32[](
+ // Provision the expected zone calldata hash arrays.
+ bytes32[] memory expectedZoneAuthorizeCalldataHashes = new bytes32[](
+ context.executionState.orders.length
+ );
+ bytes32[] memory expectedZoneValidateCalldataHashes = new bytes32[](
context.executionState.orders.length
);
@@ -229,15 +246,26 @@ abstract contract FuzzSetup is Test, AmountDeriverHelper {
order.orderType == OrderType.PARTIAL_RESTRICTED)
) {
registerChecks = true;
- expectedZoneCalldataHash[i] = calldataHashes[i];
+ expectedZoneAuthorizeCalldataHashes[
+ i
+ ] = authorizeCalldataHashes[i];
+ expectedZoneValidateCalldataHashes[i] = validateCalldataHashes[
+ i
+ ];
}
}
context
.expectations
- .expectedZoneCalldataHash = expectedZoneCalldataHash;
+ .expectedZoneAuthorizeCalldataHashes = expectedZoneAuthorizeCalldataHashes;
+ context
+ .expectations
+ .expectedZoneValidateCalldataHashes = expectedZoneValidateCalldataHashes;
if (registerChecks) {
+ context.registerCheck(
+ FuzzChecks.check_authorizeOrderExpectedDataHash.selector
+ );
context.registerCheck(
FuzzChecks.check_validateOrderExpectedDataHash.selector
);
diff --git a/test/foundry/new/helpers/FuzzTestContextLib.sol b/test/foundry/new/helpers/FuzzTestContextLib.sol
index d42f98a6e..72a56b315 100644
--- a/test/foundry/new/helpers/FuzzTestContextLib.sol
+++ b/test/foundry/new/helpers/FuzzTestContextLib.sol
@@ -3,13 +3,15 @@ pragma solidity ^0.8.17;
import { Vm } from "forge-std/Vm.sol";
+import { StdCheats } from "forge-std/StdCheats.sol";
+
import { LibPRNG } from "solady/src/utils/LibPRNG.sol";
import {
AdvancedOrderLib,
BasicOrderParametersLib,
MatchComponent
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdvancedOrder,
@@ -19,32 +21,30 @@ import {
Fulfillment,
FulfillmentComponent,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType, OrderType, Side } from "seaport-sol/SeaportEnums.sol";
+import { ItemType, OrderType, Side } from "seaport-sol/src/SeaportEnums.sol";
import {
BroadOrderType,
OrderStatusEnum,
SignatureMethod,
UnavailableReason
-} from "seaport-sol/SpaceEnums.sol";
+} from "seaport-sol/src/SpaceEnums.sol";
-import { AdvancedOrdersSpace } from "seaport-sol/StructSpace.sol";
+import { AdvancedOrdersSpace } from "seaport-sol/src/StructSpace.sol";
-import { OrderDetails } from "seaport-sol/fulfillments/lib/Structs.sol";
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
import {
AmountDeriverHelper
-} from "seaport-sol/lib/fulfillment/AmountDeriverHelper.sol";
+} from "seaport-sol/src/lib/fulfillment/AmountDeriverHelper.sol";
import {
ConduitControllerInterface
-} from "seaport-sol/ConduitControllerInterface.sol";
-
-import { SeaportInterface } from "seaport-sol/SeaportInterface.sol";
+} from "seaport-sol/src/ConduitControllerInterface.sol";
-import { Account } from "../BaseOrderTest.sol";
+import { SeaportInterface } from "seaport-sol/src/SeaportInterface.sol";
import { Result } from "./FuzzHelpers.sol";
@@ -68,6 +68,10 @@ import {
SeaportValidatorInterface
} from "../../../../contracts/helpers/order-validator/SeaportValidator.sol";
+import {
+ SeaportNavigatorInterface
+} from "../../../../contracts/helpers/navigator/SeaportNavigator.sol";
+
interface TestHelpers {
function balanceChecker() external view returns (ExpectedBalances);
@@ -78,9 +82,9 @@ interface TestHelpers {
view
returns (CriteriaResolverHelper);
- function makeAccount(
+ function makeAccountWrapper(
string memory name
- ) external view returns (Account memory);
+ ) external view returns (StdCheats.Account memory);
function getNaiveFulfillmentComponents(
OrderDetails[] memory orderDetails
@@ -138,7 +142,8 @@ struct Expectations {
/**
* @dev Expected zone calldata hashes.
*/
- bytes32[] expectedZoneCalldataHash;
+ bytes32[] expectedZoneAuthorizeCalldataHashes;
+ bytes32[] expectedZoneValidateCalldataHashes;
/**
* @dev Expected contract order calldata hashes. Index 0 of the outer array
* corresponds to the generateOrder hash, while index 1 corresponds to
@@ -315,6 +320,10 @@ struct FuzzTestContext {
* @dev A SeaportValidator interface.
*/
SeaportValidatorInterface seaportValidator;
+ /**
+ * @dev A SeaportNavigator interface.
+ */
+ SeaportNavigatorInterface seaportNavigator;
/**
* @dev A TestHelpers interface. These helper functions are used to generate
* accounts and fulfillments.
@@ -386,10 +395,35 @@ library FuzzTestContextLib {
Result[] memory results;
bool[] memory available;
Execution[] memory executions;
- bytes32[] memory hashes;
- bytes32[] memory expectedTransferEventHashes;
- bytes32[] memory expectedSeaportEventHashes;
Vm.Log[] memory actualEvents;
+ Expectations memory expectations;
+
+ {
+ bytes32[] memory authorizeHashes;
+ bytes32[] memory validateHashes;
+ bytes32[] memory expectedTransferEventHashes;
+ bytes32[] memory expectedSeaportEventHashes;
+
+ expectations = Expectations({
+ expectedZoneAuthorizeCalldataHashes: authorizeHashes,
+ expectedZoneValidateCalldataHashes: validateHashes,
+ expectedContractOrderCalldataHashes: new bytes32[2][](0),
+ expectedImplicitPreExecutions: new Execution[](0),
+ expectedImplicitPostExecutions: new Execution[](0),
+ expectedExplicitExecutions: new Execution[](0),
+ allExpectedExecutions: new Execution[](0),
+ expectedResults: results,
+ // expectedAvailableOrders: new bool[](0),
+ expectedTransferEventHashes: expectedTransferEventHashes,
+ expectedSeaportEventHashes: expectedSeaportEventHashes,
+ ineligibleOrders: new bool[](orders.length),
+ ineligibleFailures: new bool[](uint256(Failure.length)),
+ expectedImpliedNativeExecutions: 0,
+ expectedNativeTokensReturned: 0,
+ minimumValue: 0,
+ expectedFillFractions: new FractionResults[](orders.length)
+ });
+ }
return
FuzzTestContext({
@@ -398,6 +432,7 @@ library FuzzTestContextLib {
seaport: SeaportInterface(address(0)),
conduitController: ConduitControllerInterface(address(0)),
seaportValidator: SeaportValidatorInterface(address(0)),
+ seaportNavigator: SeaportNavigatorInterface(address(0)),
fuzzParams: FuzzParams({
seed: 0,
totalOrders: 0,
@@ -413,24 +448,7 @@ library FuzzTestContextLib {
availableOrders: available,
executions: executions
}),
- expectations: Expectations({
- expectedZoneCalldataHash: hashes,
- expectedContractOrderCalldataHashes: new bytes32[2][](0),
- expectedImplicitPreExecutions: new Execution[](0),
- expectedImplicitPostExecutions: new Execution[](0),
- expectedExplicitExecutions: new Execution[](0),
- allExpectedExecutions: new Execution[](0),
- expectedResults: results,
- // expectedAvailableOrders: new bool[](0),
- expectedTransferEventHashes: expectedTransferEventHashes,
- expectedSeaportEventHashes: expectedSeaportEventHashes,
- ineligibleOrders: new bool[](orders.length),
- ineligibleFailures: new bool[](uint256(Failure.length)),
- expectedImpliedNativeExecutions: 0,
- expectedNativeTokensReturned: 0,
- minimumValue: 0,
- expectedFillFractions: new FractionResults[](orders.length)
- }),
+ expectations: expectations,
executionState: ExecutionState({
caller: address(0),
contractOffererNonce: 0,
@@ -629,6 +647,24 @@ library FuzzTestContextLib {
return context;
}
+ /**
+ * @dev Sets the SeaportNavigatorInterface on a FuzzTestContext
+ *
+ * @param context the FuzzTestContext to set the
+ * SeaportNavigatorInterface of
+ * @param seaportNavigator the SeaportNavigatorInterface to set
+ *
+ * @return _context the FuzzTestContext with the SeaportNavigatorInterface
+ * set
+ */
+ function withSeaportNavigator(
+ FuzzTestContext memory context,
+ SeaportNavigatorInterface seaportNavigator
+ ) internal pure returns (FuzzTestContext memory) {
+ context.seaportNavigator = seaportNavigator;
+ return context;
+ }
+
/**
* @dev Sets the caller on a FuzzTestContext
*
@@ -1054,8 +1090,9 @@ function bound(
// Similarly for the UINT256_MAX side. This helps ensure coverage of the
// min/max values.
if (x <= 3 && size > x) return min + x;
- if (x >= type(uint256).max - 3 && size > type(uint256).max - x)
+ if (x >= type(uint256).max - 3 && size > type(uint256).max - x) {
return max - (type(uint256).max - x);
+ }
// Otherwise, wrap x into the range [min, max], i.e. the range is inclusive.
if (x > max) {
diff --git a/test/foundry/new/helpers/PreapprovedERC721.sol b/test/foundry/new/helpers/PreapprovedERC721.sol
index 04cc6de1a..b5b3074a0 100644
--- a/test/foundry/new/helpers/PreapprovedERC721.sol
+++ b/test/foundry/new/helpers/PreapprovedERC721.sol
@@ -1,4 +1,4 @@
-// SPDX-Identifier: MIT
+// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import { CustomERC721 } from "../../token/CustomERC721.sol";
diff --git a/test/foundry/new/helpers/Searializer.sol b/test/foundry/new/helpers/Searializer.sol
index 453284ae3..6b535b93c 100644
--- a/test/foundry/new/helpers/Searializer.sol
+++ b/test/foundry/new/helpers/Searializer.sol
@@ -15,14 +15,14 @@ import {
OfferItem,
OrderParameters,
ReceivedItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import {
BasicOrderType,
ItemType,
OrderType,
Side
-} from "seaport-sol/SeaportEnums.sol";
+} from "seaport-sol/src/SeaportEnums.sol";
import { Result } from "./FuzzHelpers.sol";
@@ -745,8 +745,13 @@ library Searializer {
tojsonDynArrayBytes4(obj, "checks", value.checks);
tojsonDynArrayBytes32(
obj,
- "expectedZoneCalldataHash",
- value.expectations.expectedZoneCalldataHash
+ "expectedZoneAuthorizeCalldataHashes",
+ value.expectations.expectedZoneAuthorizeCalldataHashes
+ );
+ tojsonDynArrayBytes32(
+ obj,
+ "expectedZoneValidateCalldataHashes",
+ value.expectations.expectedZoneValidateCalldataHashes
);
tojsonDynArrayArray2Bytes32(
obj,
diff --git a/test/foundry/new/helpers/event-utils/EventSerializer.sol b/test/foundry/new/helpers/event-utils/EventSerializer.sol
index 5d86a3004..e09e9623d 100644
--- a/test/foundry/new/helpers/event-utils/EventSerializer.sol
+++ b/test/foundry/new/helpers/event-utils/EventSerializer.sol
@@ -3,9 +3,9 @@ pragma solidity ^0.8.17;
import { vm } from "../VmUtils.sol";
-import { SpentItem, ReceivedItem } from "seaport-sol/SeaportStructs.sol";
+import { SpentItem, ReceivedItem } from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
struct ERC20TransferEvent {
string kind;
@@ -21,10 +21,10 @@ struct ERC721TransferEvent {
address from;
address to;
uint256 identifier;
- // bytes32 topicHash;
- // bytes32 dataHash;
- // bytes32 eventHash;
}
+// bytes32 topicHash;
+// bytes32 dataHash;
+// bytes32 eventHash;
struct ERC1155TransferEvent {
string kind;
@@ -34,10 +34,10 @@ struct ERC1155TransferEvent {
address to;
uint256 identifier;
uint256 amount;
- // bytes32 topicHash;
- // bytes32 dataHash;
- // bytes32 eventHash;
}
+// bytes32 topicHash;
+// bytes32 dataHash;
+// bytes32 eventHash;
struct OrderFulfilledEvent {
bytes32 orderHash;
diff --git a/test/foundry/new/helpers/event-utils/ExecutionsFlattener.sol b/test/foundry/new/helpers/event-utils/ExecutionsFlattener.sol
index c5e425210..d79cd6dc3 100644
--- a/test/foundry/new/helpers/event-utils/ExecutionsFlattener.sol
+++ b/test/foundry/new/helpers/event-utils/ExecutionsFlattener.sol
@@ -1,10 +1,10 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.13;
-import { ArrayHelpers, MemoryPointer } from "seaport-sol/../ArrayHelpers.sol";
+import { ArrayHelpers, MemoryPointer } from "seaport/helpers/ArrayHelpers.sol";
-import { Execution, ItemType } from "seaport-sol/SeaportStructs.sol";
-import { ExecutionLib } from "seaport-sol/lib/ExecutionLib.sol";
+import { Execution, ItemType } from "seaport-sol/src/SeaportStructs.sol";
+import { ExecutionLib } from "seaport-sol/src/lib/ExecutionLib.sol";
import { FuzzTestContext } from "../FuzzTestContextLib.sol";
diff --git a/test/foundry/new/helpers/event-utils/ExpectedEventsUtil.sol b/test/foundry/new/helpers/event-utils/ExpectedEventsUtil.sol
index fa1005e87..a03ee1b53 100644
--- a/test/foundry/new/helpers/event-utils/ExpectedEventsUtil.sol
+++ b/test/foundry/new/helpers/event-utils/ExpectedEventsUtil.sol
@@ -8,9 +8,9 @@ import {
MemoryPointer
} from "../../../../../contracts/helpers/ArrayHelpers.sol";
-import { Execution } from "seaport-sol/SeaportStructs.sol";
+import { Execution } from "seaport-sol/src/SeaportStructs.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
import { FuzzTestContext } from "../FuzzTestContextLib.sol";
@@ -116,10 +116,26 @@ library ExpectedEventsUtil {
"ExpectedEventsUtil: executions length mismatch"
);
+ Execution[] memory filteredExecutions = new Execution[](
+ executions.length
+ );
+
+ uint256 filteredExecutionIndex = 0;
+
+ for (uint256 i = 0; i < executions.length; ++i) {
+ if (executions[i].item.amount > 0) {
+ filteredExecutions[filteredExecutionIndex++] = executions[i];
+ }
+ }
+
+ assembly {
+ mstore(filteredExecutions, filteredExecutionIndex)
+ }
+
context.expectations.expectedTransferEventHashes = ArrayHelpers
.filterMapWithArg
.asExecutionsFilterMap()(
- executions,
+ filteredExecutions,
TransferEventsLib.getTransferEventHash,
context
);
@@ -451,13 +467,11 @@ library Casts {
returns (
function(
bytes32[] memory,
- function(
- uint256,
- uint256,
- ReduceInput memory //Vm.Log[] memory)
- ) internal returns (uint256),
+ function(uint256, uint256, ReduceInput memory)
+ internal
+ returns (uint256),
uint256,
- ReduceInput memory //Vm.Log[] memory
+ ReduceInput memory
) internal returns (uint256) fnOut
)
{
diff --git a/test/foundry/new/helpers/event-utils/ForgeEventsLib.sol b/test/foundry/new/helpers/event-utils/ForgeEventsLib.sol
index 48aa5e61f..5b3d94b8b 100644
--- a/test/foundry/new/helpers/event-utils/ForgeEventsLib.sol
+++ b/test/foundry/new/helpers/event-utils/ForgeEventsLib.sol
@@ -1,13 +1,11 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { Strings } from "openzeppelin-contracts/contracts/utils/Strings.sol";
+import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { Vm } from "forge-std/Vm.sol";
-import {
- MemoryPointer
-} from "../../../../../contracts/helpers/PointerLibraries.sol";
+import { MemoryPointer } from "seaport-types/src/helpers/PointerLibraries.sol";
import { getEventHash, getTopicsHash } from "./EventHashes.sol";
@@ -82,7 +80,7 @@ library ForgeEventsLib {
bytes32 topic3,
) = getTopics(log);
- MemoryPointer data = toMemoryPointer(log).pptr(32);
+ MemoryPointer data = toMemoryPointer(log).pptrOffset(32);
assembly {
switch topicsCount
case 4 {
@@ -130,10 +128,10 @@ library ForgeEventsLib {
address(uint160(uint256(topic1))),
address(uint160(uint256(topic2))),
uint256(topic3)
- // getForgeTopicsHash(log),
- // getDataHash(log),
- // getForgeEventHash(log)
).serializeERC721TransferEvent(objectKey, valueKey);
+ // getForgeTopicsHash(log),
+ // getDataHash(log),
+ // getForgeEventHash(log)
} else {
ERC20TransferEvent memory eventData;
eventData.kind = "ERC20";
diff --git a/test/foundry/new/helpers/event-utils/OrderFulfilledEventsLib.sol b/test/foundry/new/helpers/event-utils/OrderFulfilledEventsLib.sol
index 2f0303b1f..3e49e059f 100644
--- a/test/foundry/new/helpers/event-utils/OrderFulfilledEventsLib.sol
+++ b/test/foundry/new/helpers/event-utils/OrderFulfilledEventsLib.sol
@@ -12,23 +12,17 @@ import {
OrderParameters,
SpentItem,
ReceivedItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import {
- OrderDetails
-} from "../../../../../contracts/helpers/sol/fulfillments/lib/Structs.sol";
+import { OrderDetails } from "seaport-sol/src/fulfillments/lib/Structs.sol";
import { FuzzTestContext } from "../FuzzTestContextLib.sol";
import { getEventHashWithTopics, getTopicsHash } from "./EventHashes.sol";
-import {
- AdvancedOrderLib
-} from "../../../../../contracts/helpers/sol/lib/AdvancedOrderLib.sol";
+import { AdvancedOrderLib } from "seaport-sol/src/lib/AdvancedOrderLib.sol";
-import {
- OrderParametersLib
-} from "../../../../../contracts/helpers/sol/lib/OrderParametersLib.sol";
+import { OrderParametersLib } from "seaport-sol/src/lib/OrderParametersLib.sol";
import {
OrderFulfilledEvent,
diff --git a/test/foundry/new/helpers/event-utils/OrdersMatchedEventsLib.sol b/test/foundry/new/helpers/event-utils/OrdersMatchedEventsLib.sol
index 4e6677d64..c57506317 100644
--- a/test/foundry/new/helpers/event-utils/OrdersMatchedEventsLib.sol
+++ b/test/foundry/new/helpers/event-utils/OrdersMatchedEventsLib.sol
@@ -5,7 +5,7 @@ import { FuzzTestContext } from "../FuzzTestContextLib.sol";
import { getEventHashWithTopics } from "./EventHashes.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
library OrdersMatchedEventsLib {
event OrdersMatched(bytes32[] orderHashes);
diff --git a/test/foundry/new/helpers/event-utils/TransferEventsLib.sol b/test/foundry/new/helpers/event-utils/TransferEventsLib.sol
index dbf11d9fd..bef0a43b6 100644
--- a/test/foundry/new/helpers/event-utils/TransferEventsLib.sol
+++ b/test/foundry/new/helpers/event-utils/TransferEventsLib.sol
@@ -9,7 +9,7 @@ import {
Execution,
ItemType,
ReceivedItem
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import { FuzzTestContext } from "../FuzzTestContextLib.sol";
@@ -86,15 +86,15 @@ library TransferEventsLib {
execution.offerer,
address(item.recipient),
item.identifier
- // getTopicsHash(
- // Transfer.selector, // topic0
- // execution.offerer.toBytes32(), // topic1
- // toBytes32(item.recipient), // topic2
- // bytes32(item.identifier) // topic3
- // ),
- // keccak256(""),
- // getERC721TransferEventHash(execution)
).serializeERC721TransferEvent(objectKey, valueKey);
+ // getTopicsHash(
+ // Transfer.selector, // topic0
+ // execution.offerer.toBytes32(), // topic1
+ // toBytes32(item.recipient), // topic2
+ // bytes32(item.identifier) // topic3
+ // ),
+ // keccak256(""),
+ // getERC721TransferEventHash(execution)
}
if (itemType == ItemType.ERC1155) {
ReceivedItem memory item = execution.item;
@@ -108,15 +108,15 @@ library TransferEventsLib {
address(item.recipient),
item.identifier,
item.amount
- // getTopicsHash(
- // TransferSingle.selector, // topic0
- // _getConduit(execution.conduitKey, context).toBytes32(), // topic1 = operator
- // execution.offerer.toBytes32(), // topic2 = from
- // toBytes32(item.recipient) // topic3 = to
- // ),
- // keccak256(abi.encode(item.identifier, item.amount)), // dataHash
- // getERC1155TransferEventHash(execution, context) // event hash
);
+ // getTopicsHash(
+ // TransferSingle.selector, // topic0
+ // _getConduit(execution.conduitKey, context).toBytes32(), // topic1 = operator
+ // execution.offerer.toBytes32(), // topic2 = from
+ // toBytes32(item.recipient) // topic3 = to
+ // ),
+ // keccak256(abi.encode(item.identifier, item.amount)), // dataHash
+ // getERC1155TransferEventHash(execution, context) // event hash
return eventData.serializeERC1155TransferEvent(objectKey, valueKey);
}
diff --git a/test/foundry/new/helpers/sol/FulfillAvailableHelper.t.sol b/test/foundry/new/helpers/sol/FulfillAvailableHelper.t.sol
index be3603798..309fbb96c 100644
--- a/test/foundry/new/helpers/sol/FulfillAvailableHelper.t.sol
+++ b/test/foundry/new/helpers/sol/FulfillAvailableHelper.t.sol
@@ -8,20 +8,20 @@ import {
OfferItemLib,
OrderParametersLib,
SeaportArrays
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
ConsiderationItem,
OfferItem,
FulfillmentComponent,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
import {
FulfillAvailableHelper
-} from "seaport-sol/fulfillments/available/FulfillAvailableHelper.sol";
+} from "seaport-sol/src/fulfillments/available/FulfillAvailableHelper.sol";
contract FulfillAvailableHelperTest is Test {
using ConsiderationItemLib for ConsiderationItem;
diff --git a/test/foundry/new/helpers/sol/MatchFulfillmentHelper.t.sol b/test/foundry/new/helpers/sol/MatchFulfillmentHelper.t.sol
index 01d8003db..6fbe73f93 100644
--- a/test/foundry/new/helpers/sol/MatchFulfillmentHelper.t.sol
+++ b/test/foundry/new/helpers/sol/MatchFulfillmentHelper.t.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { Strings } from "openzeppelin-contracts/contracts/utils/Strings.sol";
+import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import {
ConsiderationItemLib,
@@ -11,7 +11,7 @@ import {
OrderLib,
OrderParametersLib,
SeaportArrays
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
ConsiderationItem,
@@ -21,22 +21,22 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
import {
MatchFulfillmentHelper
-} from "seaport-sol/fulfillments/match/MatchFulfillmentHelper.sol";
+} from "seaport-sol/src/fulfillments/match/MatchFulfillmentHelper.sol";
import {
MatchComponent,
MatchComponentType
-} from "seaport-sol/lib/types/MatchComponentType.sol";
+} from "seaport-sol/src/lib/types/MatchComponentType.sol";
-import { Account, BaseOrderTest } from "../../BaseOrderTest.sol";
+import { BaseOrderTest } from "../../BaseOrderTest.sol";
contract MatchFulfillmentHelperTest is BaseOrderTest {
using Strings for uint256;
@@ -2001,17 +2001,17 @@ contract MatchFulfillmentHelperTest is BaseOrderTest {
}
OrderParameters memory parameters = order
- .parameters
- .copy()
- .withOfferer(offerer.addr)
- .withStartTime(block.timestamp)
- // Bump the end time by 100 so that the test doesn't try to match the
- // same order twice.
+ .parameters
+ .copy()
+ .withOfferer(offerer.addr)
+ .withStartTime(block.timestamp)
.withEndTime(block.timestamp + 1)
.withTotalOriginalConsiderationItems(
order.parameters.consideration.length
)
.withSalt(salt);
+ // Bump the end time by 100 so that the test doesn't try to match the
+ // same order twice.
OrderComponents memory orderComponents = parameters
.toOrderComponents(seaport.getCounter(offerer.addr))
diff --git a/test/foundry/new/helpers/sol/MatchFulfillmentPriv.t.sol b/test/foundry/new/helpers/sol/MatchFulfillmentPriv.t.sol
index 48be27257..4ed727d3a 100644
--- a/test/foundry/new/helpers/sol/MatchFulfillmentPriv.t.sol
+++ b/test/foundry/new/helpers/sol/MatchFulfillmentPriv.t.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { Strings } from "openzeppelin-contracts/contracts/utils/Strings.sol";
+import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { Test } from "forge-std/Test.sol";
@@ -11,19 +11,19 @@ import {
ConsiderationItemLib,
OfferItemLib,
OrderParametersLib
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
MatchFulfillmentLib,
ProcessComponentParams
-} from "seaport-sol/fulfillments/match/MatchFulfillmentLib.sol";
+} from "seaport-sol/src/fulfillments/match/MatchFulfillmentLib.sol";
import {
MatchComponent,
MatchComponentType
-} from "seaport-sol/lib/types/MatchComponentType.sol";
+} from "seaport-sol/src/lib/types/MatchComponentType.sol";
-import { MatchArrays } from "seaport-sol/fulfillments/lib/MatchArrays.sol";
+import { MatchArrays } from "seaport-sol/src/fulfillments/lib/MatchArrays.sol";
import {
ConsiderationItem,
@@ -31,7 +31,7 @@ import {
FulfillmentComponent,
OfferItem,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
contract MatchFulfillmentLibTest is Test {
using ConsiderationItemLib for ConsiderationItem;
diff --git a/test/foundry/new/helpers/sol/lib/fulfillment/AmountDeriverHelper.t.sol b/test/foundry/new/helpers/sol/lib/fulfillment/AmountDeriverHelper.t.sol
index ab459e4cd..881395a47 100644
--- a/test/foundry/new/helpers/sol/lib/fulfillment/AmountDeriverHelper.t.sol
+++ b/test/foundry/new/helpers/sol/lib/fulfillment/AmountDeriverHelper.t.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.17;
import { Test } from "forge-std/Test.sol";
import {
AmountDeriverHelper
-} from "seaport-sol/lib/fulfillment/AmountDeriverHelper.sol";
+} from "seaport-sol/src/lib/fulfillment/AmountDeriverHelper.sol";
contract TestAmountDeriverHelper is AmountDeriverHelper {
function applyFraction(
diff --git a/test/foundry/new/helpers/sol/lib/types/MatchComponentType.t.sol b/test/foundry/new/helpers/sol/lib/types/MatchComponentType.t.sol
index de45b362b..937791ed1 100644
--- a/test/foundry/new/helpers/sol/lib/types/MatchComponentType.t.sol
+++ b/test/foundry/new/helpers/sol/lib/types/MatchComponentType.t.sol
@@ -6,7 +6,7 @@ import { Test } from "forge-std/Test.sol";
import {
MatchComponent,
MatchComponentType
-} from "seaport-core/helpers/sol/lib/types/MatchComponentType.sol";
+} from "seaport-sol/src/lib/types/MatchComponentType.sol";
contract MatchComponentTypeTest is Test {
using MatchComponentType for MatchComponent;
diff --git a/test/foundry/new/zones/ValidationOffererZone.sol b/test/foundry/new/zones/ValidationOffererZone.sol
index 50747f7bf..47357f246 100644
--- a/test/foundry/new/zones/ValidationOffererZone.sol
+++ b/test/foundry/new/zones/ValidationOffererZone.sol
@@ -1,20 +1,20 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
-import { ItemType } from "seaport-sol/SeaportEnums.sol";
+import { ItemType } from "seaport-sol/src/SeaportEnums.sol";
import {
ReceivedItem,
Schema,
SpentItem,
ZoneParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import {
ContractOffererInterface
-} from "seaport-core/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ZoneInterface } from "seaport-core/interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
contract ValidationOffererZone is ContractOffererInterface, ZoneInterface {
error IncorrectSpentAmount(address fulfiller, bytes32 got, uint256 want);
@@ -27,6 +27,12 @@ contract ValidationOffererZone is ContractOffererInterface, ZoneInterface {
receive() external payable {}
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) public pure returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
+
/**
* @dev Validates that the parties have received the correct items.
*
diff --git a/test/foundry/offerers/AdjustedAmountOfferer.t.sol b/test/foundry/offerers/AdjustedAmountOfferer.t.sol
index 9b3bb4e1c..2c8f8bbe6 100644
--- a/test/foundry/offerers/AdjustedAmountOfferer.t.sol
+++ b/test/foundry/offerers/AdjustedAmountOfferer.t.sol
@@ -7,30 +7,30 @@ import { AdjustedAmountOfferer } from "./impl/AdjustedAmountOfferer.sol";
import {
ERC20Interface
-} from "../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
OrderType,
ItemType
-} from "../../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationItem,
AdvancedOrder,
CriteriaResolver
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ConsiderationEventsAndErrors
-} from "../../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import {
ZoneInteractionErrors
-} from "../../../contracts/interfaces/ZoneInteractionErrors.sol";
+} from "seaport-types/src/interfaces/ZoneInteractionErrors.sol";
contract AdjustedAmountOffererTest is
BaseOrderTest,
@@ -198,57 +198,57 @@ contract AdjustedAmountOffererTest is
fulfillAdvanced(context, configureAdvancedOrder());
}
- // make sure altering offer item start/end amount results in falure
-
- function testAlterOfferItem() public {
- setUpOfferer(0, 0);
- setUpNormalOrder(address(offerer));
- offerItems[0].endAmount += 1;
-
- test(this.execAlterOfferItem, Context({ seaport: consideration }));
- test(
- this.execAlterOfferItem,
- Context({ seaport: referenceConsideration })
- );
- }
-
- function execAlterOfferItem(Context memory context) external stateless {
- vm.expectRevert(
- abi.encodeWithSelector(
- InvalidContractOrder.selector,
- uint256(uint160(address(offerer))) << 96
- )
- );
- fulfillAdvanced(context, configureAdvancedOrder());
- }
-
- // make sure altering consideration item start/end amount results in falure
- function testAlterConsiderationItem() public {
- setUpOfferer(0, 0);
- setUpNormalOrder(address(offerer));
- considerationItems[0].endAmount += 1;
-
- test(
- this.execAlterConsiderationItem,
- Context({ seaport: consideration })
- );
- test(
- this.execAlterConsiderationItem,
- Context({ seaport: referenceConsideration })
- );
- }
-
- function execAlterConsiderationItem(
- Context memory context
- ) external stateless {
- vm.expectRevert(
- abi.encodeWithSelector(
- InvalidContractOrder.selector,
- uint256(uint160(address(offerer))) << 96
- )
- );
- fulfillAdvanced(context, configureAdvancedOrder());
- }
+ // NOTE: this behavior has been modified as generateOrder is now called
+ // after amount derivation; the following tests are no longer valid
+ // function testAlterOfferItem() public {
+ // setUpOfferer(0, 0);
+ // setUpNormalOrder(address(offerer));
+ // offerItems[0].endAmount += 1;
+
+ // test(this.execAlterOfferItem, Context({ seaport: consideration }));
+ // test(
+ // this.execAlterOfferItem,
+ // Context({ seaport: referenceConsideration })
+ // );
+ // }
+
+ // function execAlterOfferItem(Context memory context) external stateless {
+ // vm.expectRevert(
+ // abi.encodeWithSelector(
+ // InvalidContractOrder.selector,
+ // uint256(uint160(address(offerer))) << 96
+ // )
+ // );
+ // fulfillAdvanced(context, configureAdvancedOrder());
+ // }
+
+ // // make sure altering consideration item start/end amount results in falure
+ // function testAlterConsiderationItem() public {
+ // setUpOfferer(0, 0);
+ // setUpNormalOrder(address(offerer));
+ // considerationItems[0].endAmount += 1;
+
+ // test(
+ // this.execAlterConsiderationItem, Context({ seaport: consideration })
+ // );
+ // test(
+ // this.execAlterConsiderationItem,
+ // Context({ seaport: referenceConsideration })
+ // );
+ // }
+
+ // function execAlterConsiderationItem(Context memory context)
+ // external
+ // stateless
+ // {
+ // vm.expectRevert(
+ // abi.encodeWithSelector(
+ // InvalidContractOrder.selector,
+ // uint256(uint160(address(offerer))) << 96
+ // )
+ // );
+ // fulfillAdvanced(context, configureAdvancedOrder());
+ // }
function configureAdvancedOrder() internal returns (AdvancedOrder memory) {
return configureAdvancedOrder(1, 1);
diff --git a/test/foundry/offerers/BadOfferer.t.sol b/test/foundry/offerers/BadOfferer.t.sol
index b6d3e45f5..3dd893f60 100644
--- a/test/foundry/offerers/BadOfferer.t.sol
+++ b/test/foundry/offerers/BadOfferer.t.sol
@@ -8,11 +8,11 @@ import { BadOfferer } from "./impl/BadOfferer.sol";
import {
ERC20Interface,
ERC721Interface
-} from "../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
OfferItem,
@@ -21,16 +21,16 @@ import {
CriteriaResolver,
OrderParameters,
FulfillmentComponent
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ItemType,
OrderType
-} from "../../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ZoneInteractionErrors
-} from "../../../contracts/interfaces/ZoneInteractionErrors.sol";
+} from "seaport-types/src/interfaces/ZoneInteractionErrors.sol";
contract BadOffererTest is BaseOrderTest, ZoneInteractionErrors {
BadOfferer badOfferer;
diff --git a/test/foundry/offerers/ContractOffersNativeTokenOfferItems.t.sol b/test/foundry/offerers/ContractOffersNativeTokenOfferItems.t.sol
index 57a9bb634..4e6a38adf 100644
--- a/test/foundry/offerers/ContractOffersNativeTokenOfferItems.t.sol
+++ b/test/foundry/offerers/ContractOffersNativeTokenOfferItems.t.sol
@@ -10,18 +10,18 @@ import { DifferentialTest } from "../utils/DifferentialTest.sol";
import {
ERC20Interface,
ERC721Interface
-} from "../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
ItemType,
OrderType
-} from "../../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
-import { ItemType } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
AdvancedOrder,
@@ -30,11 +30,11 @@ import {
CriteriaResolver,
SpentItem,
ReceivedItem
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ContractOffererInterface
-} from "../../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
import {
TestContractOffererNativeToken
diff --git a/test/foundry/offerers/OffererCriteriaAdvanced.t.sol b/test/foundry/offerers/OffererCriteriaAdvanced.t.sol
index 35dcd6d93..f4908c92b 100644
--- a/test/foundry/offerers/OffererCriteriaAdvanced.t.sol
+++ b/test/foundry/offerers/OffererCriteriaAdvanced.t.sol
@@ -10,32 +10,32 @@ import { Merkle } from "murky/Merkle.sol";
import {
ERC20Interface,
ERC721Interface
-} from "../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
OrderType,
ItemType,
Side
-} from "../../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationItem,
OfferItem,
AdvancedOrder,
CriteriaResolver
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
ConsiderationEventsAndErrors
-} from "../../../contracts/interfaces/ConsiderationEventsAndErrors.sol";
+} from "seaport-types/src/interfaces/ConsiderationEventsAndErrors.sol";
import {
ZoneInteractionErrors
-} from "../../../contracts/interfaces/ZoneInteractionErrors.sol";
+} from "seaport-types/src/interfaces/ZoneInteractionErrors.sol";
contract OffererCriteriaAdvancedTest is
BaseOrderTest,
diff --git a/test/foundry/offerers/StatefulOfferer.t.sol b/test/foundry/offerers/StatefulOfferer.t.sol
index d3b599914..605bb9062 100644
--- a/test/foundry/offerers/StatefulOfferer.t.sol
+++ b/test/foundry/offerers/StatefulOfferer.t.sol
@@ -8,11 +8,11 @@ import { StatefulRatifierOfferer } from "./impl/StatefulRatifierOfferer.sol";
import {
ERC20Interface,
ERC721Interface
-} from "../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
OfferItem,
@@ -21,9 +21,9 @@ import {
CriteriaResolver,
OrderComponents,
FulfillmentComponent
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { OrderType } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
contract StatefulOffererTest is BaseOrderTest {
StatefulRatifierOfferer offerer;
diff --git a/test/foundry/offerers/TestPoolOffererImpl.t.sol b/test/foundry/offerers/TestPoolOffererImpl.t.sol
index ffa1a83a5..9f9b0458e 100644
--- a/test/foundry/offerers/TestPoolOffererImpl.t.sol
+++ b/test/foundry/offerers/TestPoolOffererImpl.t.sol
@@ -3,30 +3,26 @@ pragma solidity ^0.8.7;
import { Test } from "forge-std/Test.sol";
-import { ItemType } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
SpentItem,
ReceivedItem
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
EnumerableSet
-} from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol";
+} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
-import {
- IERC721
-} from "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
+import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import {
- IERC20
-} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {
ContractOffererInterface
-} from "../../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import { TestERC20 } from "../../../contracts/test/TestERC20.sol";
@@ -34,6 +30,8 @@ import { TestERC721 } from "../../../contracts/test/TestERC721.sol";
import { TestPoolOfferer } from "./impl/TestPoolOfferer.sol";
+import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol";
+
contract TestPoolFactoryImpl {
address immutable seaport;
diff --git a/test/foundry/offerers/TestPoolOffererTest.t.sol b/test/foundry/offerers/TestPoolOffererTest.t.sol
index 1378e48eb..9b36f53d8 100644
--- a/test/foundry/offerers/TestPoolOffererTest.t.sol
+++ b/test/foundry/offerers/TestPoolOffererTest.t.sol
@@ -14,9 +14,9 @@ import {
CriteriaResolver,
OfferItem,
OrderType
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
contract TestPoolOffererTest is BaseOrderTest {
TestPoolFactory factory;
diff --git a/test/foundry/offerers/impl/AdjustedAmountOfferer.sol b/test/foundry/offerers/impl/AdjustedAmountOfferer.sol
index f4e924e4d..d39ff70e7 100644
--- a/test/foundry/offerers/impl/AdjustedAmountOfferer.sol
+++ b/test/foundry/offerers/impl/AdjustedAmountOfferer.sol
@@ -3,19 +3,19 @@ pragma solidity ^0.8.13;
import {
ERC20Interface
-} from "../../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../../../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {
SpentItem,
ReceivedItem,
Schema
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract AdjustedAmountOfferer is ContractOffererInterface, ERC165 {
int256 immutable offerAmountAdjust;
diff --git a/test/foundry/offerers/impl/BadOfferer.sol b/test/foundry/offerers/impl/BadOfferer.sol
index 4006b8001..9d5a975e5 100644
--- a/test/foundry/offerers/impl/BadOfferer.sol
+++ b/test/foundry/offerers/impl/BadOfferer.sol
@@ -4,21 +4,21 @@ pragma solidity ^0.8.13;
import {
ERC20Interface,
ERC721Interface
-} from "../../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../../../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import { ItemType } from "../../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ReceivedItem,
Schema,
SpentItem
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
interface ERC20Mintable {
function mint(address to, uint256 amount) external;
diff --git a/test/foundry/offerers/impl/PassthroughOfferer.sol b/test/foundry/offerers/impl/PassthroughOfferer.sol
index 96b2ac1c5..ee8b406ac 100644
--- a/test/foundry/offerers/impl/PassthroughOfferer.sol
+++ b/test/foundry/offerers/impl/PassthroughOfferer.sol
@@ -4,19 +4,19 @@ pragma solidity ^0.8.13;
import {
ERC20Interface,
ERC721Interface
-} from "../../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../../../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
import {
SpentItem,
ReceivedItem,
Schema
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract PassthroughOfferer is ERC165, ContractOffererInterface {
constructor(
diff --git a/test/foundry/offerers/impl/StatefulRatifierOfferer.sol b/test/foundry/offerers/impl/StatefulRatifierOfferer.sol
index 14f03550b..edd2c2f01 100644
--- a/test/foundry/offerers/impl/StatefulRatifierOfferer.sol
+++ b/test/foundry/offerers/impl/StatefulRatifierOfferer.sol
@@ -4,24 +4,21 @@ pragma solidity ^0.8.13;
import {
ERC20Interface,
ERC721Interface
-} from "../../../../contracts/interfaces/AbridgedTokenInterfaces.sol";
+} from "seaport-types/src/interfaces/AbridgedTokenInterfaces.sol";
import {
ContractOffererInterface
-} from "../../../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import {
- ItemType,
- Side
-} from "../../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType, Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
SpentItem,
ReceivedItem,
Schema
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
interface ERC20Mintable {
function mint(address to, uint256 amount) external;
diff --git a/test/foundry/offerers/impl/TestPoolFactory.sol b/test/foundry/offerers/impl/TestPoolFactory.sol
index ad3086d70..156fa3312 100644
--- a/test/foundry/offerers/impl/TestPoolFactory.sol
+++ b/test/foundry/offerers/impl/TestPoolFactory.sol
@@ -1,13 +1,9 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
-import {
- IERC721
-} from "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
+import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import {
- IERC20
-} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { TestPoolOfferer } from "./TestPoolOfferer.sol";
diff --git a/test/foundry/offerers/impl/TestPoolOfferer.sol b/test/foundry/offerers/impl/TestPoolOfferer.sol
index 568c80d04..3baca95da 100644
--- a/test/foundry/offerers/impl/TestPoolOfferer.sol
+++ b/test/foundry/offerers/impl/TestPoolOfferer.sol
@@ -3,33 +3,27 @@ pragma solidity ^0.8.7;
import {
ContractOffererInterface
-} from "../../../../contracts/interfaces/ContractOffererInterface.sol";
+} from "seaport-types/src/interfaces/ContractOffererInterface.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import { ItemType } from "../../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
SpentItem,
ReceivedItem,
Schema
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
EnumerableSet
-} from "openzeppelin-contracts/contracts/utils/structs/EnumerableSet.sol";
+} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
-import {
- IERC721
-} from "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
-
-import {
- IERC20
-} from "openzeppelin-contracts/contracts/token/ERC20/IERC20.sol";
+import { IERC721 } from "@openzeppelin/contracts/token/ERC721/IERC721.sol";
-import { Ownable } from "openzeppelin-contracts/contracts/access/Ownable.sol";
+import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
-contract TestPoolOfferer is ERC165, ContractOffererInterface, Ownable {
+contract TestPoolOfferer is ERC165, ContractOffererInterface {
using EnumerableSet for EnumerableSet.UintSet;
error OnlySeaport();
@@ -126,7 +120,8 @@ contract TestPoolOfferer is ERC165, ContractOffererInterface, Ownable {
balance = newBalance;
}
- /** @dev Generate an offer and consideration based on the minimumReceived
+ /**
+ * @dev Generate an offer and consideration based on the minimumReceived
* and maximumSpent arrays.
*
* @param minimumReceived An array of SpentItem structs representing the
@@ -337,7 +332,8 @@ contract TestPoolOfferer is ERC165, ContractOffererInterface, Ownable {
}
}
- /** @dev Generate offer and consideration items based on the number of
+ /**
+ * @dev Generate offer and consideration items based on the number of
* ERC721 tokens offered or requested.
*
* @param minimumReceived An array of SpentItem structs representing the
@@ -466,7 +462,8 @@ contract TestPoolOfferer is ERC165, ContractOffererInterface, Ownable {
}
}
- /** @dev Validates each SpentItem. Ensures that the item type is valid, all
+ /**
+ * @dev Validates each SpentItem. Ensures that the item type is valid, all
* tokens are homogenous, and that the addresses are those we expect.
*
* @param offerItem The item to validate.
@@ -545,23 +542,21 @@ contract TestPoolOfferer is ERC165, ContractOffererInterface, Ownable {
/**
* @dev Transfers the contract's entire ERC20 and ERC721 balances to the
- * contract's owner.
+ * caller. Obviously this is unsafe for production use as there's no access
+ * control.
*/
- function withdrawAll() external onlyOwner {
+ function withdrawAll() external {
// Get the contract's ERC20 balance.
IERC20 ierc20 = IERC20(erc20);
uint256 erc20Balance = ierc20.balanceOf(address(this));
- // Get the contract's owner address.
- address owner = owner();
-
- // Transfer the ERC20 balance to the contract's owner.
- ierc20.transfer(owner, erc20Balance);
+ // Transfer the ERC20 balance to the caller.
+ ierc20.transfer(msg.sender, erc20Balance);
- // Transfer each ERC721 token to the contract's owner.
+ // Transfer each ERC721 token to the caller.
while (tokenIds.length() > 0) {
uint256 tokenId = tokenIds.at(0);
- IERC721(erc721).transferFrom(address(this), owner, tokenId);
+ IERC721(erc721).transferFrom(address(this), msg.sender, tokenId);
// Remove the token from the set.
tokenIds.remove(tokenId);
diff --git a/test/foundry/utils/BaseConsiderationTest.sol b/test/foundry/utils/BaseConsiderationTest.sol
index 9d0935e46..3bbb50652 100644
--- a/test/foundry/utils/BaseConsiderationTest.sol
+++ b/test/foundry/utils/BaseConsiderationTest.sol
@@ -3,7 +3,7 @@ pragma solidity ^0.8.17;
import {
ConduitController
-} from "../../../contracts/conduit/ConduitController.sol";
+} from "seaport-core/src/conduit/ConduitController.sol";
import {
ReferenceConduitController
@@ -11,26 +11,26 @@ import {
import {
ConduitControllerInterface
-} from "../../../contracts/interfaces/ConduitControllerInterface.sol";
+} from "seaport-types/src/interfaces/ConduitControllerInterface.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
-import { ItemType } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
OfferItem,
ConsiderationItem
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { DifferentialTest } from "./DifferentialTest.sol";
import { StructCopier } from "./StructCopier.sol";
-import { Conduit } from "../../../contracts/conduit/Conduit.sol";
+import { Conduit } from "seaport-core/src/conduit/Conduit.sol";
-import { Consideration } from "../../../contracts/lib/Consideration.sol";
+import { Consideration } from "seaport-core/src/lib/Consideration.sol";
import {
ReferenceConsideration
diff --git a/test/foundry/utils/BaseOrderTest.sol b/test/foundry/utils/BaseOrderTest.sol
index 78034688a..6b700cef9 100644
--- a/test/foundry/utils/BaseOrderTest.sol
+++ b/test/foundry/utils/BaseOrderTest.sol
@@ -4,7 +4,7 @@ pragma solidity ^0.8.17;
import {
FulfillAvailableHelper,
MatchFulfillmentHelper
-} from "seaport-sol/SeaportSol.sol";
+} from "seaport-sol/src/SeaportSol.sol";
import {
AdditionalRecipient,
@@ -13,24 +13,24 @@ import {
Order,
OrderComponents,
OrderParameters
-} from "seaport-sol/SeaportStructs.sol";
+} from "seaport-sol/src/SeaportStructs.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
-import { OrderType } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
BasicOrder_additionalRecipients_data_cdPtr,
TwoWords
-} from "../../../contracts/lib/ConsiderationConstants.sol";
+} from "seaport-types/src/lib/ConsiderationConstants.sol";
import { ArithmeticUtil } from "./ArithmeticUtil.sol";
import { OrderBuilder } from "./OrderBuilder.sol";
-import { AmountDeriver } from "../../../contracts/lib/AmountDeriver.sol";
+import { AmountDeriver } from "seaport-core/src/lib/AmountDeriver.sol";
/// @dev base test class for cases that depend on pre-deployed token contracts
contract BaseOrderTest is OrderBuilder, AmountDeriver {
@@ -38,14 +38,6 @@ contract BaseOrderTest is OrderBuilder, AmountDeriver {
using ArithmeticUtil for uint128;
using ArithmeticUtil for uint120;
- /**
- * @dev used to store address and key outputs from makeAddrAndKey(name)
- */
- struct Account {
- address addr;
- uint256 key;
- }
-
FulfillmentComponent firstOrderFirstItem;
FulfillmentComponent firstOrderSecondItem;
FulfillmentComponent secondOrderFirstItem;
@@ -90,14 +82,6 @@ contract BaseOrderTest is OrderBuilder, AmountDeriver {
_;
}
- /**
- * @dev convenience wrapper for makeAddrAndKey
- */
- function makeAccount(string memory name) internal returns (Account memory) {
- (address addr, uint256 key) = makeAddrAndKey(name);
- return Account(addr, key);
- }
-
/**
* @dev convenience wrapper for makeAddrAndKey that also allocates tokens,
* ether, and approvals
diff --git a/test/foundry/utils/ConsiderationErrorsWrapper.sol b/test/foundry/utils/ConsiderationErrorsWrapper.sol
index 44939840d..31a4ac04b 100644
--- a/test/foundry/utils/ConsiderationErrorsWrapper.sol
+++ b/test/foundry/utils/ConsiderationErrorsWrapper.sol
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;
-import { Side } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { Side } from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
_revertBadFraction,
@@ -18,21 +18,17 @@ import {
_revertInvalidNativeOfferItem,
_revertInvalidProof,
_revertInvalidTime,
- _revertMismatchedFulfillmentOfferAndConsiderationComponents,
_revertMissingFulfillmentComponentOnAggregation,
_revertMissingOriginalConsiderationItems,
_revertNoReentrantCalls,
_revertNoSpecifiedOrdersAvailable,
- _revertOfferAndConsiderationRequiredOnFulfillment,
_revertOrderAlreadyFilled,
_revertOrderCriteriaResolverOutOfRange,
_revertOrderIsCancelled,
_revertOrderPartiallyFilled,
_revertPartialFillsNotEnabledForOrder,
- _revertUnresolvedConsiderationCriteria,
- _revertUnresolvedOfferCriteria,
_revertUnusedItemParameters
-} from "../../../contracts/lib/ConsiderationErrors.sol";
+} from "seaport-types/src/lib/ConsiderationErrors.sol";
contract ConsiderationErrorsWrapper {
/**
@@ -175,21 +171,6 @@ contract ConsiderationErrorsWrapper {
_revertInvalidTime(startTime, endTime);
}
- /**
- * @dev Reverts execution with a
- * "MismatchedFulfillmentOfferAndConsiderationComponents" error message.
- *
- * @param fulfillmentIndex The index of the fulfillment that caused the
- * error.
- */
- function __revertMismatchedFulfillmentOfferAndConsiderationComponents(
- uint256 fulfillmentIndex
- ) external pure {
- _revertMismatchedFulfillmentOfferAndConsiderationComponents(
- fulfillmentIndex
- );
- }
-
/**
* @dev Reverts execution with a "MissingFulfillmentComponentOnAggregation"
* error message.
@@ -226,17 +207,6 @@ contract ConsiderationErrorsWrapper {
_revertNoSpecifiedOrdersAvailable();
}
- /**
- * @dev Reverts execution with a "OfferAndConsiderationRequiredOnFulfillment"
- * error message.
- */
- function __revertOfferAndConsiderationRequiredOnFulfillment()
- external
- pure
- {
- _revertOfferAndConsiderationRequiredOnFulfillment();
- }
-
/**
* @dev Reverts execution with an "OrderAlreadyFilled" error message.
*
@@ -284,27 +254,6 @@ contract ConsiderationErrorsWrapper {
_revertPartialFillsNotEnabledForOrder();
}
- /**
- * @dev Reverts execution with an "UnresolvedConsiderationCriteria" error
- * message.
- */
- function __revertUnresolvedConsiderationCriteria(
- uint256 orderIndex,
- uint256 considerationIndex
- ) external pure {
- _revertUnresolvedConsiderationCriteria(orderIndex, considerationIndex);
- }
-
- /**
- * @dev Reverts execution with an "UnresolvedOfferCriteria" error message.
- */
- function __revertUnresolvedOfferCriteria(
- uint256 orderIndex,
- uint256 offerIndex
- ) external pure {
- _revertUnresolvedOfferCriteria(orderIndex, offerIndex);
- }
-
/**
* @dev Reverts execution with an "UnusedItemParameters" error message.
*/
diff --git a/test/foundry/utils/EIP712MerkleTree.sol b/test/foundry/utils/EIP712MerkleTree.sol
index 0c1c98bce..86f2181d8 100644
--- a/test/foundry/utils/EIP712MerkleTree.sol
+++ b/test/foundry/utils/EIP712MerkleTree.sol
@@ -11,13 +11,13 @@ import { Test } from "forge-std/Test.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
OrderComponents
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { Math } from "openzeppelin-contracts/contracts/utils/math/Math.sol";
+import { Math } from "@openzeppelin/contracts/utils/math/Math.sol";
/**
* @dev Seaport doesn't sort leaves when hashing for bulk orders, but Murky
diff --git a/test/foundry/utils/OfferConsiderationItemAdder.sol b/test/foundry/utils/OfferConsiderationItemAdder.sol
index b0f0860ab..2b63d57eb 100644
--- a/test/foundry/utils/OfferConsiderationItemAdder.sol
+++ b/test/foundry/utils/OfferConsiderationItemAdder.sol
@@ -6,7 +6,7 @@ import {
OfferItem,
ItemType,
SpentItem
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import { TestTokenMinter } from "./TestTokenMinter.sol";
diff --git a/test/foundry/utils/OrderBuilder.sol b/test/foundry/utils/OrderBuilder.sol
index 878399fc1..af77a0171 100644
--- a/test/foundry/utils/OrderBuilder.sol
+++ b/test/foundry/utils/OrderBuilder.sol
@@ -15,16 +15,16 @@ import {
Fulfillment,
FulfillmentComponent,
AdvancedOrder
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
OrderType,
BasicOrderType
-} from "../../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
contract OrderBuilder is OfferConsiderationItemAdder {
uint256 internal globalSalt;
diff --git a/test/foundry/utils/StructCopier.sol b/test/foundry/utils/StructCopier.sol
index ec41a14d4..7a71e1ab2 100644
--- a/test/foundry/utils/StructCopier.sol
+++ b/test/foundry/utils/StructCopier.sol
@@ -13,7 +13,7 @@ import {
FulfillmentComponent,
OrderParameters,
OrderComponents
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
contract StructCopier {
Order _tempOrder;
diff --git a/test/foundry/utils/TestTokenMinter.sol b/test/foundry/utils/TestTokenMinter.sol
index d904e01a5..d75ac461f 100644
--- a/test/foundry/utils/TestTokenMinter.sol
+++ b/test/foundry/utils/TestTokenMinter.sol
@@ -1,4 +1,4 @@
-// SPDX-Identifier: MIT
+// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;
import { TestERC1155 } from "../../../contracts/test/TestERC1155.sol";
@@ -6,7 +6,7 @@ import { TestERC20 } from "../../../contracts/test/TestERC20.sol";
import { TestERC721 } from "../../../contracts/test/TestERC721.sol";
import { ERC721Recipient } from "./ERC721Recipient.sol";
import { ERC1155Recipient } from "./ERC1155Recipient.sol";
-import { ItemType } from "../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
import { BaseConsiderationTest } from "./BaseConsiderationTest.sol";
import { CustomERC721 } from "../token/CustomERC721.sol";
diff --git a/test/foundry/utils/reentrancy/ReentrantStructs.sol b/test/foundry/utils/reentrancy/ReentrantStructs.sol
index ee3e3b89e..2f903e05d 100644
--- a/test/foundry/utils/reentrancy/ReentrantStructs.sol
+++ b/test/foundry/utils/reentrancy/ReentrantStructs.sol
@@ -1,5 +1,6 @@
//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.17;
+
import {
BasicOrderParameters,
OrderComponents,
@@ -8,7 +9,7 @@ import {
Order,
AdvancedOrder,
CriteriaResolver
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
struct FulfillBasicOrderParameters {
BasicOrderParameters parameters;
diff --git a/test/foundry/zone/PostFulfillmentCheck.t.sol b/test/foundry/zone/PreAndPostFulfillmentCheck.t.sol
similarity index 96%
rename from test/foundry/zone/PostFulfillmentCheck.t.sol
rename to test/foundry/zone/PreAndPostFulfillmentCheck.t.sol
index e012cdfe1..a47583e53 100644
--- a/test/foundry/zone/PostFulfillmentCheck.t.sol
+++ b/test/foundry/zone/PreAndPostFulfillmentCheck.t.sol
@@ -3,15 +3,11 @@ pragma solidity ^0.8.17;
import { BaseOrderTest } from "../utils/BaseOrderTest.sol";
-import { TestZone } from "./impl/TestZone.sol";
-
import {
TestTransferValidationZoneOfferer
-} from "../../../contracts/test/TestTransferValidationZoneOfferer.sol";
+} from "seaport/test/TestTransferValidationZoneOfferer.sol";
-import {
- PostFulfillmentStatefulTestZone
-} from "./impl/PostFullfillmentStatefulTestZone.sol";
+import { StatefulTestZone } from "./impl/StatefulTestZone.sol";
import {
AdditionalRecipient,
@@ -22,32 +18,26 @@ import {
FulfillmentComponent,
ItemType,
OfferItem
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
import {
BasicOrderType,
OrderType,
Side
-} from "../../../contracts/lib/ConsiderationEnums.sol";
+} from "seaport-types/src/lib/ConsiderationEnums.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
-contract PostFulfillmentCheckTest is BaseOrderTest {
- TestZone zone = new TestZone();
- PostFulfillmentStatefulTestZone statefulZone =
- new PostFulfillmentStatefulTestZone(50);
+contract PreAndPostFulfillmentCheckTest is BaseOrderTest {
+ StatefulTestZone statefulZone = new StatefulTestZone(50);
struct Context {
ConsiderationInterface consideration;
uint8 numOriginalAdditional;
uint8 numTips;
}
- struct EthConsideration {
- address payable recipient;
- uint256 amount;
- }
function test(
function(Context memory) external fn,
@@ -68,7 +58,7 @@ contract PostFulfillmentCheckTest is BaseOrderTest {
address(this),
true
);
- vm.label(address(zone), "TestZone");
+ vm.label(address(statefulZone), "TestZone");
}
function testAscendingAmount() public {
@@ -275,7 +265,8 @@ contract PostFulfillmentCheckTest is BaseOrderTest {
recipient: address(0)
});
- assertTrue(statefulZone.called());
+ assertTrue(statefulZone.authorizeCalled());
+ assertTrue(statefulZone.validateCalled());
}
function testBasicStateful() public {
@@ -453,7 +444,7 @@ contract PostFulfillmentCheckTest is BaseOrderTest {
);
// make new stateful zone with a larger amount so each additional
// recipient can receive
- statefulZone = new PostFulfillmentStatefulTestZone(5000);
+ statefulZone = new StatefulTestZone(5000);
// clear storage array just in case
delete additionalRecipients;
@@ -536,7 +527,8 @@ contract PostFulfillmentCheckTest is BaseOrderTest {
});
// assertions
- assertTrue(statefulZone.called());
+ assertTrue(statefulZone.authorizeCalled());
+ assertTrue(statefulZone.validateCalled());
for (uint256 i = 0; i < allAdditional.length; i++) {
assertEq(
token1.balanceOf(allAdditional[i]),
@@ -625,7 +617,8 @@ contract PostFulfillmentCheckTest is BaseOrderTest {
recipient: address(0),
maximumFulfilled: 1
});
- assertTrue(statefulZone.called());
+ assertTrue(statefulZone.authorizeCalled());
+ assertTrue(statefulZone.validateCalled());
}
function testExecMatchAdvancedOrdersWithConduit() public {
diff --git a/test/foundry/zone/TestTransferValidationZoneFuzz.t.sol b/test/foundry/zone/TestTransferValidationZoneFuzz.t.sol
index d52eea43c..5dbdfd4ef 100644
--- a/test/foundry/zone/TestTransferValidationZoneFuzz.t.sol
+++ b/test/foundry/zone/TestTransferValidationZoneFuzz.t.sol
@@ -14,13 +14,13 @@ import {
Order,
OrderComponents,
OrderType
-} from "../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { UnavailableReason } from "seaport-sol/SpaceEnums.sol";
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
import {
ConsiderationInterface
-} from "../../../contracts/interfaces/ConsiderationInterface.sol";
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
import {
ConsiderationItemLib,
@@ -30,7 +30,7 @@ import {
OrderComponentsLib,
OrderLib,
SeaportArrays
-} from "../../../contracts/helpers/sol/lib/SeaportStructLib.sol";
+} from "seaport-sol/src/lib/SeaportStructLib.sol";
import {
TestTransferValidationZoneOfferer
@@ -38,11 +38,11 @@ import {
import {
FulfillAvailableHelper
-} from "seaport-sol/fulfillments/available/FulfillAvailableHelper.sol";
+} from "seaport-sol/src/fulfillments/available/FulfillAvailableHelper.sol";
import {
MatchFulfillmentHelper
-} from "seaport-sol/fulfillments/match/MatchFulfillmentHelper.sol";
+} from "seaport-sol/src/fulfillments/match/MatchFulfillmentHelper.sol";
import { TestZone } from "./impl/TestZone.sol";
@@ -95,18 +95,18 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
.saveDefault(SINGLE_721);
OrderComponentsLib
- .empty()
- .withOfferer(offerer1.addr)
- .withZone(address(zone))
- // fill in offer later
- // fill in consideration later
- .withOrderType(OrderType.FULL_RESTRICTED)
- .withStartTime(block.timestamp)
- .withEndTime(block.timestamp + 1)
- .withZoneHash(bytes32(0)) // not strictly necessary
+ .empty()
+ .withOfferer(offerer1.addr)
+ .withZone(address(zone))
+ .withOrderType(OrderType.FULL_RESTRICTED)
+ .withStartTime(block.timestamp)
+ .withEndTime(block.timestamp + 1)
+ .withZoneHash(bytes32(0))
.withSalt(0)
.withConduitKey(conduitKeyOne)
- .saveDefault(VALIDATION_ZONE);
+ .saveDefault(VALIDATION_ZONE); // not strictly necessary
+ // fill in offer later
+ // fill in consideration later
// fill in counter later
}
@@ -347,9 +347,9 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
// Set up event expectations.
if (
+ fuzzPrimeOfferer.addr != fuzzMirrorOfferer.addr
// If the fuzzPrimeOfferer and fuzzMirrorOfferer are the same
// address, then the ERC20 transfers will be filtered.
- fuzzPrimeOfferer.addr != fuzzMirrorOfferer.addr
) {
if (
// When shouldIncludeNativeConsideration is false, there will be
@@ -368,10 +368,12 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
}
if (
- // When considerationItemsPerPrimeOrderCount is 3, there will be
- // exactly one token2 consideration item per orderPairCount.
- // And they'll all get aggregated into a single transfer.
- context.matchArgs.considerationItemsPerPrimeOrderCount >= 3
+ context
+ .matchArgs
+ // When considerationItemsPerPrimeOrderCount is 3, there will be
+ // exactly one token2 consideration item per orderPairCount.
+ // And they'll all get aggregated into a single transfer.
+ .considerationItemsPerPrimeOrderCount >= 3
) {
vm.expectEmit(true, true, false, true, address(token2));
emit Transfer(
@@ -465,7 +467,7 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
}
}
- function xtestFulfillAvailableAdvancedFuzz(
+ function testFulfillAvailableAdvancedFuzz(
FulfillFuzzInputs memory fulfillArgs
) public {
// Limit this value to avoid overflow issues.
@@ -627,6 +629,23 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
if (context.fulfillArgs.shouldUseTransferValidationZone) {
address strangerAddress = address(0xdeafbeef);
+ vm.expectRevert(
+ abi.encodeWithSignature(
+ "InvalidOwner(address,address,address,uint256)",
+ // The expected recipient is either the offer recipient or
+ // the caller, depending on the fuzz args.
+ context.fulfillArgs.shouldSpecifyRecipient
+ ? context.fulfillArgs.offerRecipient
+ : address(this),
+ // The stranger address gets passed into the recipient field
+ // below, so it will be the actual recipient.
+ strangerAddress,
+ address(test721_1),
+ // Should revert on the first call.
+ context.fulfillArgs.tokenId
+ )
+ );
+
// Make the call to Seaport.
context.seaport.fulfillAvailableAdvancedOrders{
value: context.fulfillArgs.excessNativeTokens +
@@ -644,7 +663,7 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
.considerationFulfillmentComponents,
fulfillerConduitKey: bytes32(conduitKey),
recipient: strangerAddress,
- maximumFulfilled: infra.advancedOrders.length
+ maximumFulfilled: context.fulfillArgs.maximumFulfilledCount
});
}
@@ -745,7 +764,8 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
// Check that the zone was called the expected number of times.
if (context.fulfillArgs.shouldUseTransferValidationZone) {
assertTrue(
- zone.callCount() == context.fulfillArgs.maximumFulfilledCount
+ zone.callCount() == context.fulfillArgs.maximumFulfilledCount,
+ "Zone call count incorrect."
);
}
@@ -759,7 +779,8 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
test721_1.ownerOf(context.fulfillArgs.tokenId + i),
context.fulfillArgs.shouldSpecifyRecipient
? context.fulfillArgs.offerRecipient
- : address(this)
+ : address(this),
+ "NFT owner incorrect."
);
}
@@ -773,7 +794,11 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
// Edge case: If the fuzz args pick this address for the
// consideration recipient, then the caller's balance should not
// change.
- assertEq(infra.callerBalanceAfter, infra.callerBalanceBefore);
+ assertEq(
+ infra.callerBalanceAfter,
+ infra.callerBalanceBefore,
+ "Caller balance incorrect (this contract)."
+ );
} else {
// Check that the consideration recipient's native balance was
// increased by the amount * the number of NFTs for sale.
@@ -781,7 +806,8 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
infra.considerationRecipientNativeBalanceAfter,
infra.considerationRecipientNativeBalanceBefore +
context.fulfillArgs.amount *
- context.fulfillArgs.maximumFulfilledCount
+ context.fulfillArgs.maximumFulfilledCount,
+ "Consideration recipient native balance incorrect."
);
// The consideration (amount * maximumFulfilledCount) should be
// spent, and the excessNativeTokens should be returned.
@@ -789,7 +815,8 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
infra.callerBalanceAfter +
context.fulfillArgs.amount *
context.fulfillArgs.maximumFulfilledCount,
- infra.callerBalanceBefore
+ infra.callerBalanceBefore,
+ "Caller balance incorrect."
);
}
} else {
@@ -803,14 +830,16 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
// change.
assertEq(
infra.considerationRecipientToken1BalanceAfter,
- infra.considerationRecipientToken1BalanceBefore
+ infra.considerationRecipientToken1BalanceBefore,
+ "Consideration recipient token1 balance incorrect (this)."
);
} else {
assertEq(
infra.considerationRecipientToken1BalanceAfter,
infra.considerationRecipientToken1BalanceBefore +
context.fulfillArgs.amount *
- context.fulfillArgs.maximumFulfilledCount
+ context.fulfillArgs.maximumFulfilledCount,
+ "Consideration recipient token1 balance incorrect."
);
}
@@ -824,14 +853,16 @@ contract TestTransferValidationZoneOffererTest is BaseOrderTest {
// not change.
assertEq(
infra.considerationRecipientToken2BalanceAfter,
- infra.considerationRecipientToken2BalanceBefore
+ infra.considerationRecipientToken2BalanceBefore,
+ "Consideration recipient token2 balance incorrect (this)."
);
} else {
assertEq(
infra.considerationRecipientToken2BalanceAfter,
infra.considerationRecipientToken2BalanceBefore +
context.fulfillArgs.amount *
- context.fulfillArgs.maximumFulfilledCount
+ context.fulfillArgs.maximumFulfilledCount,
+ "Consideration recipient token2 balance incorrect."
);
}
}
diff --git a/test/foundry/zone/TestZoneCalldataFidelity.t.sol b/test/foundry/zone/TestZoneCalldataFidelity.t.sol
new file mode 100644
index 000000000..29a2446b5
--- /dev/null
+++ b/test/foundry/zone/TestZoneCalldataFidelity.t.sol
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ ConsiderationItemLib,
+ OfferItemLib,
+ OrderParametersLib
+} from "seaport-sol/src/SeaportSol.sol";
+
+import { BaseOrderTest } from "../utils/BaseOrderTest.sol";
+
+import { HashCalldataTestZone } from "./impl/HashCalldataTestZone.sol";
+
+import {
+ AdvancedOrder,
+ ConsiderationItem,
+ CriteriaResolver,
+ ItemType,
+ OfferItem,
+ OrderParameters,
+ ZoneParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+contract PreAndPostFulfillmentCheckTest is BaseOrderTest {
+ using ConsiderationItemLib for ConsiderationItem[];
+ using OfferItemLib for OfferItem[];
+ using OrderParametersLib for OrderParameters;
+
+ HashCalldataTestZone testZone = new HashCalldataTestZone();
+
+ struct Context {
+ ConsiderationInterface consideration;
+ TestCase testCase;
+ }
+
+ struct TestCase {
+ uint256 itemType;
+ uint256 offerItemStartingIdentifier;
+ uint256 considerationItemStartingIdentifier;
+ uint256 startAmount;
+ uint256 endAmount;
+ bytes signature;
+ bytes extraData;
+ uint256 recipient;
+ uint256 offerLength;
+ uint256 considerationLength;
+ uint256 orderType;
+ uint256 startTime;
+ uint256 endTime;
+ uint256 zoneHash;
+ uint256 salt;
+ }
+
+ function test(
+ function(Context memory) external fn,
+ Context memory context
+ ) internal {
+ try fn(context) {
+ fail();
+ } catch (bytes memory reason) {
+ assertPass(reason);
+ }
+ }
+
+ function setUp() public override {
+ super.setUp();
+ conduitController.updateChannel(address(conduit), address(this), true);
+ referenceConduitController.updateChannel(
+ address(referenceConduit),
+ address(this),
+ true
+ );
+ vm.label(address(testZone), "TestZone");
+ }
+
+ function testCalldataEquivalence(TestCase memory testCase) public {
+ test(
+ this.execCalldataEquivalence,
+ Context({ consideration: consideration, testCase: testCase })
+ );
+ test(
+ this.execCalldataEquivalence,
+ Context({
+ consideration: referenceConsideration,
+ testCase: testCase
+ })
+ );
+ }
+
+ function execCalldataEquivalence(Context memory context) public stateless {
+ // Bound the test case.
+ TestCase memory testCase = _boundTestCase(context.testCase);
+
+ // Mint the necessary tokens.
+ _mintNecessaryTokens(testCase);
+
+ // Create the params for the advanced order.
+ OrderParameters memory orderParameters = OrderParameters({
+ offerer: address(this),
+ zone: address(testZone),
+ offer: new OfferItem[](testCase.offerLength),
+ consideration: new ConsiderationItem[](
+ testCase.considerationLength
+ ),
+ orderType: OrderType(testCase.orderType),
+ startTime: testCase.startTime,
+ endTime: testCase.endTime,
+ zoneHash: bytes32(testCase.zoneHash),
+ salt: testCase.salt,
+ conduitKey: bytes32(0),
+ totalOriginalConsiderationItems: testCase.considerationLength
+ });
+
+ // Populate the offer and consideration.
+ for (uint256 i = 0; i < testCase.offerLength; i++) {
+ orderParameters.offer[i] = OfferItem({
+ itemType: ItemType(testCase.itemType),
+ token: address(test721_1),
+ identifierOrCriteria: testCase.offerItemStartingIdentifier + i,
+ startAmount: testCase.startAmount,
+ endAmount: testCase.endAmount
+ });
+ }
+
+ for (uint256 i = 0; i < testCase.considerationLength; i++) {
+ orderParameters.consideration[i] = ConsiderationItem({
+ itemType: ItemType(testCase.itemType),
+ token: address(test721_1),
+ identifierOrCriteria: testCase
+ .considerationItemStartingIdentifier + i,
+ startAmount: testCase.startAmount,
+ endAmount: testCase.endAmount,
+ recipient: payable(address(uint160(testCase.recipient)))
+ });
+ }
+
+ // Create the advanced order.
+ AdvancedOrder memory advancedOrder = AdvancedOrder({
+ parameters: orderParameters,
+ numerator: 1,
+ denominator: 1,
+ signature: new bytes(0),
+ extraData: abi.encodePacked(bytes32(testCase.extraData))
+ });
+
+ // Generate the order hash.
+ bytes32 orderHash = context.consideration.getOrderHash(
+ advancedOrder.parameters.toOrderComponents(0)
+ );
+
+ // Create the expected zone parameters.
+ ZoneParameters memory zoneParameters = ZoneParameters({
+ orderHash: orderHash,
+ fulfiller: address(this),
+ offerer: address(this),
+ offer: orderParameters.offer.toSpentItemArray(),
+ consideration: orderParameters.consideration.toReceivedItemArray(),
+ extraData: abi.encodePacked(bytes32(testCase.extraData)),
+ orderHashes: new bytes32[](0),
+ startTime: testCase.startTime,
+ endTime: testCase.endTime,
+ zoneHash: bytes32(testCase.zoneHash)
+ });
+
+ // Hash the zone parameters.
+ bytes32 expectedZoneHash = bytes32(
+ keccak256(abi.encode(zoneParameters))
+ );
+
+ // Send the expectation for authorize to the test zone.
+ testZone.setExpectedAuthorizeCalldataHash(expectedZoneHash);
+
+ // Add the order hash to the zone parameters.
+ zoneParameters.orderHashes = new bytes32[](1);
+ zoneParameters.orderHashes[0] = orderHash;
+
+ // Hash the updated zone parameters.
+ expectedZoneHash = bytes32(keccak256(abi.encode(zoneParameters)));
+
+ // Send the expectation for validate to the test zone.
+ testZone.setExpectedValidateCalldataHash(expectedZoneHash);
+
+ // Fulfill the advanced order.
+ context.consideration.fulfillAdvancedOrder({
+ advancedOrder: advancedOrder,
+ criteriaResolvers: new CriteriaResolver[](0),
+ fulfillerConduitKey: bytes32(0),
+ recipient: payable(address(uint160(testCase.recipient)))
+ });
+ }
+
+ function _boundTestCase(
+ TestCase memory _testCase
+ ) internal view returns (TestCase memory) {
+ TestCase memory testCase = _testCase;
+
+ testCase.itemType = bound(testCase.itemType, 2, 2);
+ testCase.offerItemStartingIdentifier = bound(
+ testCase.offerItemStartingIdentifier,
+ 1,
+ type(uint16).max
+ );
+ testCase.considerationItemStartingIdentifier = bound(
+ testCase.considerationItemStartingIdentifier,
+ type(uint32).max,
+ type(uint64).max
+ );
+ testCase.startAmount = bound(testCase.startAmount, 1, 1);
+ testCase.endAmount = bound(
+ testCase.endAmount,
+ 1,
+ testCase.itemType == 2 ? 1 : 1000
+ );
+ testCase.recipient = bound(testCase.recipient, 10, type(uint160).max);
+ testCase.offerLength = bound(testCase.offerLength, 1, 30);
+ testCase.considerationLength = bound(
+ testCase.considerationLength,
+ 1,
+ 30
+ );
+ testCase.orderType = bound(testCase.orderType, 1, 3); // 0, 4);
+ testCase.startTime = bound(testCase.startTime, 0, 1);
+ testCase.endTime = bound(
+ testCase.endTime,
+ block.timestamp + 1,
+ type(uint256).max
+ );
+
+ return testCase;
+ }
+
+ function _mintNecessaryTokens(TestCase memory testCase) internal {
+ for (uint256 i = 0; i < testCase.offerLength; i++) {
+ test721_1.mint(
+ address(this),
+ testCase.offerItemStartingIdentifier + i
+ );
+ test1155_1.mint(
+ address(this),
+ testCase.offerItemStartingIdentifier + i,
+ testCase.endAmount
+ );
+ }
+ for (uint256 i = 0; i < testCase.considerationLength; i++) {
+ test721_1.mint(
+ address(this),
+ testCase.considerationItemStartingIdentifier + i
+ );
+ test1155_1.mint(
+ address(this),
+ testCase.considerationItemStartingIdentifier + i,
+ testCase.endAmount
+ );
+ }
+ }
+}
diff --git a/test/foundry/zone/UnauthorizedOrderSkip.t.sol b/test/foundry/zone/UnauthorizedOrderSkip.t.sol
new file mode 100644
index 000000000..85d2e23f7
--- /dev/null
+++ b/test/foundry/zone/UnauthorizedOrderSkip.t.sol
@@ -0,0 +1,1665 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ ConsiderationItemLib,
+ FulfillmentLib,
+ OfferItemLib,
+ OrderComponentsLib,
+ OrderLib,
+ OrderParametersLib,
+ SeaportArrays
+} from "seaport-sol/src/lib/SeaportStructLib.sol";
+
+import { UnavailableReason } from "seaport-sol/src/SpaceEnums.sol";
+
+import { BaseOrderTest } from "../utils/BaseOrderTest.sol";
+
+import {
+ AdvancedOrder,
+ ConsiderationItem,
+ CriteriaResolver,
+ Fulfillment,
+ FulfillmentComponent,
+ ItemType,
+ OfferItem,
+ Order,
+ OrderComponents,
+ OrderParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { OrderType } from "seaport-types/src/lib/ConsiderationEnums.sol";
+
+import {
+ ConsiderationInterface
+} from "seaport-types/src/interfaces/ConsiderationInterface.sol";
+
+import {
+ FulfillAvailableHelper
+} from "seaport-sol/src/fulfillments/available/FulfillAvailableHelper.sol";
+
+import {
+ MatchFulfillmentHelper
+} from "seaport-sol/src/fulfillments/match/MatchFulfillmentHelper.sol";
+
+import { VerboseAuthZone } from "./impl/VerboseAuthZone.sol";
+
+contract UnauthorizedOrderSkipTest is BaseOrderTest {
+ using OfferItemLib for OfferItem;
+ using ConsiderationItemLib for ConsiderationItem;
+ using OrderComponentsLib for OrderComponents;
+ using OrderParametersLib for OrderParameters;
+ using OrderLib for Order;
+
+ MatchFulfillmentHelper matchFulfillmentHelper;
+ FulfillAvailableHelper fulfillAvailableFulfillmentHelper;
+
+ struct Context {
+ ConsiderationInterface seaport;
+ bool isReference;
+ FulfillFuzzInputs fulfillArgs;
+ MatchFuzzInputs matchArgs;
+ }
+
+ struct FulfillFuzzInputs {
+ uint256 tokenId;
+ uint128 amount;
+ uint128 excessNativeTokens;
+ uint256 orderCount;
+ uint256 considerationItemsPerOrderCount;
+ uint256 maximumFulfilledCount;
+ address offerRecipient;
+ address considerationRecipient;
+ bytes32 zoneHash;
+ uint256 salt;
+ bool shouldReturnInvalidMagicValue;
+ bool shouldRevert;
+ bool shouldAggregateFulfillmentComponents;
+ bool shouldUseConduit;
+ bool shouldIncludeNativeConsideration;
+ bool shouldIncludeExcessOfferItems;
+ bool shouldSpecifyRecipient;
+ bool shouldIncludeJunkDataInAdvancedOrder;
+ }
+
+ struct MatchFuzzInputs {
+ uint256 tokenId;
+ uint128 amount;
+ uint128 excessNativeTokens;
+ uint256 orderPairCount;
+ uint256 considerationItemsPerPrimeOrderCount;
+ // This is currently used only as the unspent prime offer item recipient
+ // but would also set the recipient for unspent mirror offer items if
+ // any were added in the test in the future.
+ address unspentPrimeOfferItemRecipient;
+ string primeOfferer;
+ string mirrorOfferer;
+ bytes32 zoneHash;
+ uint256 salt;
+ bool shouldReturnInvalidMagicValue;
+ bool shouldRevert;
+ bool shouldUseConduit;
+ bool shouldIncludeNativeConsideration;
+ bool shouldIncludeExcessOfferItems;
+ bool shouldSpecifyUnspentOfferItemRecipient;
+ bool shouldIncludeJunkDataInAdvancedOrder;
+ }
+
+ // Used for stack depth management.
+ struct MatchAdvancedOrdersInfra {
+ Order[] orders;
+ Fulfillment[] fulfillments;
+ AdvancedOrder[] advancedOrders;
+ CriteriaResolver[] criteriaResolvers;
+ uint256 callerBalanceBefore;
+ uint256 callerBalanceAfter;
+ uint256 primeOffererBalanceBefore;
+ uint256 primeOffererBalanceAfter;
+ }
+
+ // Used for stack depth management.
+ struct FulfillAvailableAdvancedOrdersInfra {
+ AdvancedOrder[] advancedOrders;
+ FulfillmentComponent[][] offerFulfillmentComponents;
+ FulfillmentComponent[][] considerationFulfillmentComponents;
+ CriteriaResolver[] criteriaResolvers;
+ uint256 callerBalanceBefore;
+ uint256 callerBalanceAfter;
+ uint256 considerationRecipientNativeBalanceBefore;
+ uint256 considerationRecipientToken1BalanceBefore;
+ uint256 considerationRecipientToken2BalanceBefore;
+ uint256 considerationRecipientNativeBalanceAfter;
+ uint256 considerationRecipientToken1BalanceAfter;
+ uint256 considerationRecipientToken2BalanceAfter;
+ }
+
+ // Used for stack depth management.
+ struct OrderAndFulfillmentInfra {
+ OfferItem[] offerItemArray;
+ ConsiderationItem[] considerationItemArray;
+ OrderComponents orderComponents;
+ Order[] orders;
+ Fulfillment fulfillment;
+ Fulfillment[] fulfillments;
+ }
+
+ // Used for stack depth management.
+ struct OrderComponentInfra {
+ OrderComponents orderComponents;
+ OrderComponents[] orderComponentsArray;
+ OfferItem[][] offerItemArray;
+ ConsiderationItem[][] considerationItemArray;
+ ConsiderationItem nativeConsiderationItem;
+ ConsiderationItem erc20ConsiderationItemOne;
+ ConsiderationItem erc20ConsiderationItemTwo;
+ }
+
+ event Authorized(bytes32 orderHash);
+ event AuthorizeOrderReverted(bytes32 orderHash);
+ event AuthorizeOrderNonMagicValue(bytes32 orderHash);
+
+ FulfillFuzzInputs emptyFulfill;
+ MatchFuzzInputs emptyMatch;
+
+ Account fuzzPrimeOfferer;
+ Account fuzzMirrorOfferer;
+
+ string constant SINGLE_721 = "single 721";
+ string constant STD_RESTRICTED = "validation zone";
+
+ function test(
+ function(Context memory) external fn,
+ Context memory context
+ ) internal {
+ try fn(context) {
+ fail();
+ } catch (bytes memory reason) {
+ assertPass(reason);
+ }
+ }
+
+ function setUp() public override {
+ super.setUp();
+ matchFulfillmentHelper = new MatchFulfillmentHelper();
+ fulfillAvailableFulfillmentHelper = new FulfillAvailableHelper();
+ // Can this be removed?
+ conduitController.updateChannel(address(conduit), address(this), true);
+ referenceConduitController.updateChannel(
+ address(referenceConduit),
+ address(this),
+ true
+ );
+
+ // create a default consideration for a single 721;
+ // note that it does not have recipient, token or
+ // identifier set
+ ConsiderationItemLib
+ .empty()
+ .withItemType(ItemType.ERC721)
+ .withStartAmount(1)
+ .withEndAmount(1)
+ .saveDefault(SINGLE_721);
+
+ // create a default offerItem for a single 721;
+ // note that it does not have token or identifier set
+ OfferItemLib
+ .empty()
+ .withItemType(ItemType.ERC721)
+ .withStartAmount(1)
+ .withEndAmount(1)
+ .saveDefault(SINGLE_721);
+
+ OrderComponentsLib
+ .empty()
+ .withOfferer(offerer1.addr)
+ .withOrderType(OrderType.FULL_RESTRICTED)
+ .withStartTime(block.timestamp)
+ .withEndTime(block.timestamp + 1)
+ .withZoneHash(bytes32(0))
+ .withSalt(0)
+ .withConduitKey(conduitKeyOne)
+ .saveDefault(STD_RESTRICTED);
+ }
+
+ function testMatchAuthRevertAndInvMagicValue(
+ MatchFuzzInputs memory _matchArgs
+ ) public {
+ _matchArgs = _boundMatchArgs(_matchArgs);
+
+ test(
+ this.execMatch,
+ Context({
+ seaport: consideration,
+ isReference: false,
+ matchArgs: _matchArgs,
+ fulfillArgs: emptyFulfill
+ })
+ );
+ test(
+ this.execMatch,
+ Context({
+ seaport: referenceConsideration,
+ isReference: true,
+ matchArgs: _matchArgs,
+ fulfillArgs: emptyFulfill
+ })
+ );
+ }
+
+ function execMatch(Context memory context) public stateless {
+ // Set up the zone.
+ VerboseAuthZone verboseZone = new VerboseAuthZone(
+ context.matchArgs.shouldReturnInvalidMagicValue,
+ context.matchArgs.shouldRevert
+ );
+
+ vm.label(address(verboseZone), "VerboseZone");
+
+ // Set up the infrastructure for this function in a struct to avoid
+ // stack depth issues.
+ MatchAdvancedOrdersInfra memory infra = MatchAdvancedOrdersInfra({
+ orders: new Order[](context.matchArgs.orderPairCount),
+ fulfillments: new Fulfillment[](context.matchArgs.orderPairCount),
+ advancedOrders: new AdvancedOrder[](
+ context.matchArgs.orderPairCount
+ ),
+ criteriaResolvers: new CriteriaResolver[](0),
+ callerBalanceBefore: 0,
+ callerBalanceAfter: 0,
+ primeOffererBalanceBefore: 0,
+ primeOffererBalanceAfter: 0
+ });
+
+ // The prime offerer is offering NFTs and considering ERC20/Native.
+ fuzzPrimeOfferer = makeAndAllocateAccount(
+ context.matchArgs.primeOfferer
+ );
+ // The mirror offerer is offering ERC20/Native and considering NFTs.
+ fuzzMirrorOfferer = makeAndAllocateAccount(
+ context.matchArgs.mirrorOfferer
+ );
+
+ // Create the orders and fulfuillments.
+ (
+ infra.orders,
+ infra.fulfillments
+ ) = _buildOrdersAndFulfillmentsMirrorOrdersFromFuzzArgs(
+ context,
+ address(verboseZone)
+ );
+
+ // Set up the advanced orders array.
+ infra.advancedOrders = new AdvancedOrder[](infra.orders.length);
+
+ // Convert the orders to advanced orders.
+ for (uint256 i = 0; i < infra.orders.length; i++) {
+ infra.advancedOrders[i] = infra.orders[i].toAdvancedOrder(
+ 1,
+ 1,
+ context.matchArgs.shouldIncludeJunkDataInAdvancedOrder
+ ? bytes(
+ abi.encodePacked(
+ context.matchArgs.salt,
+ context.matchArgs.salt
+ )
+ )
+ : bytes("")
+ );
+ }
+
+ // Store the native token balances before the call for later reference.
+ infra.callerBalanceBefore = address(this).balance;
+ infra.primeOffererBalanceBefore = address(fuzzPrimeOfferer.addr)
+ .balance;
+
+ // Set up expectations for the call.
+ uint256 offererCounter = context.seaport.getCounter(
+ infra.orders[0].parameters.offerer
+ );
+
+ // Set up the first orderHash.
+ bytes32 orderHash = context.seaport.getOrderHash(
+ infra.orders[0].parameters.toOrderComponents(offererCounter)
+ );
+
+ if (context.matchArgs.shouldReturnInvalidMagicValue) {
+ // Expect AuthorizeOrderNonMagicValue event.
+ vm.expectEmit(true, false, false, true, address(verboseZone));
+ emit AuthorizeOrderNonMagicValue(orderHash);
+ vm.expectRevert(
+ abi.encodeWithSignature(
+ "InvalidRestrictedOrder(bytes32)",
+ orderHash
+ )
+ );
+ } else if (context.matchArgs.shouldRevert) {
+ // Expect AuthorizeOrderReverted event.
+ vm.expectEmit(true, false, false, true, address(verboseZone));
+ emit AuthorizeOrderReverted(orderHash);
+ if (context.isReference) {
+ vm.expectRevert(
+ abi.encodeWithSignature(
+ "InvalidRestrictedOrder(bytes32)",
+ orderHash
+ )
+ );
+ } else {
+ vm.expectRevert(
+ abi.encodeWithSignature("OrderNotAuthorized()")
+ );
+ }
+ } else {
+ if (
+ !context.matchArgs.shouldRevert &&
+ !context.matchArgs.shouldReturnInvalidMagicValue
+ ) {
+ bytes32[] memory orderHashesToAuth = new bytes32[](
+ infra.orders.length
+ );
+
+ // Iterate over the orders and authorize them, then set up event expectations.
+ for (uint256 i = 0; i < infra.orders.length; i++) {
+ offererCounter = context.seaport.getCounter(
+ infra.orders[i].parameters.offerer
+ );
+
+ // Set up the orderHash.
+ orderHash = context.seaport.getOrderHash(
+ infra.orders[i].parameters.toOrderComponents(
+ offererCounter
+ )
+ );
+
+ orderHashesToAuth[i] = orderHash;
+
+ // Call `setAuthorizationStatus` on the verboseZone.
+ verboseZone.setAuthorizationStatus(orderHash, true);
+ }
+
+ // Iterate again and set up the expectations for the events.
+ // (Can't call `getOrderHash` between `vm.expectEmit` calls).
+ for (uint256 i = 0; i < orderHashesToAuth.length; i++) {
+ if (orderHashesToAuth[i] != bytes32(0)) {
+ // Expect Authorized event.
+ vm.expectEmit(
+ true,
+ false,
+ false,
+ true,
+ address(verboseZone)
+ );
+ emit Authorized(orderHashesToAuth[i]);
+ }
+ }
+ }
+
+ if (
+ // When shouldIncludeNativeConsideration is false, there will be
+ // exactly one token1 consideration item per orderPairCount. And
+ // they'll all get aggregated into a single transfer.
+ !context.matchArgs.shouldIncludeNativeConsideration
+ ) {
+ // This checks that the ERC20 transfers were all aggregated into
+ // a single transfer.
+ vm.expectEmit(true, true, false, true, address(token1));
+ emit Transfer(
+ address(fuzzMirrorOfferer.addr), // from
+ address(fuzzPrimeOfferer.addr), // to
+ context.matchArgs.amount * context.matchArgs.orderPairCount
+ );
+ }
+
+ if (
+ context
+ .matchArgs
+ // When considerationItemsPerPrimeOrderCount is 3, there will be
+ // exactly one token2 consideration item per orderPairCount.
+ // And they'll all get aggregated into a single transfer.
+ .considerationItemsPerPrimeOrderCount >= 3
+ ) {
+ vm.expectEmit(true, true, false, true, address(token2));
+ emit Transfer(
+ address(fuzzMirrorOfferer.addr), // from
+ address(fuzzPrimeOfferer.addr), // to
+ context.matchArgs.amount * context.matchArgs.orderPairCount
+ );
+ }
+ }
+
+ // Make the call to Seaport.
+ context.seaport.matchAdvancedOrders{
+ value: (context.matchArgs.amount *
+ context.matchArgs.orderPairCount) +
+ context.matchArgs.excessNativeTokens
+ }(
+ infra.advancedOrders,
+ infra.criteriaResolvers,
+ infra.fulfillments,
+ // If shouldSpecifyUnspentOfferItemRecipient is true, send the
+ // unspent offer items to the recipient specified by the fuzz args.
+ // Otherwise, pass in the zero address, which will result in the
+ // unspent offer items being sent to the caller.
+ context.matchArgs.shouldSpecifyUnspentOfferItemRecipient
+ ? address(context.matchArgs.unspentPrimeOfferItemRecipient)
+ : address(0)
+ );
+
+ // If the call should return an invalid magic value or revert, return
+ // early.
+ if (
+ context.matchArgs.shouldReturnInvalidMagicValue ||
+ context.matchArgs.shouldRevert
+ ) {
+ return;
+ }
+
+ // Note the native token balances after the call for later checks.
+ infra.callerBalanceAfter = address(this).balance;
+ infra.primeOffererBalanceAfter = address(fuzzPrimeOfferer.addr).balance;
+
+ // Check that the NFTs were transferred to the expected recipient.
+ for (uint256 i = 0; i < context.matchArgs.orderPairCount; i++) {
+ assertEq(
+ test721_1.ownerOf(context.matchArgs.tokenId + i),
+ fuzzMirrorOfferer.addr
+ );
+ }
+
+ if (context.matchArgs.shouldIncludeExcessOfferItems) {
+ // Check that the excess offer NFTs were transferred to the expected
+ // recipient.
+ for (uint256 i = 0; i < context.matchArgs.orderPairCount; i++) {
+ assertEq(
+ test721_1.ownerOf((context.matchArgs.tokenId + i) * 2),
+ context.matchArgs.shouldSpecifyUnspentOfferItemRecipient
+ ? context.matchArgs.unspentPrimeOfferItemRecipient
+ : address(this)
+ );
+ }
+ }
+
+ if (context.matchArgs.shouldIncludeNativeConsideration) {
+ // Check that ETH is moving from the caller to the prime offerer.
+ // This also checks that excess native tokens are being swept back
+ // to the caller.
+ assertEq(
+ infra.callerBalanceBefore -
+ context.matchArgs.amount *
+ context.matchArgs.orderPairCount,
+ infra.callerBalanceAfter
+ );
+ assertEq(
+ infra.primeOffererBalanceBefore +
+ context.matchArgs.amount *
+ context.matchArgs.orderPairCount,
+ infra.primeOffererBalanceAfter
+ );
+ } else {
+ assertEq(infra.callerBalanceBefore, infra.callerBalanceAfter);
+ }
+ }
+
+ function testFulfillAvailableAuthRevertAndInvMagicValue(
+ FulfillFuzzInputs memory fulfillArgs
+ ) public {
+ fulfillArgs = _boundFulfillArgs(fulfillArgs);
+
+ test(
+ this.execFulfillAvailable,
+ Context(consideration, false, fulfillArgs, emptyMatch)
+ );
+ test(
+ this.execFulfillAvailable,
+ Context(referenceConsideration, true, fulfillArgs, emptyMatch)
+ );
+ }
+
+ function execFulfillAvailable(Context memory context) external stateless {
+ // Set up the infrastructure.
+ FulfillAvailableAdvancedOrdersInfra
+ memory infra = FulfillAvailableAdvancedOrdersInfra({
+ advancedOrders: new AdvancedOrder[](
+ context.fulfillArgs.orderCount
+ ),
+ offerFulfillmentComponents: new FulfillmentComponent[][](
+ context.fulfillArgs.orderCount
+ ),
+ considerationFulfillmentComponents: new FulfillmentComponent[][](
+ context.fulfillArgs.orderCount
+ ),
+ criteriaResolvers: new CriteriaResolver[](0),
+ callerBalanceBefore: address(this).balance,
+ callerBalanceAfter: address(this).balance,
+ considerationRecipientNativeBalanceBefore: context
+ .fulfillArgs
+ .considerationRecipient
+ .balance,
+ considerationRecipientToken1BalanceBefore: token1.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ ),
+ considerationRecipientToken2BalanceBefore: token2.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ ),
+ considerationRecipientNativeBalanceAfter: context
+ .fulfillArgs
+ .considerationRecipient
+ .balance,
+ considerationRecipientToken1BalanceAfter: token1.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ ),
+ considerationRecipientToken2BalanceAfter: token2.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ )
+ });
+
+ // Use a conduit sometimes.
+ bytes32 conduitKey = context.fulfillArgs.shouldUseConduit
+ ? conduitKeyOne
+ : bytes32(0);
+
+ // Mint enough ERC721s to cover the number of NFTs for sale.
+ for (uint256 i; i < context.fulfillArgs.orderCount; i++) {
+ test721_1.mint(offerer1.addr, context.fulfillArgs.tokenId + i);
+ }
+
+ // Mint enough ERC20s to cover price per NFT * NFTs for sale.
+ token1.mint(
+ address(this),
+ context.fulfillArgs.amount * context.fulfillArgs.orderCount
+ );
+ token2.mint(
+ address(this),
+ context.fulfillArgs.amount * context.fulfillArgs.orderCount
+ );
+
+ // Set up the zone.
+ VerboseAuthZone verboseZone = new VerboseAuthZone(
+ context.fulfillArgs.shouldReturnInvalidMagicValue,
+ context.fulfillArgs.shouldRevert
+ );
+
+ vm.label(address(verboseZone), "VerboseZone");
+
+ // Create the orders.
+ infra.advancedOrders = _buildOrdersFromFuzzArgs(
+ context,
+ offerer1.key,
+ address(verboseZone)
+ );
+
+ // Create the fulfillments.
+ if (context.fulfillArgs.shouldAggregateFulfillmentComponents) {
+ (
+ infra.offerFulfillmentComponents,
+ infra.considerationFulfillmentComponents
+ ) = fulfillAvailableFulfillmentHelper
+ .getAggregatedFulfillmentComponents(infra.advancedOrders);
+ } else {
+ (
+ infra.offerFulfillmentComponents,
+ infra.considerationFulfillmentComponents
+ ) = fulfillAvailableFulfillmentHelper.getNaiveFulfillmentComponents(
+ infra.advancedOrders
+ );
+ }
+
+ // Store balances before the call for later comparison.
+ infra.callerBalanceBefore = address(this).balance;
+ infra.considerationRecipientNativeBalanceBefore = address(
+ context.fulfillArgs.considerationRecipient
+ ).balance;
+ infra.considerationRecipientToken1BalanceBefore = token1.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ );
+ infra.considerationRecipientToken2BalanceBefore = token2.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ );
+
+ bytes32[] memory orderHashesThatShouldRevertInAuth = new bytes32[](
+ infra.advancedOrders.length
+ );
+ uint256 skippedOrderCount;
+
+ // Set up expectations for the call.
+ if (context.fulfillArgs.shouldReturnInvalidMagicValue) {
+ uint256 offererCounter = context.seaport.getCounter(
+ infra.advancedOrders[0].parameters.offerer
+ );
+
+ // Set up the orderHash.
+ bytes32 orderHash = context.seaport.getOrderHash(
+ infra.advancedOrders[0].parameters.toOrderComponents(
+ offererCounter
+ )
+ );
+
+ // Expect AuthorizeOrderNonMagicValue event.
+ vm.expectEmit(true, false, false, true, address(verboseZone));
+ emit AuthorizeOrderNonMagicValue(orderHash);
+ vm.expectRevert(
+ abi.encodeWithSignature(
+ "InvalidRestrictedOrder(bytes32)",
+ orderHash
+ )
+ );
+ } else if (context.fulfillArgs.shouldRevert) {
+ bool gotOneKeeper;
+
+ // Iterate over the orders and expect AuthorizeOrderReverted events.
+ for (uint256 i = 0; i < infra.advancedOrders.length; i++) {
+ uint256 offererCounter = context.seaport.getCounter(
+ infra.advancedOrders[i].parameters.offerer
+ );
+
+ // Set up the orderHash.
+ bytes32 orderHash = context.seaport.getOrderHash(
+ infra.advancedOrders[i].parameters.toOrderComponents(
+ offererCounter
+ )
+ );
+
+ if ((uint256(orderHash) % 2) == 0 && gotOneKeeper) {
+ orderHashesThatShouldRevertInAuth[i] = orderHash;
+ skippedOrderCount++;
+ } else {
+ // Auth the order.
+ verboseZone.setAuthorizationStatus(orderHash, true);
+ gotOneKeeper = true;
+ }
+ }
+
+ for (
+ uint256 i = 0;
+ i < context.fulfillArgs.maximumFulfilledCount;
+ i++
+ ) {
+ if (orderHashesThatShouldRevertInAuth[i] != bytes32(0)) {
+ // Expect AuthorizeOrderReverted event.
+ vm.expectEmit(
+ true,
+ false,
+ false,
+ true,
+ address(verboseZone)
+ );
+ emit AuthorizeOrderReverted(
+ orderHashesThatShouldRevertInAuth[i]
+ );
+ }
+ }
+ } else {
+ // This is the happy path (no reverts or invalid magic values).
+ bytes32[] memory orderHashesToAuth = new bytes32[](
+ infra.advancedOrders.length
+ );
+
+ // Iterate over the orders and authorize them, then set up event
+ // expectations.
+ for (
+ uint256 i = 0;
+ i < context.fulfillArgs.maximumFulfilledCount;
+ i++
+ ) {
+ uint256 offererCounter = context.seaport.getCounter(
+ infra.advancedOrders[i].parameters.offerer
+ );
+
+ // Set up the orderHash.
+ bytes32 orderHash = context.seaport.getOrderHash(
+ infra.advancedOrders[i].parameters.toOrderComponents(
+ offererCounter
+ )
+ );
+
+ orderHashesToAuth[i] = orderHash;
+
+ // Auth the order.
+ verboseZone.setAuthorizationStatus(orderHash, true);
+ }
+
+ // Iterate again and set up the expectations for the events.
+ // (Can't call `getOrderHash` between `vm.expectEmit` calls).
+ for (uint256 i = 0; i < orderHashesToAuth.length; i++) {
+ if (orderHashesToAuth[i] != bytes32(0)) {
+ // Expect Authorized event.
+ vm.expectEmit(
+ true,
+ false,
+ false,
+ true,
+ address(verboseZone)
+ );
+ emit Authorized(orderHashesToAuth[i]);
+ }
+ }
+ }
+
+ // This is the happyish path.
+ if (!context.fulfillArgs.shouldReturnInvalidMagicValue) {
+ uint256 eligibleOrders = infra.advancedOrders.length -
+ skippedOrderCount;
+ uint256 expectedFulfilledOrderCount = eligibleOrders <
+ context.fulfillArgs.maximumFulfilledCount
+ ? eligibleOrders
+ : context.fulfillArgs.maximumFulfilledCount;
+
+ if (
+ !context.fulfillArgs.shouldIncludeNativeConsideration &&
+ // If the fuzz args pick this address as the consideration
+ // recipient, then the ERC20 transfers and the native token
+ // transfers will be filtered, so there will be no events.
+ address(context.fulfillArgs.considerationRecipient) !=
+ address(this)
+ ) {
+ // This checks that the ERC20 transfers were not all aggregated
+ // into a single transfer.
+ vm.expectEmit(true, true, false, true, address(token1));
+ emit Transfer(
+ address(this), // from
+ address(context.fulfillArgs.considerationRecipient), // to
+ // The value should in the transfer event should either be
+ // the amount * the number of NFTs for sale (if aggregating) or
+ // the amount (if not aggregating).
+ context.fulfillArgs.amount *
+ (
+ context
+ .fulfillArgs
+ .shouldAggregateFulfillmentComponents
+ ? expectedFulfilledOrderCount
+ : 1
+ )
+ );
+
+ if (context.fulfillArgs.considerationItemsPerOrderCount >= 2) {
+ // This checks that the second consideration item is being
+ // properly handled.
+ vm.expectEmit(true, true, false, true, address(token2));
+ emit Transfer(
+ address(this), // from
+ address(context.fulfillArgs.considerationRecipient), // to
+ context.fulfillArgs.amount *
+ (
+ context
+ .fulfillArgs
+ .shouldAggregateFulfillmentComponents
+ ? expectedFulfilledOrderCount
+ : 1
+ ) // value
+ );
+ }
+ }
+ }
+
+ // Make the call to Seaport. When the fuzz args call for using native
+ // consideration, send enough native tokens to cover the amount per sale
+ // * the number of sales. Otherwise, send just the excess native
+ // tokens.
+ context.seaport.fulfillAvailableAdvancedOrders{
+ value: context.fulfillArgs.excessNativeTokens +
+ (
+ context.fulfillArgs.shouldIncludeNativeConsideration
+ ? context.fulfillArgs.amount *
+ context.fulfillArgs.maximumFulfilledCount
+ : 0
+ )
+ }({
+ advancedOrders: infra.advancedOrders,
+ criteriaResolvers: infra.criteriaResolvers,
+ offerFulfillments: infra.offerFulfillmentComponents,
+ considerationFulfillments: infra.considerationFulfillmentComponents,
+ fulfillerConduitKey: bytes32(conduitKey),
+ // If the fuzz args call for specifying a recipient, pass in the
+ // offer recipient. Otherwise, pass in the null address, which
+ // sets the caller as the recipient.
+ recipient: context.fulfillArgs.shouldSpecifyRecipient
+ ? context.fulfillArgs.offerRecipient
+ : address(0),
+ maximumFulfilled: context.fulfillArgs.maximumFulfilledCount
+ });
+
+ // Return early if the call should return an invalid magic value,
+ // because that triggers a seaport-level revert.
+ if (context.fulfillArgs.shouldReturnInvalidMagicValue) {
+ return;
+ }
+
+ // Store balances after the call for later comparison.
+ infra.callerBalanceAfter = address(this).balance;
+ infra.considerationRecipientNativeBalanceAfter = address(
+ context.fulfillArgs.considerationRecipient
+ ).balance;
+ infra.considerationRecipientToken1BalanceAfter = token1.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ );
+ infra.considerationRecipientToken2BalanceAfter = token2.balanceOf(
+ context.fulfillArgs.considerationRecipient
+ );
+
+ // Check that the NFTs were transferred to the expected recipient.
+ for (
+ uint256 i = 0;
+ i < context.fulfillArgs.maximumFulfilledCount;
+ i++
+ ) {
+ if (orderHashesThatShouldRevertInAuth[i] == bytes32(0)) {
+ // The NFT should be owned according to this snippet if the order
+ // was not skipped.
+ assertEq(
+ test721_1.ownerOf(context.fulfillArgs.tokenId + i),
+ context.fulfillArgs.shouldSpecifyRecipient
+ ? context.fulfillArgs.offerRecipient
+ : address(this),
+ "NFT owner incorrect."
+ );
+ } else {
+ // The NFT should be owned by the original minter if the order
+ // was skipped.
+ assertEq(
+ test721_1.ownerOf(context.fulfillArgs.tokenId + i),
+ offerer1.addr,
+ "NFT owner incorrect."
+ );
+ }
+ }
+
+ {
+ uint256 eligibleOrders = infra.advancedOrders.length -
+ skippedOrderCount;
+ uint256 expectedFulfilledOrderCount = eligibleOrders <
+ context.fulfillArgs.maximumFulfilledCount
+ ? eligibleOrders
+ : context.fulfillArgs.maximumFulfilledCount;
+
+ // Check that the ERC20s or native tokens were transferred to the
+ // expected recipient according to the fuzz args.
+ if (context.fulfillArgs.shouldIncludeNativeConsideration) {
+ if (
+ address(context.fulfillArgs.considerationRecipient) ==
+ address(this)
+ ) {
+ // Edge case: If the fuzz args pick this address for the
+ // consideration recipient, then the caller's balance should not
+ // change.
+ assertEq(
+ infra.callerBalanceAfter,
+ infra.callerBalanceBefore,
+ "Caller balance incorrect (this contract)."
+ );
+ } else {
+ // Check that the consideration recipient's native balance was
+ // increased by the amount * the number of NFTs for sale.
+ assertEq(
+ infra.considerationRecipientNativeBalanceAfter,
+ infra.considerationRecipientNativeBalanceBefore +
+ context.fulfillArgs.amount *
+ expectedFulfilledOrderCount,
+ "Consideration recipient native balance incorrect."
+ );
+ // The consideration (amount * maximumFulfilledCount) should be
+ // spent, and the excessNativeTokens should be returned.
+ assertEq(
+ infra.callerBalanceAfter +
+ context.fulfillArgs.amount *
+ expectedFulfilledOrderCount,
+ infra.callerBalanceBefore,
+ "Caller balance incorrect."
+ );
+ }
+ } else {
+ // The `else` here is the case where no native consieration is used.
+ if (
+ address(context.fulfillArgs.considerationRecipient) ==
+ address(this)
+ ) {
+ // Edge case: If the fuzz args pick this address for the
+ // consideration recipient, then the caller's balance should not
+ // change.
+ assertEq(
+ infra.considerationRecipientToken1BalanceAfter,
+ infra.considerationRecipientToken1BalanceBefore,
+ "Consideration recipient token1 balance incorrect (this)."
+ );
+ } else {
+ assertEq(
+ infra.considerationRecipientToken1BalanceAfter,
+ infra.considerationRecipientToken1BalanceBefore +
+ context.fulfillArgs.amount *
+ expectedFulfilledOrderCount,
+ "Consideration recipient token1 balance incorrect."
+ );
+ }
+
+ if (context.fulfillArgs.considerationItemsPerOrderCount >= 2) {
+ if (
+ address(context.fulfillArgs.considerationRecipient) ==
+ address(this)
+ ) {
+ // Edge case: If the fuzz args pick this address for the
+ // consideration recipient, then the caller's balance should
+ // not change.
+ assertEq(
+ infra.considerationRecipientToken2BalanceAfter,
+ infra.considerationRecipientToken2BalanceBefore,
+ "Consideration recipient token2 balance incorrect (this)."
+ );
+ } else {
+ assertEq(
+ infra.considerationRecipientToken2BalanceAfter,
+ infra.considerationRecipientToken2BalanceBefore +
+ context.fulfillArgs.amount *
+ expectedFulfilledOrderCount,
+ "Consideration recipient token2 balance incorrect."
+ );
+ }
+ }
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////////////////
+ // //
+ // Pretty much everything below here can be ignored. It's all just very //
+ // lightly modified code from `TestTransferValidationZoneOffererTest`, //
+ // which is pretty stable. //
+ // //
+ ////////////////////////////////////////////////////////////////////////////
+
+ function _buildOrdersFromFuzzArgs(
+ Context memory context,
+ uint256 key,
+ address verboseZoneAddress
+ ) internal view returns (AdvancedOrder[] memory advancedOrders) {
+ // Create the OrderComponents array from the fuzz args.
+ OrderComponents[] memory orderComponents;
+ orderComponents = _buildOrderComponentsArrayFromFuzzArgs(
+ context,
+ verboseZoneAddress
+ );
+
+ // Set up the AdvancedOrder array.
+ AdvancedOrder[] memory _advancedOrders = new AdvancedOrder[](
+ context.fulfillArgs.orderCount
+ );
+
+ // Iterate over the OrderComponents array and build an AdvancedOrder
+ // for each OrderComponents.
+ Order memory order;
+ for (uint256 i = 0; i < orderComponents.length; i++) {
+ if (orderComponents[i].orderType == OrderType.CONTRACT) {
+ revert("Not implemented.");
+ } else {
+ // Create the order.
+ order = _toOrder(context.seaport, orderComponents[i], key);
+ // Convert it to an AdvancedOrder and add it to the array.
+ _advancedOrders[i] = order.toAdvancedOrder(
+ 1,
+ 1,
+ // Reusing salt here for junk data.
+ context.fulfillArgs.shouldIncludeJunkDataInAdvancedOrder
+ ? bytes(
+ abi.encodePacked(
+ context.fulfillArgs.salt,
+ context.fulfillArgs.salt
+ )
+ )
+ : bytes("")
+ );
+ }
+ }
+
+ return _advancedOrders;
+ }
+
+ function _buildOrdersAndFulfillmentsMirrorOrdersFromFuzzArgs(
+ Context memory context,
+ address verboseZoneAddress
+ ) internal returns (Order[] memory, Fulfillment[] memory) {
+ uint256 i;
+
+ // Set up the OrderAndFulfillmentInfra struct.
+ OrderAndFulfillmentInfra memory infra = OrderAndFulfillmentInfra(
+ new OfferItem[](context.matchArgs.orderPairCount),
+ new ConsiderationItem[](context.matchArgs.orderPairCount),
+ OrderComponentsLib.empty(),
+ new Order[](context.matchArgs.orderPairCount * 2),
+ FulfillmentLib.empty(),
+ new Fulfillment[](context.matchArgs.orderPairCount * 2)
+ );
+
+ // Iterate once for each orderPairCount, which is
+ // used as the number of order pairs to make here.
+ for (i = 0; i < context.matchArgs.orderPairCount; i++) {
+ // Mint the NFTs for the prime offerer to sell.
+ test721_1.mint(
+ fuzzPrimeOfferer.addr,
+ context.matchArgs.tokenId + i
+ );
+ test721_1.mint(
+ fuzzPrimeOfferer.addr,
+ (context.matchArgs.tokenId + i) * 2
+ );
+
+ // Build the OfferItem array for the prime offerer's order.
+ infra.offerItemArray = _buildPrimeOfferItemArray(context, i);
+ // Build the ConsiderationItem array for the prime offerer's order.
+ infra.considerationItemArray = _buildPrimeConsiderationItemArray(
+ context
+ );
+
+ // Build the OrderComponents for the prime offerer's order.
+ infra.orderComponents = _buildOrderComponents(
+ context,
+ infra.offerItemArray,
+ infra.considerationItemArray,
+ fuzzPrimeOfferer.addr,
+ verboseZoneAddress
+ );
+
+ // Add the order to the orders array.
+ infra.orders[i] = _toOrder(
+ context.seaport,
+ infra.orderComponents,
+ fuzzPrimeOfferer.key
+ );
+
+ // Build the offerItemArray for the mirror offerer's order.
+ infra.offerItemArray = _buildMirrorOfferItemArray(context);
+
+ // Build the considerationItemArray for the mirror offerer's order.
+ // Note that the consideration on the mirror is always just one NFT,
+ // even if the prime order has an excess item.
+ infra.considerationItemArray = buildMirrorConsiderationItemArray(
+ context,
+ i
+ );
+
+ // Build the OrderComponents for the mirror offerer's order.
+ infra.orderComponents = _buildOrderComponents(
+ context,
+ infra.offerItemArray,
+ infra.considerationItemArray,
+ fuzzMirrorOfferer.addr,
+ verboseZoneAddress
+ );
+
+ // Create the order and add the order to the orders array.
+ infra.orders[i + context.matchArgs.orderPairCount] = _toOrder(
+ context.seaport,
+ infra.orderComponents,
+ fuzzMirrorOfferer.key
+ );
+ }
+
+ bytes32[] memory orderHashes = new bytes32[](
+ context.matchArgs.orderPairCount * 2
+ );
+
+ UnavailableReason[] memory unavailableReasons = new UnavailableReason[](
+ context.matchArgs.orderPairCount * 2
+ );
+
+ // Build fulfillments.
+ (infra.fulfillments, , ) = matchFulfillmentHelper
+ .getMatchedFulfillments(
+ infra.orders,
+ orderHashes,
+ unavailableReasons
+ );
+
+ return (infra.orders, infra.fulfillments);
+ }
+
+ function _buildPrimeOfferItemArray(
+ Context memory context,
+ uint256 i
+ ) internal view returns (OfferItem[] memory _offerItemArray) {
+ // Set up the OfferItem array.
+ OfferItem[] memory offerItemArray = new OfferItem[](
+ context.matchArgs.shouldIncludeExcessOfferItems ? 2 : 1
+ );
+
+ // If the fuzz args call for an excess offer item...
+ if (context.matchArgs.shouldIncludeExcessOfferItems) {
+ // Create the OfferItem array containing the offered item and the
+ // excess item.
+ offerItemArray = SeaportArrays.OfferItems(
+ OfferItemLib
+ .fromDefault(SINGLE_721)
+ .withToken(address(test721_1))
+ .withIdentifierOrCriteria(context.matchArgs.tokenId + i),
+ OfferItemLib
+ .fromDefault(SINGLE_721)
+ .withToken(address(test721_1))
+ .withIdentifierOrCriteria(
+ (context.matchArgs.tokenId + i) * 2
+ )
+ );
+ } else {
+ // Otherwise, create the OfferItem array containing the one offered
+ // item.
+ offerItemArray = SeaportArrays.OfferItems(
+ OfferItemLib
+ .fromDefault(SINGLE_721)
+ .withToken(address(test721_1))
+ .withIdentifierOrCriteria(context.matchArgs.tokenId + i)
+ );
+ }
+
+ return offerItemArray;
+ }
+
+ function _buildPrimeConsiderationItemArray(
+ Context memory context
+ )
+ internal
+ view
+ returns (ConsiderationItem[] memory _considerationItemArray)
+ {
+ // Set up the ConsiderationItem array.
+ ConsiderationItem[]
+ memory considerationItemArray = new ConsiderationItem[](
+ context.matchArgs.considerationItemsPerPrimeOrderCount
+ );
+
+ // Create the consideration items.
+ (
+ ConsiderationItem memory nativeConsiderationItem,
+ ConsiderationItem memory erc20ConsiderationItemOne,
+ ConsiderationItem memory erc20ConsiderationItemTwo
+ ) = _createReusableConsiderationItems(
+ context.matchArgs.amount,
+ fuzzPrimeOfferer.addr
+ );
+
+ if (context.matchArgs.considerationItemsPerPrimeOrderCount == 1) {
+ // If the fuzz args call for native consideration...
+ if (context.matchArgs.shouldIncludeNativeConsideration) {
+ // ...add a native consideration item...
+ considerationItemArray = SeaportArrays.ConsiderationItems(
+ nativeConsiderationItem
+ );
+ } else {
+ // ...otherwise, add an ERC20 consideration item.
+ considerationItemArray = SeaportArrays.ConsiderationItems(
+ erc20ConsiderationItemOne
+ );
+ }
+ } else if (
+ context.matchArgs.considerationItemsPerPrimeOrderCount == 2
+ ) {
+ // If the fuzz args call for native consideration...
+ if (context.matchArgs.shouldIncludeNativeConsideration) {
+ // ...add a native consideration item and an ERC20
+ // consideration item...
+ considerationItemArray = SeaportArrays.ConsiderationItems(
+ nativeConsiderationItem,
+ erc20ConsiderationItemOne
+ );
+ } else {
+ // ...otherwise, add two ERC20 consideration items.
+ considerationItemArray = SeaportArrays.ConsiderationItems(
+ erc20ConsiderationItemOne,
+ erc20ConsiderationItemTwo
+ );
+ }
+ } else {
+ // If the fuzz args call for three consideration items per prime
+ // order, add all three consideration items.
+ considerationItemArray = SeaportArrays.ConsiderationItems(
+ nativeConsiderationItem,
+ erc20ConsiderationItemOne,
+ erc20ConsiderationItemTwo
+ );
+ }
+
+ return considerationItemArray;
+ }
+
+ function _buildOrderComponentsArrayFromFuzzArgs(
+ Context memory context,
+ address verboseZoneAddress
+ ) internal view returns (OrderComponents[] memory _orderComponentsArray) {
+ // Set up the OrderComponentInfra struct.
+ OrderComponentInfra memory orderComponentInfra = OrderComponentInfra(
+ OrderComponentsLib.empty(),
+ new OrderComponents[](context.fulfillArgs.orderCount),
+ new OfferItem[][](context.fulfillArgs.orderCount),
+ new ConsiderationItem[][](context.fulfillArgs.orderCount),
+ ConsiderationItemLib.empty(),
+ ConsiderationItemLib.empty(),
+ ConsiderationItemLib.empty()
+ );
+
+ // Create three different consideration items.
+ (
+ orderComponentInfra.nativeConsiderationItem,
+ orderComponentInfra.erc20ConsiderationItemOne,
+ orderComponentInfra.erc20ConsiderationItemTwo
+ ) = _createReusableConsiderationItems(
+ context.fulfillArgs.amount,
+ context.fulfillArgs.considerationRecipient
+ );
+
+ // Iterate once for each order and create the OfferItems[] and
+ // ConsiderationItems[] for each order.
+ for (uint256 i; i < context.fulfillArgs.orderCount; i++) {
+ // Add a one-element OfferItems[] to the OfferItems[][].
+ orderComponentInfra.offerItemArray[i] = SeaportArrays.OfferItems(
+ OfferItemLib
+ .fromDefault(SINGLE_721)
+ .withToken(address(test721_1))
+ .withIdentifierOrCriteria(context.fulfillArgs.tokenId + i)
+ );
+
+ if (context.fulfillArgs.considerationItemsPerOrderCount == 1) {
+ // If the fuzz args call for native consideration...
+ if (context.fulfillArgs.shouldIncludeNativeConsideration) {
+ // ...add a native consideration item...
+ orderComponentInfra.considerationItemArray[
+ i
+ ] = SeaportArrays.ConsiderationItems(
+ orderComponentInfra.nativeConsiderationItem
+ );
+ } else {
+ // ...otherwise, add an ERC20 consideration item.
+ orderComponentInfra.considerationItemArray[
+ i
+ ] = SeaportArrays.ConsiderationItems(
+ orderComponentInfra.erc20ConsiderationItemOne
+ );
+ }
+ } else if (
+ context.fulfillArgs.considerationItemsPerOrderCount == 2
+ ) {
+ // If the fuzz args call for native consideration...
+ if (context.fulfillArgs.shouldIncludeNativeConsideration) {
+ // ...add a native consideration item and an ERC20
+ // consideration item...
+ orderComponentInfra.considerationItemArray[
+ i
+ ] = SeaportArrays.ConsiderationItems(
+ orderComponentInfra.nativeConsiderationItem,
+ orderComponentInfra.erc20ConsiderationItemOne
+ );
+ } else {
+ // ...otherwise, add two ERC20 consideration items.
+ orderComponentInfra.considerationItemArray[
+ i
+ ] = SeaportArrays.ConsiderationItems(
+ orderComponentInfra.erc20ConsiderationItemOne,
+ orderComponentInfra.erc20ConsiderationItemTwo
+ );
+ }
+ } else {
+ orderComponentInfra.considerationItemArray[i] = SeaportArrays
+ .ConsiderationItems(
+ orderComponentInfra.nativeConsiderationItem,
+ orderComponentInfra.erc20ConsiderationItemOne,
+ orderComponentInfra.erc20ConsiderationItemTwo
+ );
+ }
+ }
+
+ bytes32 conduitKey;
+
+ // Iterate once for each order and create the OrderComponents.
+ for (uint256 i = 0; i < context.fulfillArgs.orderCount; i++) {
+ // if context.fulfillArgs.shouldUseConduit is false: don't use conduits at all.
+ // if context.fulfillArgs.shouldUseConduit is true:
+ // if context.fulfillArgs.tokenId % 2 == 0:
+ // use conduits for some and not for others
+ // if context.fulfillArgs.tokenId % 2 != 0:
+ // use conduits for all
+ // This is plainly deranged, but it allows for conduit use
+ // for all, for some, and none without weighing down the stack.
+ conduitKey = !context
+ .fulfillArgs
+ .shouldIncludeNativeConsideration &&
+ context.fulfillArgs.shouldUseConduit &&
+ (context.fulfillArgs.tokenId % 2 == 0 ? i % 2 == 0 : true)
+ ? conduitKeyOne
+ : bytes32(0);
+
+ // Build the order components.
+ orderComponentInfra.orderComponents = OrderComponentsLib
+ .fromDefault(STD_RESTRICTED)
+ .withOffer(orderComponentInfra.offerItemArray[i])
+ .withConsideration(
+ orderComponentInfra.considerationItemArray[i]
+ )
+ .withZone(verboseZoneAddress)
+ .withZoneHash(context.fulfillArgs.zoneHash)
+ .withConduitKey(conduitKey)
+ .withSalt(context.fulfillArgs.salt % (i + 1)); // Is this dumb?
+
+ // Add the OrderComponents to the OrderComponents[].
+ orderComponentInfra.orderComponentsArray[i] = orderComponentInfra
+ .orderComponents;
+ }
+
+ // Return the OrderComponents[].
+ return orderComponentInfra.orderComponentsArray;
+ }
+
+ function _buildOrderComponents(
+ Context memory context,
+ OfferItem[] memory offerItemArray,
+ ConsiderationItem[] memory considerationItemArray,
+ address offerer,
+ address verboseZoneAddress
+ ) internal view returns (OrderComponents memory _orderComponents) {
+ OrderComponents memory orderComponents = OrderComponentsLib.empty();
+
+ // Create the offer and consideration item arrays.
+ OfferItem[] memory _offerItemArray = offerItemArray;
+ ConsiderationItem[]
+ memory _considerationItemArray = considerationItemArray;
+
+ // Build the OrderComponents for the prime offerer's order.
+ orderComponents = OrderComponentsLib
+ .fromDefault(STD_RESTRICTED)
+ .withOffer(_offerItemArray)
+ .withConsideration(_considerationItemArray)
+ .withZone(verboseZoneAddress)
+ .withOrderType(OrderType.FULL_OPEN)
+ .withConduitKey(
+ context.matchArgs.tokenId % 2 == 0 ? conduitKeyOne : bytes32(0)
+ )
+ .withOfferer(offerer)
+ .withCounter(context.seaport.getCounter(offerer));
+
+ // ... set the zone to the verboseZone and set the order type to
+ // FULL_RESTRICTED.
+ orderComponents = orderComponents
+ .copy()
+ .withZone(verboseZoneAddress)
+ .withOrderType(OrderType.FULL_RESTRICTED);
+
+ return orderComponents;
+ }
+
+ function _toOrder(
+ ConsiderationInterface seaport,
+ OrderComponents memory orderComponents,
+ uint256 pkey
+ ) internal view returns (Order memory order) {
+ bytes32 orderHash = seaport.getOrderHash(orderComponents);
+ bytes memory signature = signOrder(seaport, pkey, orderHash);
+ order = OrderLib
+ .empty()
+ .withParameters(orderComponents.toOrderParameters())
+ .withSignature(signature);
+ }
+
+ function _buildMirrorOfferItemArray(
+ Context memory context
+ ) internal view returns (OfferItem[] memory _offerItemArray) {
+ // Set up the OfferItem array.
+ OfferItem[] memory offerItemArray = new OfferItem[](1);
+
+ // Create some consideration items.
+ (
+ ConsiderationItem memory nativeConsiderationItem,
+ ConsiderationItem memory erc20ConsiderationItemOne,
+ ConsiderationItem memory erc20ConsiderationItemTwo
+ ) = _createReusableConsiderationItems(
+ context.matchArgs.amount,
+ fuzzPrimeOfferer.addr
+ );
+
+ // Convert them to OfferItems.
+ OfferItem memory nativeOfferItem = nativeConsiderationItem
+ .toOfferItem();
+ OfferItem memory erc20OfferItemOne = erc20ConsiderationItemOne
+ .toOfferItem();
+ OfferItem memory erc20OfferItemTwo = erc20ConsiderationItemTwo
+ .toOfferItem();
+
+ if (context.matchArgs.considerationItemsPerPrimeOrderCount == 1) {
+ // If the fuzz args call for native consideration...
+ if (context.matchArgs.shouldIncludeNativeConsideration) {
+ // ...add a native consideration item...
+ offerItemArray = SeaportArrays.OfferItems(nativeOfferItem);
+ } else {
+ // ...otherwise, add an ERC20 consideration item.
+ offerItemArray = SeaportArrays.OfferItems(erc20OfferItemOne);
+ }
+ } else if (
+ context.matchArgs.considerationItemsPerPrimeOrderCount == 2
+ ) {
+ // If the fuzz args call for native consideration...
+ if (context.matchArgs.shouldIncludeNativeConsideration) {
+ // ...add a native consideration item and an ERC20
+ // consideration item...
+ offerItemArray = SeaportArrays.OfferItems(
+ nativeOfferItem,
+ erc20OfferItemOne
+ );
+ } else {
+ // ...otherwise, add two ERC20 consideration items.
+ offerItemArray = SeaportArrays.OfferItems(
+ erc20OfferItemOne,
+ erc20OfferItemTwo
+ );
+ }
+ } else {
+ offerItemArray = SeaportArrays.OfferItems(
+ nativeOfferItem,
+ erc20OfferItemOne,
+ erc20OfferItemTwo
+ );
+ }
+
+ return offerItemArray;
+ }
+
+ function buildMirrorConsiderationItemArray(
+ Context memory context,
+ uint256 i
+ )
+ internal
+ view
+ returns (ConsiderationItem[] memory _considerationItemArray)
+ {
+ // Set up the ConsiderationItem array.
+ ConsiderationItem[]
+ memory considerationItemArray = new ConsiderationItem[](
+ context.matchArgs.considerationItemsPerPrimeOrderCount
+ );
+
+ // Note that the consideration array here will always be just one NFT
+ // so because the second NFT on the offer side is meant to be excess.
+ considerationItemArray = SeaportArrays.ConsiderationItems(
+ ConsiderationItemLib
+ .fromDefault(SINGLE_721)
+ .withToken(address(test721_1))
+ .withIdentifierOrCriteria(context.matchArgs.tokenId + i)
+ .withRecipient(fuzzMirrorOfferer.addr)
+ );
+
+ return considerationItemArray;
+ }
+
+ function _createReusableConsiderationItems(
+ uint256 amount,
+ address recipient
+ )
+ internal
+ view
+ returns (
+ ConsiderationItem memory nativeConsiderationItem,
+ ConsiderationItem memory erc20ConsiderationItemOne,
+ ConsiderationItem memory erc20ConsiderationItemTwo
+ )
+ {
+ // Create a reusable native consideration item.
+ nativeConsiderationItem = ConsiderationItemLib
+ .empty()
+ .withItemType(ItemType.NATIVE)
+ .withIdentifierOrCriteria(0)
+ .withStartAmount(amount)
+ .withEndAmount(amount)
+ .withRecipient(recipient);
+
+ // Create a reusable ERC20 consideration item.
+ erc20ConsiderationItemOne = ConsiderationItemLib
+ .empty()
+ .withItemType(ItemType.ERC20)
+ .withToken(address(token1))
+ .withIdentifierOrCriteria(0)
+ .withStartAmount(amount)
+ .withEndAmount(amount)
+ .withRecipient(recipient);
+
+ // Create a second reusable ERC20 consideration item.
+ erc20ConsiderationItemTwo = ConsiderationItemLib
+ .empty()
+ .withItemType(ItemType.ERC20)
+ .withIdentifierOrCriteria(0)
+ .withToken(address(token2))
+ .withStartAmount(amount)
+ .withEndAmount(amount)
+ .withRecipient(recipient);
+ }
+
+ function _boundMatchArgs(
+ MatchFuzzInputs memory matchArgs
+ ) internal returns (MatchFuzzInputs memory) {
+ // Avoid weird overflow issues.
+ matchArgs.amount = uint128(
+ bound(matchArgs.amount, 1, 0xffffffffffffffff)
+ );
+ // Avoid trying to mint the same token.
+ matchArgs.tokenId = bound(matchArgs.tokenId, 0xff, 0xffffffffffffffff);
+ // Make 2-8 order pairs per call. Each order pair will have 1-2 offer
+ // items on the prime side (depending on whether
+ // shouldIncludeExcessOfferItems is true or false).
+ matchArgs.orderPairCount = bound(matchArgs.orderPairCount, 2, 32);
+ // Use 1-3 (prime) consideration items per order.
+ matchArgs.considerationItemsPerPrimeOrderCount = bound(
+ matchArgs.considerationItemsPerPrimeOrderCount,
+ 1,
+ 3
+ );
+ // To put three items in the consideration, native tokens must be
+ // included.
+ matchArgs.shouldIncludeNativeConsideration =
+ matchArgs.shouldIncludeNativeConsideration ||
+ matchArgs.considerationItemsPerPrimeOrderCount >= 3;
+ // Include some excess native tokens to check that they're ending up
+ // with the caller afterward.
+ matchArgs.excessNativeTokens = uint128(
+ bound(
+ matchArgs.excessNativeTokens,
+ 0,
+ 0xfffffffffffffffffffffffffffff
+ )
+ );
+ // Don't set the offer recipient to the null address, because that's the
+ // way to indicate that the caller should be the recipient.
+ matchArgs.unspentPrimeOfferItemRecipient = _nudgeAddressIfProblematic(
+ address(
+ uint160(
+ bound(
+ uint160(matchArgs.unspentPrimeOfferItemRecipient),
+ 1,
+ type(uint160).max
+ )
+ )
+ )
+ );
+
+ matchArgs.shouldRevert =
+ matchArgs.shouldRevert &&
+ !matchArgs.shouldReturnInvalidMagicValue;
+
+ return matchArgs;
+ }
+
+ function _boundFulfillArgs(
+ FulfillFuzzInputs memory fulfillArgs
+ ) internal returns (FulfillFuzzInputs memory) {
+ // Limit this value to avoid overflow issues.
+ fulfillArgs.amount = uint128(
+ bound(fulfillArgs.amount, 1, 0xffffffffffffffff)
+ );
+ // Limit this value to avoid overflow issues.
+ fulfillArgs.tokenId = bound(fulfillArgs.tokenId, 1, 0xffffffffffffffff);
+ // Create between 4 and 16 orders.
+ fulfillArgs.orderCount = bound(fulfillArgs.orderCount, 4, 32);
+ // Use between 1 and 3 consideration items per order.
+ fulfillArgs.considerationItemsPerOrderCount = bound(
+ fulfillArgs.considerationItemsPerOrderCount,
+ 1,
+ 3
+ );
+ // To put three items in the consideration, native tokens must be
+ // included.
+ fulfillArgs.shouldIncludeNativeConsideration =
+ fulfillArgs.shouldIncludeNativeConsideration ||
+ fulfillArgs.considerationItemsPerOrderCount >= 3;
+ // Fulfill between 2 and the orderCount.
+ fulfillArgs.maximumFulfilledCount = bound(
+ fulfillArgs.maximumFulfilledCount,
+ 2,
+ fulfillArgs.orderCount
+ );
+ // Limit this value to avoid overflow issues.
+ fulfillArgs.excessNativeTokens = uint128(
+ bound(
+ fulfillArgs.excessNativeTokens,
+ 0,
+ 0xfffffffffffffffffffffffffffff
+ )
+ );
+ // Don't set the offer recipient to the null address, because that's the
+ // way to indicate that the caller should be the recipient and because
+ // some tokens refuse to transfer to the null address.
+ fulfillArgs.offerRecipient = _nudgeAddressIfProblematic(
+ address(
+ uint160(
+ bound(
+ uint160(fulfillArgs.offerRecipient),
+ 1,
+ type(uint160).max
+ )
+ )
+ )
+ );
+ // Don't set the consideration recipient to the null address, because
+ // some tokens refuse to transfer to the null address.
+ fulfillArgs.considerationRecipient = _nudgeAddressIfProblematic(
+ address(
+ uint160(
+ bound(
+ uint160(fulfillArgs.considerationRecipient),
+ 1,
+ type(uint160).max
+ )
+ )
+ )
+ );
+
+ fulfillArgs.shouldRevert =
+ fulfillArgs.shouldRevert &&
+ !fulfillArgs.shouldReturnInvalidMagicValue;
+
+ return fulfillArgs;
+ }
+
+ function _nudgeAddressIfProblematic(
+ address _address
+ ) internal returns (address) {
+ bool success;
+ assembly {
+ // Transfer the native token and store if it succeeded or not.
+ success := call(gas(), _address, 1, 0, 0, 0, 0)
+ }
+
+ if (success) {
+ return _address;
+ } else {
+ return address(uint160(_address) + 1);
+ }
+ }
+}
diff --git a/test/foundry/zone/impl/BadZone.sol b/test/foundry/zone/impl/BadZone.sol
index 216a7a704..22400a5b2 100644
--- a/test/foundry/zone/impl/BadZone.sol
+++ b/test/foundry/zone/impl/BadZone.sol
@@ -4,15 +4,19 @@ pragma solidity ^0.8.17;
import {
ZoneParameters,
Schema
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import {
- ZoneInterface
-} from "../../../../contracts/interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
contract BadZone is ERC165, ZoneInterface {
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) public pure returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
+
function validateOrder(
ZoneParameters calldata zoneParameters
) external pure returns (bytes4 validOrderMagicValue) {
diff --git a/test/foundry/zone/impl/HashCalldataTestZone.sol b/test/foundry/zone/impl/HashCalldataTestZone.sol
new file mode 100644
index 000000000..6ec35225d
--- /dev/null
+++ b/test/foundry/zone/impl/HashCalldataTestZone.sol
@@ -0,0 +1,104 @@
+//SPDX-License-Identifier: MIT
+pragma solidity ^0.8.13;
+
+import {
+ Schema,
+ ZoneParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
+
+contract HashCalldataTestZone is ZoneInterface {
+ bytes32 public expectedZoneAuthorizeCalldataHash;
+ bytes32 public expectedZoneValidateCalldataHash;
+
+ function authorizeOrder(
+ ZoneParameters calldata zoneParameters
+ ) public view returns (bytes4) {
+ // Hash the zone parameters.
+ bytes32 _expectedZoneHash = bytes32(
+ keccak256(abi.encode(zoneParameters))
+ );
+
+ if (_expectedZoneHash != expectedZoneAuthorizeCalldataHash) {
+ revert(
+ "Zone calldata hash does not match expected zone hash in authorizeOrder"
+ );
+ }
+
+ // Return the authorizeOrder magic value.
+ return this.authorizeOrder.selector;
+ }
+
+ /**
+ * @dev Validates the order with the given `zoneParameters`. Called by
+ * Consideration whenever any extraData is provided by the caller.
+ *
+ * @param zoneParameters The parameters for the order.
+ *
+ * @return validOrderMagicValue The validOrder magic value.
+ */
+ function validateOrder(
+ ZoneParameters calldata zoneParameters
+ ) external view returns (bytes4 validOrderMagicValue) {
+ // Hash the zone parameters.
+ bytes32 _expectedZoneHash = bytes32(
+ keccak256(abi.encode(zoneParameters))
+ );
+
+ if (_expectedZoneHash != expectedZoneValidateCalldataHash) {
+ revert(
+ "Zone calldata hash does not match expected zone hash in validateOrder"
+ );
+ }
+
+ // Return the validOrderMagicValue.
+ return ZoneInterface.validateOrder.selector;
+ }
+
+ function setExpectedAuthorizeCalldataHash(
+ bytes32 _expectedZoneAuthorizeCalldataHash
+ ) public {
+ expectedZoneAuthorizeCalldataHash = _expectedZoneAuthorizeCalldataHash;
+ }
+
+ function setExpectedValidateCalldataHash(
+ bytes32 _expectedZoneValidateCalldataHash
+ ) public {
+ expectedZoneValidateCalldataHash = _expectedZoneValidateCalldataHash;
+ }
+
+ receive() external payable {}
+
+ function getSeaportMetadata()
+ external
+ pure
+ override(ZoneInterface)
+ returns (string memory name, Schema[] memory schemas)
+ {
+ // Return the metadata.
+ name = "TestCalldataHashContractOfferer";
+ schemas = new Schema[](1);
+ schemas[0].id = 1337;
+ schemas[0].metadata = new bytes(0);
+ }
+
+ /**
+ * @dev Enable accepting ERC1155 tokens via safeTransfer.
+ */
+ function onERC1155Received(
+ address,
+ address,
+ uint256,
+ uint256,
+ bytes calldata
+ ) external pure returns (bytes4) {
+ return this.onERC1155Received.selector;
+ }
+
+ function supportsInterface(
+ bytes4 interfaceId
+ ) public view virtual override(ZoneInterface) returns (bool) {
+ return interfaceId == type(ZoneInterface).interfaceId;
+ }
+}
diff --git a/test/foundry/zone/impl/PostFullfillmentStatefulTestZone.sol b/test/foundry/zone/impl/StatefulTestZone.sol
similarity index 66%
rename from test/foundry/zone/impl/PostFullfillmentStatefulTestZone.sol
rename to test/foundry/zone/impl/StatefulTestZone.sol
index f46ad1f21..d0d0fa0d3 100644
--- a/test/foundry/zone/impl/PostFullfillmentStatefulTestZone.sol
+++ b/test/foundry/zone/impl/StatefulTestZone.sol
@@ -2,19 +2,17 @@
pragma solidity ^0.8.17;
import {
- ZoneParameters,
- Schema
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+ Schema,
+ ZoneParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ItemType } from "../../../../contracts/lib/ConsiderationEnums.sol";
+import { ItemType } from "seaport-types/src/lib/ConsiderationEnums.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import {
- ZoneInterface
-} from "../../../../contracts/interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
-contract PostFulfillmentStatefulTestZone is ERC165, ZoneInterface {
+contract StatefulTestZone is ERC165, ZoneInterface {
error IncorrectAmount(uint256 actual, uint256 expected);
error IncorrectItemType(ItemType actual, ItemType expected);
error IncorrectIdentifier(uint256 actual, uint256 expected);
@@ -25,7 +23,20 @@ contract PostFulfillmentStatefulTestZone is ERC165, ZoneInterface {
amountToCheck = amount;
}
- bool public called = false;
+ bool public authorizeCalled = false;
+ bool public validateCalled = false;
+
+ function authorizeOrder(
+ ZoneParameters calldata zoneParameters
+ ) public returns (bytes4) {
+ _checkZoneParameters(zoneParameters);
+
+ // Set the global called flag to true.
+ authorizeCalled = true;
+
+ // Return the authorizeOrder magic value.
+ return this.authorizeOrder.selector;
+ }
/**
* @dev Validates the order with the given `zoneParameters`. Called by
@@ -38,32 +49,10 @@ contract PostFulfillmentStatefulTestZone is ERC165, ZoneInterface {
function validateOrder(
ZoneParameters calldata zoneParameters
) external returns (bytes4 validOrderMagicValue) {
- // Check that the amount in the offer is correct.
- if (zoneParameters.offer[0].amount != amountToCheck) {
- revert IncorrectAmount(
- zoneParameters.offer[0].amount,
- amountToCheck
- );
- }
-
- // Check that the item type in the consideration is correct.
- if (zoneParameters.consideration[0].itemType != ItemType.ERC721) {
- revert IncorrectIdentifier(
- uint256(zoneParameters.consideration[0].itemType),
- uint256(ItemType.ERC721)
- );
- }
-
- // Check that the token ID in the consideration is correct.
- if (zoneParameters.consideration[0].identifier != 42) {
- revert IncorrectIdentifier(
- zoneParameters.consideration[0].identifier,
- 42
- );
- }
+ _checkZoneParameters(zoneParameters);
// Set the global called flag to true.
- called = true;
+ validateCalled = true;
// Return the validOrderMagicValue.
return ZoneInterface.validateOrder.selector;
@@ -85,7 +74,7 @@ contract PostFulfillmentStatefulTestZone is ERC165, ZoneInterface {
schemas[0].id = 3003;
schemas[0].metadata = new bytes(0);
- return ("PostFulfillmentStatefulTestZone", schemas);
+ return ("StatefulTestZone", schemas);
}
function supportsInterface(
@@ -95,4 +84,32 @@ contract PostFulfillmentStatefulTestZone is ERC165, ZoneInterface {
interfaceId == type(ZoneInterface).interfaceId ||
super.supportsInterface(interfaceId);
}
+
+ function _checkZoneParameters(
+ ZoneParameters calldata zoneParameters
+ ) internal view {
+ // Check that the amount in the offer is correct.
+ if (zoneParameters.offer[0].amount != amountToCheck) {
+ revert IncorrectAmount(
+ zoneParameters.offer[0].amount,
+ amountToCheck
+ );
+ }
+
+ // Check that the item type in the consideration is correct.
+ if (zoneParameters.consideration[0].itemType != ItemType.ERC721) {
+ revert IncorrectItemType(
+ zoneParameters.consideration[0].itemType,
+ ItemType.ERC721
+ );
+ }
+
+ // Check that the token ID in the consideration is correct.
+ if (zoneParameters.consideration[0].identifier != 42) {
+ revert IncorrectIdentifier(
+ zoneParameters.consideration[0].identifier,
+ 42
+ );
+ }
+ }
}
diff --git a/test/foundry/zone/impl/TestZone.sol b/test/foundry/zone/impl/TestZone.sol
index d46c0a3fc..50fda8a66 100644
--- a/test/foundry/zone/impl/TestZone.sol
+++ b/test/foundry/zone/impl/TestZone.sol
@@ -4,15 +4,19 @@ pragma solidity ^0.8.17;
import {
ZoneParameters,
Schema
-} from "../../../../contracts/lib/ConsiderationStructs.sol";
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
-import { ERC165 } from "../../../../contracts/interfaces/ERC165.sol";
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
-import {
- ZoneInterface
-} from "../../../../contracts/interfaces/ZoneInterface.sol";
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
contract TestZone is ERC165, ZoneInterface {
+ function authorizeOrder(
+ ZoneParameters calldata
+ ) public pure returns (bytes4) {
+ return this.authorizeOrder.selector;
+ }
+
// Called by Consideration whenever any extraData is provided by the caller.
function validateOrder(
ZoneParameters calldata
diff --git a/test/foundry/zone/impl/VerboseAuthZone.sol b/test/foundry/zone/impl/VerboseAuthZone.sol
new file mode 100644
index 000000000..0f64a73eb
--- /dev/null
+++ b/test/foundry/zone/impl/VerboseAuthZone.sol
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: MIT
+pragma solidity ^0.8.17;
+
+import {
+ Schema,
+ ZoneParameters
+} from "seaport-types/src/lib/ConsiderationStructs.sol";
+
+import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
+
+import { ZoneInterface } from "seaport-types/src/interfaces/ZoneInterface.sol";
+
+contract VerboseAuthZone is ERC165, ZoneInterface {
+ // Create a mapping of orderHashes to authorized status.
+ mapping(bytes32 => bool) public orderIsAuthorized;
+
+ bool shouldReturnInvalidMagicValue;
+ bool shouldRevert;
+
+ event Authorized(bytes32 orderHash);
+
+ event AuthorizeOrderReverted(bytes32 orderHash);
+
+ event AuthorizeOrderNonMagicValue(bytes32 orderHash);
+
+ error OrderNotAuthorized();
+
+ constructor(bool _shouldReturnInvalidMagicValue, bool _shouldRevert) {
+ shouldReturnInvalidMagicValue = _shouldReturnInvalidMagicValue;
+ shouldRevert = _shouldRevert;
+ }
+
+ function setAuthorizationStatus(bytes32 orderHash, bool status) public {
+ orderIsAuthorized[orderHash] = status;
+ }
+
+ function authorizeOrder(
+ ZoneParameters calldata zoneParameters
+ ) public returns (bytes4) {
+ if (!orderIsAuthorized[zoneParameters.orderHash]) {
+ if (shouldReturnInvalidMagicValue) {
+ emit AuthorizeOrderNonMagicValue(zoneParameters.orderHash);
+
+ // Return the a value that is not the authorizeOrder magic
+ // value.
+ return bytes4(0x12345678);
+ }
+
+ if (shouldRevert) {
+ emit AuthorizeOrderReverted(zoneParameters.orderHash);
+ revert OrderNotAuthorized();
+ }
+ }
+
+ emit Authorized(zoneParameters.orderHash);
+
+ // Return the authorizeOrder magic value.
+ return this.authorizeOrder.selector;
+ }
+
+ function validateOrder(
+ ZoneParameters calldata /* zoneParameters */
+ ) external pure returns (bytes4 validOrderMagicValue) {
+ // Return the validOrderMagicValue.
+ return ZoneInterface.validateOrder.selector;
+ }
+
+ function getSeaportMetadata()
+ external
+ pure
+ override
+ returns (
+ string memory name,
+ Schema[] memory schemas // map to Seaport Improvement Proposal IDs
+ )
+ {
+ schemas = new Schema[](1);
+ schemas[0].id = 3003;
+ schemas[0].metadata = new bytes(0);
+
+ return ("VerboseAuthZone", schemas);
+ }
+
+ function supportsInterface(
+ bytes4 interfaceId
+ ) public view override(ERC165, ZoneInterface) returns (bool) {
+ return
+ interfaceId == type(ZoneInterface).interfaceId ||
+ super.supportsInterface(interfaceId);
+ }
+}
diff --git a/test/revert.spec.ts b/test/revert.spec.ts
index 42506030a..ef7a6e871 100644
--- a/test/revert.spec.ts
+++ b/test/revert.spec.ts
@@ -5540,7 +5540,7 @@ describe(`Reverts (Seaport v${VERSION})`, function () {
});
// Skip this test when testing the reference contract
- if (!process.env.REFERENCE) {
+ if (!process.env.REFERENCE && !(hre as any).__SOLIDITY_COVERAGE_RUNNING) {
it("Reverts when 1155 token transfer reverts (via conduit, returndata)", async () => {
const recipient = await (
await ethers.getContractFactory("ExcessReturnDataRecipient")
@@ -5629,7 +5629,7 @@ describe(`Reverts (Seaport v${VERSION})`, function () {
ethers.constants.AddressZero,
{
value,
- gasLimit: baseGas.add(74000),
+ gasLimit: baseGas.add(80000),
}
)
).to.be.revertedWithCustomError(
@@ -8168,7 +8168,7 @@ describe(`Reverts (Seaport v${VERSION})`, function () {
)
.withArgs(orderHash);
});
- it("Fulfillment reverts if contract offerer reverts", async () => {
+ it("Fulfillment bubbles up error if contract offerer reverts with data", async () => {
// Contract offerer mints nft
const nftId = await mint721(
offererContract,
@@ -8215,22 +8215,19 @@ describe(`Reverts (Seaport v${VERSION})`, function () {
order.denominator = 1;
order.signature = "0x";
- await expect(
- marketplaceContract
- .connect(buyer)
- .fulfillAdvancedOrder(
- order,
- [],
- toKey(0),
- ethers.constants.AddressZero,
- { value }
- )
- )
- .to.be.revertedWithCustomError(
- marketplaceContract,
- "InvalidContractOrder"
- )
- .withArgs(orderHash);
+ if (!process.env.REFERENCE) {
+ await expect(
+ marketplaceContract
+ .connect(buyer)
+ .fulfillAdvancedOrder(
+ order,
+ [],
+ toKey(0),
+ ethers.constants.AddressZero,
+ { value }
+ )
+ ).to.be.revertedWithCustomError(offererContract, "IntentionalRevert");
+ }
});
it("Fulfillment reverts if contract offerer returns with garbage data", async () => {
// Contract offerer mints nft
@@ -8398,9 +8395,10 @@ describe(`Reverts (Seaport v${VERSION})`, function () {
});
});
+ // TODO: Add this test back in
describe(`Changing chainId`, function () {
// Note: Run this test last in this file as it hacks changing the hre
- it("Reverts on changed chainId", async () => {
+ it.skip("Reverts on changed chainId", async () => {
const nftId = await mintAndApprove721(
seller,
marketplaceContract.address
diff --git a/test/utils/eip712/code-gen.ts b/test/utils/eip712/code-gen.ts
deleted file mode 100644
index 12e89ac98..000000000
--- a/test/utils/eip712/code-gen.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { writeFileSync } from "fs";
-import path from "path";
-
-import { toHex } from "../encoding";
-
-const readCode = (index: number, length: number) => {
- const [shiftKey, letMaybe, prevNode, sibling] =
- index > 0
- ? [
- `shr(${index}, key)`,
- ``,
- `keccak256(0, TwoWords)`,
- `add(proof, ${toHex(index * 32)})`,
- ]
- : [`key`, `let `, `leaf`, `proof`];
-
- const getPtr = `${letMaybe}scratch := shl(5, and(${shiftKey}, 1))`;
- const writePrevNode = `mstore(scratch, ${prevNode})`;
- const code = [
- getPtr,
- writePrevNode,
- `mstore(xor(scratch, OneWord), calldataload(${sibling}))`,
- ];
- if (index + 1 === length) {
- code.push(`root := keccak256(0, TwoWords)`);
- }
- return code;
-};
-
-const depth = 7;
-
-const allCode = [
- `\tfunction _computeMerkleProofDepth${depth}(Eip712MerkleProof proofPtr, uint256 leaf) pure returns (bytes32 root) {`,
- `\t\tassembly{`,
- `\t\tlet key := shr(248, proofPtr)`,
- `\t\tlet proof := add(proofPtr, 1)`,
-];
-for (let i = 0; i < depth; i++) {
- if (i === depth - 1) allCode.push("\t\t\t// Compute root hash");
- else allCode.push(`\t\t\t// Compute level ${i + 1}`);
- allCode.push(...readCode(i, depth).map((ln) => "\t\t\t" + ln));
- if (i !== depth - 1) allCode.push("");
-}
-allCode.push("\t\t}", "\t}");
-
-writeFileSync(path.join(__dirname, "gen.sol"), allCode.join("\n"));
diff --git a/test/utils/events.ts b/test/utils/events.ts
index d25b43277..aa2ac2d37 100644
--- a/test/utils/events.ts
+++ b/test/utils/events.ts
@@ -1,4 +1,5 @@
-import type { Contract, ContractTransaction } from "ethers";
+import type { ContractTransaction } from "ethers";
+import type { Interface } from "ethers/lib/utils";
type DecodedTransactionEvent = {
eventName: string;
@@ -7,7 +8,7 @@ type DecodedTransactionEvent = {
type EventDecoder = {
eventName: string;
- contract: Contract;
+ contract: { interface: Interface };
};
export async function decodeEvents(
diff --git a/test/utils/helpers.ts b/test/utils/helpers.ts
index 6941cb70c..90f522866 100644
--- a/test/utils/helpers.ts
+++ b/test/utils/helpers.ts
@@ -9,7 +9,7 @@ import type {
Order,
} from "./types";
-export const VERSION = `1.5${process.env.REFERENCE ? "-reference" : ""}`;
+export const VERSION = `1.6${process.env.REFERENCE ? "-reference" : ""}`;
export const minRandom = (min: ethers.BigNumberish) => randomBN(10).add(min);
diff --git a/test/zone.spec.ts b/test/zone.spec.ts
index 4d43217f8..c23dce06a 100644
--- a/test/zone.spec.ts
+++ b/test/zone.spec.ts
@@ -2,6 +2,14 @@ import { loadFixture } from "@nomicfoundation/hardhat-network-helpers";
import { expect } from "chai";
import { ethers, network } from "hardhat";
+import {
+ type ConduitInterface,
+ type ConsiderationInterface,
+ type TestERC721,
+ type TestZone,
+ PausableZoneEventsAndErrors__factory as pausableZoneFactory,
+} from "../typechain-types";
+
import { merkleTree } from "./utils/criteria";
import {
buildResolver,
@@ -18,17 +26,13 @@ import { faucet } from "./utils/faucet";
import { seaportFixture } from "./utils/fixtures";
import { VERSION } from "./utils/helpers";
-import type {
- ConduitInterface,
- ConsiderationInterface,
- TestERC721,
- TestZone,
-} from "../typechain-types";
import type { SeaportFixtures } from "./utils/fixtures";
import type { Contract, Wallet } from "ethers";
const { parseEther } = ethers.utils;
+const pausableZoneInterface = pausableZoneFactory.createInterface();
+
describe(`Zone - PausableZone (Seaport v${VERSION})`, function () {
const { provider } = ethers;
const owner = new ethers.Wallet(randomHex(32), provider);
@@ -605,7 +609,7 @@ describe(`Zone - PausableZone (Seaport v${VERSION})`, function () {
await createZone(pausableZoneController);
});
- it("Assign pauser and self destruct the zone", async () => {
+ it("Assign pauser", async () => {
const pausableZoneControllerFactory = await ethers.getContractFactory(
"PausableZoneController",
owner
@@ -622,12 +626,12 @@ describe(`Zone - PausableZone (Seaport v${VERSION})`, function () {
// Attach to zone
const zone = await zoneContract.attach(zoneAddr);
- // Try to nuke the zone through the deployer before being assigned pauser
+ // Try to pause the zone through the deployer before being assigned pauser
await expect(pausableZoneController.connect(buyer).pause(zoneAddr)).to.be
.reverted;
- // Try to nuke the zone directly before being assigned pauser
- await expect(zone.connect(buyer).pause(zoneAddr)).to.be.reverted;
+ // Try to pause the zone directly before being assigned pauser
+ await expect(zone.connect(buyer).pause()).to.be.reverted;
await expect(
pausableZoneController.connect(buyer).assignPauser(seller.address)
@@ -646,7 +650,7 @@ describe(`Zone - PausableZone (Seaport v${VERSION})`, function () {
// Check pauser owner
expect(await pausableZoneController.pauser()).to.equal(buyer.address);
- // Now as pauser, nuke the zone
+ // Now as pauser, pause the zone
const tx = await pausableZoneController.connect(buyer).pause(zoneAddr);
// Check paused event was emitted
@@ -679,7 +683,7 @@ describe(`Zone - PausableZone (Seaport v${VERSION})`, function () {
);
});
- it("Revert on an order with a pausable zone if zone has been self destructed", async () => {
+ it("Revert on an order with a pausable zone if zone has been paused", async () => {
const pausableZoneControllerFactory = await ethers.getContractFactory(
"PausableZoneController",
owner
@@ -710,20 +714,27 @@ describe(`Zone - PausableZone (Seaport v${VERSION})`, function () {
2
);
- // owner nukes the zone
- pausableZoneController.pause(zoneAddr);
+ // owner pauses the zone
+ const tx = await pausableZoneController.pause(zoneAddr);
+
+ const events = await decodeEvents(tx, [
+ { eventName: "Paused", contract: { interface: pausableZoneInterface } },
+ ]);
+ expect(events.length).to.be.equal(1);
+
+ const [pauseEvent] = events;
+ expect(pauseEvent.eventName).to.equal("Paused");
if (!process.env.REFERENCE) {
await expect(
marketplaceContract.connect(buyer).fulfillOrder(order, toKey(0), {
value,
})
- )
- .to.be.revertedWithCustomError(
- marketplaceContract,
- "InvalidRestrictedOrder"
- )
- .withArgs(orderHash);
+ ).to.be.revertedWithCustomError(
+ // eslint-disable-next-line camelcase
+ { interface: pausableZoneInterface },
+ "ZoneIsPaused"
+ );
} else {
await expect(
marketplaceContract.connect(buyer).fulfillOrder(order, toKey(0), {
@@ -744,7 +755,7 @@ describe(`Zone - PausableZone (Seaport v${VERSION})`, function () {
const zoneAddr = await createZone(pausableZoneController);
- // non owner tries to use pausable deployer to nuke the zone, reverts
+ // non owner tries to use pausable deployer to pause the zone, reverts
await expect(pausableZoneController.connect(buyer).pause(zoneAddr)).to.be
.reverted;
});
diff --git a/yarn.lock b/yarn.lock
index a993fc65d..bf3174d98 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -387,6 +387,11 @@
"@ethersproject/properties" "^5.7.0"
"@ethersproject/strings" "^5.7.0"
+"@fastify/busboy@^2.0.0":
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/@fastify/busboy/-/busboy-2.0.0.tgz#f22824caff3ae506b18207bad4126dbc6ccdb6b8"
+ integrity sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==
+
"@humanwhocodes/config-array@^0.11.6":
version "0.11.7"
resolved "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz"
@@ -466,137 +471,95 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
-"@nomicfoundation/ethereumjs-block@^4.0.0":
- version "4.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-4.0.0.tgz"
- integrity sha512-bk8uP8VuexLgyIZAHExH1QEovqx0Lzhc9Ntm63nCRKLHXIZkobaFaeCVwTESV7YkPKUk7NiK11s8ryed4CS9yA==
- dependencies:
- "@nomicfoundation/ethereumjs-common" "^3.0.0"
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-trie" "^5.0.0"
- "@nomicfoundation/ethereumjs-tx" "^4.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- ethereum-cryptography "0.1.3"
+"@nomicfoundation/edr-darwin-arm64@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-arm64/-/edr-darwin-arm64-0.2.1.tgz#10c1a07add192583ce8b2d4cc93439f52b390a41"
+ integrity sha512-aMYaRaZVQ/TmyNJIoXf1bU4k0zfinaL9Sy1day4yGlL6eiQPFfRGj9W6TZaZIoYG0XTx/mQWD7dkXJ7LdrleJA==
-"@nomicfoundation/ethereumjs-blockchain@^6.0.0":
- version "6.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-6.0.0.tgz"
- integrity sha512-pLFEoea6MWd81QQYSReLlLfH7N9v7lH66JC/NMPN848ySPPQA5renWnE7wPByfQFzNrPBuDDRFFULMDmj1C0xw==
- dependencies:
- "@nomicfoundation/ethereumjs-block" "^4.0.0"
- "@nomicfoundation/ethereumjs-common" "^3.0.0"
- "@nomicfoundation/ethereumjs-ethash" "^2.0.0"
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-trie" "^5.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- abstract-level "^1.0.3"
- debug "^4.3.3"
- ethereum-cryptography "0.1.3"
- level "^8.0.0"
- lru-cache "^5.1.1"
- memory-level "^1.0.0"
+"@nomicfoundation/edr-darwin-x64@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-darwin-x64/-/edr-darwin-x64-0.2.1.tgz#eaa29d2ba9f91ddb5f59b872c5a54f94a6fe3095"
+ integrity sha512-ma0SLcjHm5L3nPHcKFJB0jv/gKGSKaxr5Z65rurX/eaYUQJ7YGMsb8er9bSCo9rjzOtxf4FoPj3grL3zGpOj8A==
-"@nomicfoundation/ethereumjs-common@^3.0.0":
- version "3.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-3.0.0.tgz"
- integrity sha512-WS7qSshQfxoZOpHG/XqlHEGRG1zmyjYrvmATvc4c62+gZXgre1ymYP8ZNgx/3FyZY0TWe9OjFlKOfLqmgOeYwA==
- dependencies:
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- crc-32 "^1.2.0"
+"@nomicfoundation/edr-linux-arm64-gnu@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-gnu/-/edr-linux-arm64-gnu-0.2.1.tgz#8149db0d742157405effe82d485ea9bfefddc795"
+ integrity sha512-NX3G4pBhRitWrjSGY3HTyCq3wKSm5YqrKVOCNQGl9/jcjSovqxlgzFMiTx4YZCzGntfJ/1om9AI84OWxYJjoDw==
-"@nomicfoundation/ethereumjs-ethash@^2.0.0":
- version "2.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-2.0.0.tgz"
- integrity sha512-WpDvnRncfDUuXdsAXlI4lXbqUDOA+adYRQaEezIkxqDkc+LDyYDbd/xairmY98GnQzo1zIqsIL6GB5MoMSJDew==
- dependencies:
- "@nomicfoundation/ethereumjs-block" "^4.0.0"
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- abstract-level "^1.0.3"
- bigint-crypto-utils "^3.0.23"
- ethereum-cryptography "0.1.3"
+"@nomicfoundation/edr-linux-arm64-musl@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-arm64-musl/-/edr-linux-arm64-musl-0.2.1.tgz#7d53afe5607eb406d199a199d00209a6304ff07b"
+ integrity sha512-gdQ3QHkt9XRkdtOGQ8fMwS11MXdjLeZgLrqoial4V4qtMaamIMMhVczK+VEvUhD8p7G4BVmp6kmkvcsthmndmw==
-"@nomicfoundation/ethereumjs-evm@^1.0.0":
- version "1.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-1.0.0.tgz"
- integrity sha512-hVS6qRo3V1PLKCO210UfcEQHvlG7GqR8iFzp0yyjTg2TmJQizcChKgWo8KFsdMw6AyoLgLhHGHw4HdlP8a4i+Q==
- dependencies:
- "@nomicfoundation/ethereumjs-common" "^3.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- "@types/async-eventemitter" "^0.2.1"
- async-eventemitter "^0.2.4"
- debug "^4.3.3"
- ethereum-cryptography "0.1.3"
- mcl-wasm "^0.7.1"
- rustbn.js "~0.2.0"
+"@nomicfoundation/edr-linux-x64-gnu@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-gnu/-/edr-linux-x64-gnu-0.2.1.tgz#b762c95368fcb88bbbabba4d8be5380f38967413"
+ integrity sha512-OqabFY37vji6mYbLD9CvG28lja68czeVw58oWByIhFV3BpBu/cyP1oAbhzk3LieylujabS3Ekpvjw2Tkf0A9RQ==
-"@nomicfoundation/ethereumjs-rlp@^4.0.0", "@nomicfoundation/ethereumjs-rlp@^4.0.0-beta.2":
- version "4.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-4.0.0.tgz"
- integrity sha512-GaSOGk5QbUk4eBP5qFbpXoZoZUj/NrW7MRa0tKY4Ew4c2HAS0GXArEMAamtFrkazp0BO4K5p2ZCG3b2FmbShmw==
+"@nomicfoundation/edr-linux-x64-musl@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-linux-x64-musl/-/edr-linux-x64-musl-0.2.1.tgz#522448c42bff7d2abd52ddcf11ae6ca3dfdd6db4"
+ integrity sha512-vHfFFK2EPISuQUQge+bdjXamb0EUjfl8srYSog1qfiwyLwLeuSbpyyFzDeITAgPpkkFuedTfJW553K0Hipspyg==
-"@nomicfoundation/ethereumjs-statemanager@^1.0.0":
- version "1.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-1.0.0.tgz"
- integrity sha512-jCtqFjcd2QejtuAMjQzbil/4NHf5aAWxUc+CvS0JclQpl+7M0bxMofR2AJdtz+P3u0ke2euhYREDiE7iSO31vQ==
- dependencies:
- "@nomicfoundation/ethereumjs-common" "^3.0.0"
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-trie" "^5.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- debug "^4.3.3"
- ethereum-cryptography "0.1.3"
- functional-red-black-tree "^1.0.1"
+"@nomicfoundation/edr-win32-arm64-msvc@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-arm64-msvc/-/edr-win32-arm64-msvc-0.2.1.tgz#ccfa443c274e49de93016a1060be810096dc6f1d"
+ integrity sha512-K/mui67RCKxghbSyvhvW3rvyVN1pa9M1Q9APUx1PtWjSSdXDFpqEY1NYsv2syb47Ca8ObJwVMF+LvnB6GvhUOQ==
-"@nomicfoundation/ethereumjs-trie@^5.0.0":
- version "5.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-5.0.0.tgz"
- integrity sha512-LIj5XdE+s+t6WSuq/ttegJzZ1vliwg6wlb+Y9f4RlBpuK35B9K02bO7xU+E6Rgg9RGptkWd6TVLdedTI4eNc2A==
- dependencies:
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- ethereum-cryptography "0.1.3"
- readable-stream "^3.6.0"
+"@nomicfoundation/edr-win32-ia32-msvc@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-ia32-msvc/-/edr-win32-ia32-msvc-0.2.1.tgz#822b19d3e67d6dcfa5394cb6a4d55d8bab1b2f26"
+ integrity sha512-HHK0mXEtjvfjJrJlqcYgQCy3lZIXS1KNl2GaP8bwEIuEwx++XxXs/ThLjPepM1nhCGICij8IGy7p3KrkzRelsw==
-"@nomicfoundation/ethereumjs-tx@^4.0.0":
- version "4.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-4.0.0.tgz"
- integrity sha512-Gg3Lir2lNUck43Kp/3x6TfBNwcWC9Z1wYue9Nz3v4xjdcv6oDW9QSMJxqsKw9QEGoBBZ+gqwpW7+F05/rs/g1w==
- dependencies:
- "@nomicfoundation/ethereumjs-common" "^3.0.0"
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- ethereum-cryptography "0.1.3"
+"@nomicfoundation/edr-win32-x64-msvc@0.2.1":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr-win32-x64-msvc/-/edr-win32-x64-msvc-0.2.1.tgz#7b56ff742b2724779cc9f3385815b394f76de8df"
+ integrity sha512-FY4eQJdj1/y8ST0RyQycx63yr+lvdYNnUkzgWf4X+vPH1lOhXae+L2NDcNCQlTDAfQcD6yz0bkBUkLrlJ8pTww==
-"@nomicfoundation/ethereumjs-util@^8.0.0":
- version "8.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-8.0.0.tgz"
- integrity sha512-2emi0NJ/HmTG+CGY58fa+DQuAoroFeSH9gKu9O6JnwTtlzJtgfTixuoOqLEgyyzZVvwfIpRueuePb8TonL1y+A==
- dependencies:
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0-beta.2"
+"@nomicfoundation/edr@^0.2.0":
+ version "0.2.1"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/edr/-/edr-0.2.1.tgz#a3d2a542dcd5dc5a8d757116d52baea05f370531"
+ integrity sha512-Dleau3ItHJh2n85G2J6AIPBoLgu/mOWkmrh26z3VsJE2tp/e00hUk/dqz85ncsVcBYEc6/YOn/DomWu0wSF9tQ==
+ optionalDependencies:
+ "@nomicfoundation/edr-darwin-arm64" "0.2.1"
+ "@nomicfoundation/edr-darwin-x64" "0.2.1"
+ "@nomicfoundation/edr-linux-arm64-gnu" "0.2.1"
+ "@nomicfoundation/edr-linux-arm64-musl" "0.2.1"
+ "@nomicfoundation/edr-linux-x64-gnu" "0.2.1"
+ "@nomicfoundation/edr-linux-x64-musl" "0.2.1"
+ "@nomicfoundation/edr-win32-arm64-msvc" "0.2.1"
+ "@nomicfoundation/edr-win32-ia32-msvc" "0.2.1"
+ "@nomicfoundation/edr-win32-x64-msvc" "0.2.1"
+
+"@nomicfoundation/ethereumjs-common@4.0.4":
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.4.tgz#9901f513af2d4802da87c66d6f255b510bef5acb"
+ integrity sha512-9Rgb658lcWsjiicr5GzNCjI1llow/7r0k50dLL95OJ+6iZJcVbi15r3Y0xh2cIO+zgX0WIHcbzIu6FeQf9KPrg==
+ dependencies:
+ "@nomicfoundation/ethereumjs-util" "9.0.4"
+
+"@nomicfoundation/ethereumjs-rlp@5.0.4":
+ version "5.0.4"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.4.tgz#66c95256fc3c909f6fb18f6a586475fc9762fa30"
+ integrity sha512-8H1S3s8F6QueOc/X92SdrA4RDenpiAEqMg5vJH99kcQaCy/a3Q6fgseo75mgWlbanGJXSlAPtnCeG9jvfTYXlw==
+
+"@nomicfoundation/ethereumjs-tx@5.0.4":
+ version "5.0.4"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.4.tgz#b0ceb58c98cc34367d40a30d255d6315b2f456da"
+ integrity sha512-Xjv8wAKJGMrP1f0n2PeyfFCCojHd7iS3s/Ab7qzF1S64kxZ8Z22LCMynArYsVqiFx6rzYy548HNVEyI+AYN/kw==
+ dependencies:
+ "@nomicfoundation/ethereumjs-common" "4.0.4"
+ "@nomicfoundation/ethereumjs-rlp" "5.0.4"
+ "@nomicfoundation/ethereumjs-util" "9.0.4"
ethereum-cryptography "0.1.3"
-"@nomicfoundation/ethereumjs-vm@^6.0.0":
- version "6.0.0"
- resolved "https://registry.npmjs.org/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-6.0.0.tgz"
- integrity sha512-JMPxvPQ3fzD063Sg3Tp+UdwUkVxMoo1uML6KSzFhMH3hoQi/LMuXBoEHAoW83/vyNS9BxEe6jm6LmT5xdeEJ6w==
- dependencies:
- "@nomicfoundation/ethereumjs-block" "^4.0.0"
- "@nomicfoundation/ethereumjs-blockchain" "^6.0.0"
- "@nomicfoundation/ethereumjs-common" "^3.0.0"
- "@nomicfoundation/ethereumjs-evm" "^1.0.0"
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-statemanager" "^1.0.0"
- "@nomicfoundation/ethereumjs-trie" "^5.0.0"
- "@nomicfoundation/ethereumjs-tx" "^4.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- "@types/async-eventemitter" "^0.2.1"
- async-eventemitter "^0.2.4"
- debug "^4.3.3"
+"@nomicfoundation/ethereumjs-util@9.0.4":
+ version "9.0.4"
+ resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.4.tgz#84c5274e82018b154244c877b76bc049a4ed7b38"
+ integrity sha512-sLOzjnSrlx9Bb9EFNtHzK/FJFsfg2re6bsGqinFinH1gCqVfz9YYlXiMWwDM4C/L4ywuHFCYwfKTVr/QHQcU0Q==
+ dependencies:
+ "@nomicfoundation/ethereumjs-rlp" "5.0.4"
ethereum-cryptography "0.1.3"
- functional-red-black-tree "^1.0.1"
- mcl-wasm "^0.7.1"
- rustbn.js "~0.2.0"
"@nomicfoundation/hardhat-chai-matchers@^1.0.5":
version "1.0.5"
@@ -704,6 +667,11 @@
table "^6.8.0"
undici "^5.4.0"
+"@openzeppelin/contracts@^4.9.3":
+ version "4.9.3"
+ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.9.3.tgz#00d7a8cf35a475b160b3f0293a6403c511099364"
+ integrity sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg==
+
"@rari-capital/solmate@^6.2.0":
version "6.4.0"
resolved "https://registry.npmjs.org/@rari-capital/solmate/-/solmate-6.4.0.tgz"
@@ -853,11 +821,6 @@
dependencies:
fs-extra "^9.1.0"
-"@types/async-eventemitter@^0.2.1":
- version "0.2.1"
- resolved "https://registry.npmjs.org/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz"
- integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg==
-
"@types/bn.js@^4.11.3":
version "4.11.6"
resolved "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz"
@@ -1073,26 +1036,6 @@ abbrev@1, abbrev@1.0.x:
resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz"
integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==
-abort-controller@^3.0.0:
- version "3.0.0"
- resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz"
- integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
- dependencies:
- event-target-shim "^5.0.0"
-
-abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3:
- version "1.0.3"
- resolved "https://registry.npmjs.org/abstract-level/-/abstract-level-1.0.3.tgz"
- integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA==
- dependencies:
- buffer "^6.0.3"
- catering "^2.1.0"
- is-buffer "^2.0.5"
- level-supports "^4.0.0"
- level-transcoder "^1.0.1"
- module-error "^1.0.1"
- queue-microtask "^1.2.3"
-
acorn-jsx@^5.0.0, acorn-jsx@^5.3.2:
version "5.3.2"
resolved "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz"
@@ -1168,6 +1111,13 @@ amdefine@>=0.0.4:
resolved "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz"
integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==
+ansi-align@^3.0.0:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
+ integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==
+ dependencies:
+ string-width "^4.1.0"
+
ansi-colors@3.2.3:
version "3.2.3"
resolved "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz"
@@ -1358,14 +1308,7 @@ astral-regex@^2.0.0:
resolved "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz"
integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==
-async-eventemitter@^0.2.4:
- version "0.2.4"
- resolved "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz"
- integrity sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==
- dependencies:
- async "^2.4.0"
-
-async@1.x, async@>=2.6.4, async@^2.4.0:
+async@1.x, async@>=2.6.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c"
integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==
@@ -1402,11 +1345,6 @@ base-x@^3.0.2:
dependencies:
safe-buffer "^5.0.1"
-base64-js@^1.3.1:
- version "1.5.1"
- resolved "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz"
- integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==
-
bcrypt-pbkdf@^1.0.0:
version "1.0.2"
resolved "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz"
@@ -1419,18 +1357,6 @@ bech32@1.1.4:
resolved "https://registry.npmjs.org/bech32/-/bech32-1.1.4.tgz"
integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==
-bigint-crypto-utils@^3.0.23:
- version "3.1.7"
- resolved "https://registry.npmjs.org/bigint-crypto-utils/-/bigint-crypto-utils-3.1.7.tgz"
- integrity sha512-zpCQpIE2Oy5WIQpjC9iYZf8Uh9QqoS51ZCooAcNvzv1AQ3VWdT52D0ksr1+/faeK8HVIej1bxXcP75YcqH3KPA==
- dependencies:
- bigint-mod-arith "^3.1.0"
-
-bigint-mod-arith@^3.1.0:
- version "3.1.2"
- resolved "https://registry.npmjs.org/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz"
- integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ==
-
bignumber.js@^9.0.1:
version "9.1.1"
resolved "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz"
@@ -1461,6 +1387,20 @@ bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1:
resolved "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz"
integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==
+boxen@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50"
+ integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==
+ dependencies:
+ ansi-align "^3.0.0"
+ camelcase "^6.2.0"
+ chalk "^4.1.0"
+ cli-boxes "^2.2.1"
+ string-width "^4.2.2"
+ type-fest "^0.20.2"
+ widest-line "^3.1.0"
+ wrap-ansi "^7.0.0"
+
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz"
@@ -1480,16 +1420,6 @@ brorand@^1.1.0:
resolved "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz"
integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==
-browser-level@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/browser-level/-/browser-level-1.0.1.tgz"
- integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ==
- dependencies:
- abstract-level "^1.0.2"
- catering "^2.1.1"
- module-error "^1.0.2"
- run-parallel-limit "^1.1.0"
-
browser-stdout@1.3.1:
version "1.3.1"
resolved "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz"
@@ -1538,14 +1468,6 @@ buffer-xor@^1.0.3:
resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9"
integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==
-buffer@^6.0.3:
- version "6.0.3"
- resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6"
- integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==
- dependencies:
- base64-js "^1.3.1"
- ieee754 "^1.2.1"
-
builtins@^5.0.1:
version "5.0.1"
resolved "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz"
@@ -1553,13 +1475,6 @@ builtins@^5.0.1:
dependencies:
semver "^7.0.0"
-busboy@^1.6.0:
- version "1.6.0"
- resolved "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz"
- integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==
- dependencies:
- streamsearch "^1.1.0"
-
bytes@3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz"
@@ -1615,7 +1530,7 @@ callsites@^3.0.0:
resolved "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
-camelcase@^6.0.0:
+camelcase@^6.0.0, camelcase@^6.2.0:
version "6.3.0"
resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
@@ -1625,11 +1540,6 @@ caseless@^0.12.0, caseless@~0.12.0:
resolved "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz"
integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==
-catering@^2.1.0, catering@^2.1.1:
- version "2.1.1"
- resolved "https://registry.npmjs.org/catering/-/catering-2.1.1.tgz"
- integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w==
-
cbor@^8.1.0:
version "8.1.0"
resolved "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz"
@@ -1737,17 +1647,6 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3:
inherits "^2.0.1"
safe-buffer "^5.0.1"
-classic-level@^1.2.0:
- version "1.2.0"
- resolved "https://registry.npmjs.org/classic-level/-/classic-level-1.2.0.tgz"
- integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg==
- dependencies:
- abstract-level "^1.0.2"
- catering "^2.1.0"
- module-error "^1.0.1"
- napi-macros "~2.0.0"
- node-gyp-build "^4.3.0"
-
clean-stack@^2.0.0:
version "2.2.0"
resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz"
@@ -1764,6 +1663,11 @@ cli-barchart@^0.2.3:
string-width "^4.2.3"
term-size "^2.2.1"
+cli-boxes@^2.2.1:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f"
+ integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==
+
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz"
@@ -1943,11 +1847,6 @@ cosmiconfig@^5.0.7:
js-yaml "^3.13.1"
parse-json "^4.0.0"
-crc-32@^1.2.0:
- version "1.2.2"
- resolved "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz"
- integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==
-
create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0:
version "1.2.0"
resolved "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz"
@@ -2037,7 +1936,7 @@ debug@3.2.6:
dependencies:
ms "^2.1.1"
-debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4:
+debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
@@ -2759,11 +2658,6 @@ ethjs-util@0.1.6, ethjs-util@^0.1.6:
is-hex-prefixed "1.0.0"
strip-hex-prefix "1.0.0"
-event-target-shim@^5.0.0:
- version "5.0.1"
- resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz"
- integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
-
evp_bytestokey@^1.0.3:
version "1.0.3"
resolved "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz"
@@ -2942,9 +2836,9 @@ flatted@^3.1.0:
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
follow-redirects@^1.12.1:
- version "1.15.2"
- resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz"
- integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
+ version "1.15.4"
+ resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
+ integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
forever-agent@~0.6.1:
version "0.6.1"
@@ -3074,9 +2968,9 @@ get-caller-file@^2.0.1, get-caller-file@^2.0.5:
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
get-func-name@^2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz"
- integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41"
+ integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==
get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3:
version "1.1.3"
@@ -3301,31 +3195,25 @@ hardhat-gas-reporter@^1.0.7:
eth-gas-reporter "^0.2.25"
sha1 "^1.1.1"
-hardhat@^2.12.1-ir.0:
- version "2.12.1-ir.0"
- resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.12.1-ir.0.tgz#4972a0777e5806cce6b54cf258c52570c58d141a"
- integrity sha512-z5TGBaf3tpY92zcDmifPyYdQa1EGuLAcOlmqQUd0wR93Yua8UCdNyZHk+P2PNBJK4sm/DYt5d3DJbaFMN24sog==
+hardhat@^2.21.0:
+ version "2.21.0"
+ resolved "https://registry.yarnpkg.com/hardhat/-/hardhat-2.21.0.tgz#2e23126310a6c77cd7e149e6af1dd67626b7a74f"
+ integrity sha512-8DlJAVJDEVHaV1sh9FLuKLLgCFv9EAJ+M+8IbjSIPgoeNo3ss5L1HgGBMfnI88c7OzMEZkdcuyGoobFeK3Orqw==
dependencies:
"@ethersproject/abi" "^5.1.2"
"@metamask/eth-sig-util" "^4.0.0"
- "@nomicfoundation/ethereumjs-block" "^4.0.0"
- "@nomicfoundation/ethereumjs-blockchain" "^6.0.0"
- "@nomicfoundation/ethereumjs-common" "^3.0.0"
- "@nomicfoundation/ethereumjs-evm" "^1.0.0"
- "@nomicfoundation/ethereumjs-rlp" "^4.0.0"
- "@nomicfoundation/ethereumjs-statemanager" "^1.0.0"
- "@nomicfoundation/ethereumjs-trie" "^5.0.0"
- "@nomicfoundation/ethereumjs-tx" "^4.0.0"
- "@nomicfoundation/ethereumjs-util" "^8.0.0"
- "@nomicfoundation/ethereumjs-vm" "^6.0.0"
+ "@nomicfoundation/edr" "^0.2.0"
+ "@nomicfoundation/ethereumjs-common" "4.0.4"
+ "@nomicfoundation/ethereumjs-tx" "5.0.4"
+ "@nomicfoundation/ethereumjs-util" "9.0.4"
"@nomicfoundation/solidity-analyzer" "^0.1.0"
"@sentry/node" "^5.18.1"
"@types/bn.js" "^5.1.0"
"@types/lru-cache" "^5.1.0"
- abort-controller "^3.0.0"
adm-zip "^0.4.16"
aggregate-error "^3.0.0"
ansi-escapes "^4.3.0"
+ boxen "^5.1.2"
chalk "^2.4.2"
chokidar "^3.4.0"
ci-info "^2.0.0"
@@ -3345,7 +3233,6 @@ hardhat@^2.12.1-ir.0:
mnemonist "^0.38.0"
mocha "^10.0.0"
p-map "^4.0.0"
- qs "^6.7.0"
raw-body "^2.4.1"
resolve "1.17.0"
semver "^6.3.0"
@@ -3353,7 +3240,7 @@ hardhat@^2.12.1-ir.0:
source-map-support "^0.5.13"
stacktrace-parser "^0.1.10"
tsort "0.0.1"
- undici "^5.4.0"
+ undici "^5.14.0"
uuid "^8.3.2"
ws "^7.4.6"
@@ -3522,11 +3409,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24:
dependencies:
safer-buffer ">= 2.1.2 < 3"
-ieee754@^1.2.1:
- version "1.2.1"
- resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz"
- integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
-
ignore@^4.0.6:
version "4.0.6"
resolved "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz"
@@ -3658,11 +3540,6 @@ is-buffer@^1.1.5:
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-is-buffer@^2.0.5:
- version "2.0.5"
- resolved "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz"
- integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
-
is-callable@^1.1.4, is-callable@^1.2.7:
version "1.2.7"
resolved "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz"
@@ -3994,27 +3871,6 @@ klaw@^1.0.0:
optionalDependencies:
graceful-fs "^4.1.9"
-level-supports@^4.0.0:
- version "4.0.1"
- resolved "https://registry.npmjs.org/level-supports/-/level-supports-4.0.1.tgz"
- integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA==
-
-level-transcoder@^1.0.1:
- version "1.0.1"
- resolved "https://registry.npmjs.org/level-transcoder/-/level-transcoder-1.0.1.tgz"
- integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w==
- dependencies:
- buffer "^6.0.3"
- module-error "^1.0.1"
-
-level@^8.0.0:
- version "8.0.0"
- resolved "https://registry.npmjs.org/level/-/level-8.0.0.tgz"
- integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ==
- dependencies:
- browser-level "^1.0.1"
- classic-level "^1.2.0"
-
levn@^0.3.0, levn@~0.3.0:
version "0.3.0"
resolved "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz"
@@ -4149,13 +4005,6 @@ lowercase-keys@^3.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2"
integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==
-lru-cache@^5.1.1:
- version "5.1.1"
- resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz"
- integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
- dependencies:
- yallist "^3.0.2"
-
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz"
@@ -4178,11 +4027,6 @@ markdown-table@^1.1.3:
resolved "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz"
integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==
-mcl-wasm@^0.7.1:
- version "0.7.9"
- resolved "https://registry.npmjs.org/mcl-wasm/-/mcl-wasm-0.7.9.tgz"
- integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ==
-
md5.js@^1.3.4:
version "1.3.5"
resolved "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz"
@@ -4192,15 +4036,6 @@ md5.js@^1.3.4:
inherits "^2.0.1"
safe-buffer "^5.1.2"
-memory-level@^1.0.0:
- version "1.0.0"
- resolved "https://registry.npmjs.org/memory-level/-/memory-level-1.0.0.tgz"
- integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og==
- dependencies:
- abstract-level "^1.0.0"
- functional-red-black-tree "^1.0.1"
- module-error "^1.0.1"
-
memorystream@^0.3.1:
version "0.3.1"
resolved "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz"
@@ -4427,11 +4262,6 @@ mocha@^7.1.1:
yargs-parser "13.1.2"
yargs-unparser "1.6.0"
-module-error@^1.0.1, module-error@^1.0.2:
- version "1.0.2"
- resolved "https://registry.npmjs.org/module-error/-/module-error-1.0.2.tgz"
- integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA==
-
ms@2.0.0:
version "2.0.0"
resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz"
@@ -4462,11 +4292,6 @@ nanoid@3.3.3:
resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.3.tgz"
integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
-napi-macros@~2.0.0:
- version "2.0.0"
- resolved "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz"
- integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==
-
natural-compare-lite@^1.4.0:
version "1.4.0"
resolved "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz"
@@ -4521,7 +4346,7 @@ node-fetch@2.6.7, node-fetch@>=2.6.7:
fetch-blob "^3.1.4"
formdata-polyfill "^4.0.10"
-node-gyp-build@^4.2.0, node-gyp-build@^4.3.0:
+node-gyp-build@^4.2.0:
version "4.5.0"
resolved "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.5.0.tgz"
integrity sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==
@@ -4920,7 +4745,7 @@ punycode@^2.1.0, punycode@^2.1.1:
resolved "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz"
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
-qs@^6.4.0, qs@^6.7.0:
+qs@^6.4.0:
version "6.11.0"
resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz"
integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==
@@ -4932,7 +4757,7 @@ qs@~6.5.2:
resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz"
integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==
-queue-microtask@^1.2.2, queue-microtask@^1.2.3:
+queue-microtask@^1.2.2:
version "1.2.3"
resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
@@ -5214,13 +5039,6 @@ run-async@^2.2.0:
resolved "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz"
integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==
-run-parallel-limit@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz"
- integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==
- dependencies:
- queue-microtask "^1.2.2"
-
run-parallel@^1.1.9:
version "1.2.0"
resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz"
@@ -5228,11 +5046,6 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
-rustbn.js@~0.2.0:
- version "0.2.0"
- resolved "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz"
- integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==
-
rxjs@^6.4.0:
version "6.6.7"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz"
@@ -5306,6 +5119,37 @@ scuffed-abi@^1.0.4:
resolved "https://registry.npmjs.org/scuffed-abi/-/scuffed-abi-1.0.4.tgz"
integrity sha512-1NN2L1j+TMF6+/J2jHcAnhPH8Lwaqu5dlgknZPqejEVFQ8+cvcnXYNbaHtGEXTjSNrQLBGePXicD4oFGqecOnQ==
+seaport-core@1.6.3:
+ version "1.6.3"
+ resolved "https://registry.yarnpkg.com/seaport-core/-/seaport-core-1.6.3.tgz#f05eb1ceea6b11ab535b22ec1220ae1b7d7d8aa2"
+ integrity sha512-W4tWOg7B7MTcfOhKf3MeMWlY6lmw5h1jr7UnV9LhZIwoGL6Y97lxIEj3uxTWm41bG4Ma05VR6T6hpFPQxQCClA==
+ dependencies:
+ seaport-types "github:ProjectOpenSea/seaport-types#d72955b25b6cf324bbf85ed59aca316f5329eb61"
+
+seaport-core@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/seaport-core/-/seaport-core-0.0.1.tgz#99db0b605d0fbbfd43ca7a4724e64374ce47f6d4"
+ integrity sha512-fgdSIC0ru8xK+fdDfF4bgTFH8ssr6EwbPejC2g/JsWzxy+FvG7JfaX57yn/eIv6hoscgZL87Rm+kANncgwLH3A==
+ dependencies:
+ seaport-types "^0.0.1"
+
+seaport-sol@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/seaport-sol/-/seaport-sol-1.6.0.tgz#2a71ae8da5af9aecffee21767632ef37aaaaee13"
+ integrity sha512-a1FBK1jIeEQXZ9CmQvtmfG0w7CE8nIad89btGg7qrrrtF4j1S0Ilmzpe2Hderap05Uvf3EWS9P/aghDQCNAwkA==
+ dependencies:
+ seaport-core "^0.0.1"
+ seaport-types "^0.0.1"
+
+seaport-types@^0.0.1:
+ version "0.0.1"
+ resolved "https://registry.yarnpkg.com/seaport-types/-/seaport-types-0.0.1.tgz#e2a32fe8641853d7dadb1b0232d911d88ccc3f1a"
+ integrity sha512-m7MLa7sq3YPwojxXiVvoX1PM9iNVtQIn7AdEtBnKTwgxPfGRWUlbs/oMgetpjT/ZYTmv3X5/BghOcstWYvKqRA==
+
+"seaport-types@github:ProjectOpenSea/seaport-types#d72955b25b6cf324bbf85ed59aca316f5329eb61":
+ version "1.6.0"
+ resolved "https://codeload.github.com/ProjectOpenSea/seaport-types/tar.gz/d72955b25b6cf324bbf85ed59aca316f5329eb61"
+
secp256k1@^4.0.1:
version "4.0.3"
resolved "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.3.tgz"
@@ -5316,19 +5160,19 @@ secp256k1@^4.0.1:
node-gyp-build "^4.2.0"
semver@^5.5.0, semver@^5.5.1, semver@^5.7.0:
- version "5.7.1"
- resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz"
- integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
+ version "5.7.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
+ integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
semver@^6.3.0:
- version "6.3.0"
- resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz"
- integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
+ version "6.3.1"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4"
+ integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
semver@^7.0.0, semver@^7.3.4, semver@^7.3.7, semver@^7.3.8:
- version "7.3.8"
- resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz"
- integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==
+ version "7.5.4"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e"
+ integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==
dependencies:
lru-cache "^6.0.0"
@@ -5606,11 +5450,6 @@ stealthy-require@^1.1.1:
resolved "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz"
integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g==
-streamsearch@^1.1.0:
- version "1.1.0"
- resolved "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz"
- integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
-
string-argv@^0.3.1:
version "0.3.1"
resolved "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz"
@@ -5638,7 +5477,7 @@ string-width@^3.0.0, string-width@^3.1.0:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^5.1.0"
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -6084,12 +5923,12 @@ underscore@>=1.12.1:
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441"
integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==
-undici@>=5.8.2, undici@^5.4.0:
- version "5.20.0"
- resolved "https://registry.yarnpkg.com/undici/-/undici-5.20.0.tgz#6327462f5ce1d3646bcdac99da7317f455bcc263"
- integrity sha512-J3j60dYzuo6Eevbawwp1sdg16k5Tf768bxYK4TUJRH7cBM4kFCbf3mOnM/0E3vQYXvpxITbbWmBafaDbxLDz3g==
+undici@>=5.8.2, undici@^5.14.0, undici@^5.4.0:
+ version "5.26.3"
+ resolved "https://registry.yarnpkg.com/undici/-/undici-5.26.3.tgz#ab3527b3d5bb25b12f898dfd22165d472dd71b79"
+ integrity sha512-H7n2zmKEWgOllKkIUkLvFmsJQj062lSm3uA4EYApG8gLuiOM0/go9bIoC3HVaSnfg4xunowDE2i9p8drkXuvDw==
dependencies:
- busboy "^1.6.0"
+ "@fastify/busboy" "^2.0.0"
universalify@^0.1.0:
version "0.1.2"
@@ -6207,10 +6046,17 @@ wide-align@1.1.3:
dependencies:
string-width "^1.0.2 || 2"
+widest-line@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca"
+ integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==
+ dependencies:
+ string-width "^4.0.0"
+
word-wrap@^1.2.3, word-wrap@~1.2.3:
- version "1.2.3"
- resolved "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz"
- integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.4.tgz#cb4b50ec9aca570abd1f52f33cd45b6c61739a9f"
+ integrity sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==
wordwrap@^1.0.0:
version "1.0.0"
@@ -6289,11 +6135,6 @@ y18n@^5.0.5:
resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz"
integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==
-yallist@^3.0.2:
- version "3.1.1"
- resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz"
- integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
-
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz"