From daa0494518da460b8664fcc5979c7e36cc0fdaaa Mon Sep 17 00:00:00 2001 From: Liam Freeman Date: Wed, 23 Mar 2022 09:00:53 +0000 Subject: [PATCH 1/7] gated creation script failing on minter role for artist address --- hardhat.config.js | 2 +- package-lock.json | 46 ++- package.json | 8 +- .../merkle-and-ipfs/in/ko-staff-list.json | 21 ++ .../data/merkle-and-ipfs/out/ko-merkle.json | 210 +++++++++++++ .../x_setup_gated_sale_with_phases.js | 278 ++++++++++++------ 6 files changed, 463 insertions(+), 102 deletions(-) create mode 100644 scripts/data/merkle-and-ipfs/in/ko-staff-list.json create mode 100644 scripts/data/merkle-and-ipfs/out/ko-merkle.json diff --git a/hardhat.config.js b/hardhat.config.js index 9126155f..c350bbca 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -5,7 +5,7 @@ require('hardhat-contract-sizer') require('hardhat-abi-exporter'); require('@nomiclabs/hardhat-solhint'); require("@nomiclabs/hardhat-etherscan"); -require('@openzeppelin/hardhat-upgrades') +require('@openzeppelin/hardhat-upgrades'); require("@nomiclabs/hardhat-truffle5"); const INFURA_PROJECT_ID = process.env.INFURA_PROJECT_ID; diff --git a/package-lock.json b/package-lock.json index 1c7d09fd..2a3c81d3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2752,13 +2752,14 @@ "integrity": "sha512-bavxs18L47EmcdnL9I6DzsVSUJO+0/zD6zH7/6qG7QRBugvR3VNVZR+nMvuZlCNwuTTnCa3apR00PYzYr/efAw==" }, "@openzeppelin/hardhat-upgrades": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.14.0.tgz", - "integrity": "sha512-dWLC+cgawHcZ5AbEblA3nTrBpcG9J7Z7J5UmM7qdsc/Yc97USJjXfcD6uYOQ+PhyFVBY0Ni83WGVll48d4QRWQ==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/hardhat-upgrades/-/hardhat-upgrades-1.16.1.tgz", + "integrity": "sha512-vSlOCi3n9MGex3F+Qs+0WZJx2d2sg1rhWQ6FbHAybfQH7wngQn4INv1m3JZZpmerkOAoHi1Cdv4GOGLmxFnWYQ==", "dev": true, "requires": { - "@openzeppelin/upgrades-core": "^1.12.0", - "chalk": "^4.1.0" + "@openzeppelin/upgrades-core": "^1.13.1", + "chalk": "^4.1.0", + "proper-lockfile": "^4.1.1" }, "dependencies": { "ansi-styles": { @@ -2831,9 +2832,9 @@ } }, "@openzeppelin/upgrades-core": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.12.0.tgz", - "integrity": "sha512-gu/ijQW+RJqGlniNkpNmiwBus3R1cuJNT0/MEJASWRFNr4Qvn0d7LZONaAkhnvlBpxdiiPenMcFIrRlwvZL4iw==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@openzeppelin/upgrades-core/-/upgrades-core-1.14.1.tgz", + "integrity": "sha512-iKlh1mbUxyfdjdEiUFyhMkqirfas+DMUu7ED53nZbHEyhcYsm+5Fl/g0Bv6bZA+a7k8kO8+22DNEKsqaDUBc2Q==", "dev": true, "requires": { "bn.js": "^5.1.2", @@ -4419,12 +4420,20 @@ "dev": true }, "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "version": "0.21.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz", + "integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==", "dev": true, "requires": { - "follow-redirects": "^1.10.0" + "follow-redirects": "^1.14.0" + }, + "dependencies": { + "follow-redirects": { + "version": "1.14.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", + "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "dev": true + } } }, "balanced-match": { @@ -16357,7 +16366,7 @@ } }, "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#1a27c59c15ab1e95ee8e5c4ed6ad814c49cc439e", + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#ee3994657fa7a427238e6ba92a84d0b529bbcde0", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "dev": true, "requires": { @@ -19709,6 +19718,11 @@ "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==", "dev": true }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, "ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -21369,9 +21383,9 @@ } }, "solidity-ast": { - "version": "0.4.30", - "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.30.tgz", - "integrity": "sha512-3xsQIbZEPx6w7+sQokuOvk1RkMb5GIpuK0GblQDIH6IAkU4+uyJQVJIRNP+8KwhzkViwRKq0hS4zLqQNLKpxOA==", + "version": "0.4.31", + "resolved": "https://registry.npmjs.org/solidity-ast/-/solidity-ast-0.4.31.tgz", + "integrity": "sha512-kX6o4XE4ihaqENuRRTMJfwQNHoqWusPENZUlX4oVb19gQdfi7IswFWnThONHSW/61umgfWdKtCBgW45iuOTryQ==", "dev": true }, "solidity-coverage": { diff --git a/package.json b/package.json index 76e1a37b..3b176081 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,9 @@ "compile": "npx hardhat compile --show-stack-traces", "coverage": "NODE_OPTIONS=--max-old-space-size=4096 npx hardhat coverage", "test": "npx hardhat test --parallel", + "clean": "rm -rf artifacts/ && rm -rf cache/", + "clean-node-modules": "rm -rf node_modules/", + "clean-test": "npm run clean && npm run compile && npm run test", "contract-size": "npx hardhat size-contracts", "gas": "REPORT_GAS=true npx hardhat test" }, @@ -20,10 +23,10 @@ "@nomiclabs/hardhat-solhint": "2.0.0", "@nomiclabs/hardhat-truffle5": "2.0.4", "@nomiclabs/hardhat-web3": "^2.0.0", - "@openzeppelin/hardhat-upgrades": "1.14.0", + "@openzeppelin/hardhat-upgrades": "^1.16.1", "@openzeppelin/test-helpers": "0.5.15", "@pinata/sdk": "^1.1.23", - "axios": "^0.21.1", + "axios": "^0.21.4", "chai": "^4.3.0", "commander": "^7.0.0", "dotenv": "^8.2.0", @@ -42,6 +45,7 @@ "@openzeppelin/contracts": "4.2.0", "@openzeppelin/contracts-upgradeable": "^4.4.2", "hardhat-contract-sizer": "^2.0.3", + "moment": "^2.29.1", "prompt-sync": "^4.2.0" } } diff --git a/scripts/data/merkle-and-ipfs/in/ko-staff-list.json b/scripts/data/merkle-and-ipfs/in/ko-staff-list.json new file mode 100644 index 00000000..6b386b11 --- /dev/null +++ b/scripts/data/merkle-and-ipfs/in/ko-staff-list.json @@ -0,0 +1,21 @@ +{ + "0x0f48669B1681D41357EAc232F516B77D0c10F0F1": 1, + "0x7DEc37c03ea5ca2C47ad2509BE6abAf8C63CDB39": 1, + "0x401cBf2194D35D078c0BcdAe4BeA42275483ab5F": 1, + "0xd9c575163C3fC0948490b02cCe19aCf8D9eC8427": 1, + "0x0b6Fa76a74fb44a1F6e62AC952cd6B1905C1Feb8": 1, + "0x5f8429d70c0b9e18622daafad4e8938073a09322": 1, + "0x70482d3BD44fbEF402a0CEE6D9BeA516d12bE128": 1, + "0x88157aCff3FAfD9696D7CA005291fB0b6e4dc833": 1, + "0x93B63028Dd964318Ce6C8c0437Be0097F35bc366": 1, + "0xe27dc3aa4352244dd8baab17e8813339456f8a2c": 1, + "0x681A7040477Be268A4b9A02c5e8263fd9fEbf0a9": 1, + "0xd514f2065fde42a02c73c913735E8E5a2FcC085E": 1, + "0x2ac0b77652cfb7ebde8190d7c3e1a41e18dcc66f": 1, + "0xD84708b4d3c9a3B26c22C62511236190C5a30e8c": 1, + "0xf7C088582dcd4B2CA1e629de63699034D2cE7880": 1, + "0x5770fFaF8c51E6F7728B36BcC46794107c56641a": 1, + "0x3507d8cB9bD241b6dC37Be87c8a30bF8d112fB4A": 1, + "0xFc8e2EA4f20E08b6124FDEb6813561349BC1F599": 1, + "0x5c9a5964c7C85c15C87854b0938a94f99485AA46": 1 +} diff --git a/scripts/data/merkle-and-ipfs/out/ko-merkle.json b/scripts/data/merkle-and-ipfs/out/ko-merkle.json new file mode 100644 index 00000000..a3849a94 --- /dev/null +++ b/scripts/data/merkle-and-ipfs/out/ko-merkle.json @@ -0,0 +1,210 @@ +{ + "generateMerkleProofs": { + "merkleRoot": "0x48f5f6ffa48cab857824eee299f8585244a47fcd26a66f57ebc2ac1c8e370297", + "tokenTotal": "0x13", + "claims": { + "0x0b6Fa76a74fb44a1F6e62AC952cd6B1905C1Feb8": { + "index": 0, + "amount": "0x01", + "proof": [ + "0xd18e31c32b345478a3dadef6202e677c808b8d327bf206b0e3a0b79de18da287", + "0x939977d3bdbc92fa58e356e3465d2a01b059c4d1d8d448aeaaabea487466d510", + "0x22e0263b6b89c154b32e6ba58e1eb32c9f0b6211bb550420021c9a757c4a31c9", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x0f48669B1681D41357EAc232F516B77D0c10F0F1": { + "index": 1, + "amount": "0x01", + "proof": [ + "0x20e0c760447da478ed21290562792dc56b48bb31c9495bd9babf9590b42f739b", + "0x31c3ecdc8a96156878c6d1b6e25f3c1e598c8a0dedeb328764098f9a7eaf5d12", + "0x689c7ba9846d3e77970a3efa5d644519ea770bed9691636daace62e4244c1daa", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x2AC0B77652cfb7ebdE8190d7c3E1a41E18dCc66f": { + "index": 2, + "amount": "0x01", + "proof": [ + "0x32da3f738526859f9b5c101f83373ff4a44b88ffb20b44dca81eed815acda9a2", + "0x31c3ecdc8a96156878c6d1b6e25f3c1e598c8a0dedeb328764098f9a7eaf5d12", + "0x689c7ba9846d3e77970a3efa5d644519ea770bed9691636daace62e4244c1daa", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x3507d8cB9bD241b6dC37Be87c8a30bF8d112fB4A": { + "index": 3, + "amount": "0x01", + "proof": [ + "0x9f2a83e73face6956849108e376d62d1336b48be3cfb9b3afdeec50a9dad1c5f", + "0xacea1b3e069509e3309d60fcb6a6b10ec5cbe9d7a5a2ee8e5ced4a6c9e1174bf", + "0x22e0263b6b89c154b32e6ba58e1eb32c9f0b6211bb550420021c9a757c4a31c9", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x401cBf2194D35D078c0BcdAe4BeA42275483ab5F": { + "index": 4, + "amount": "0x01", + "proof": [ + "0x44b61e4a3f92400481c473c4de5a4aa577b3de6e88d4a943acd632aae61c66cc", + "0xbc54e7bbe9557d3814e31d2cd172bde1e0b79c5be4df30ca89d4daaa38b984a7", + "0x689c7ba9846d3e77970a3efa5d644519ea770bed9691636daace62e4244c1daa", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x5770fFaF8c51E6F7728B36BcC46794107c56641a": { + "index": 5, + "amount": "0x01", + "proof": [ + "0x207d7c9ecf122727679d051577eed23c069ec8adc9d98ff8c1078824496ba416", + "0x02e08c7ed0827ebcb27bf6eedb4c5d6eaed7c7ccc5cc3bff7346ce939a479433", + "0xef3e188be48472229eb3622a3f77d88d03b3620ddda48812c5754fb71bb560dd", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x5F8429d70c0B9e18622DAafAd4e8938073a09322": { + "index": 6, + "amount": "0x01", + "proof": [ + "0x621d0219a4fd6f69a1387ce281330c6e56b42f0a2439c3ed8d58dcfb8ecef247", + "0xedfab723d2db17c400aadbd8763725884353bb10d205260039fe2e1acb6e4baa", + "0x621df1bc34e33be295591e7cafdc4c3a84291509d7c21843281d059e52c0d553", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x5c9a5964c7C85c15C87854b0938a94f99485AA46": { + "index": 7, + "amount": "0x01", + "proof": [ + "0x8275e21cd47933bb718bffbdf2f88dabc7b717b5827d64731f87e821de6f4ef4", + "0x1a3db094f7de64c3dfe4dedd0360b7266a837ad16e6fb99fac67ecc066980657", + "0x621df1bc34e33be295591e7cafdc4c3a84291509d7c21843281d059e52c0d553", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x681A7040477Be268A4b9A02c5e8263fd9fEbf0a9": { + "index": 8, + "amount": "0x01", + "proof": [ + "0xe38b57fe87e939db5bdf0271ff92e6b2649806af68f1f8520422877e42a88685", + "0xfe7ea77620572d769ffb7d06cae4a9e9cba69cbe414359c3d842796e8488ad63", + "0x816fcb90778d16efdcf5dbbf8d16f6ccbc55a67698178474219b8de19aa134f0" + ] + }, + "0x70482d3BD44fbEF402a0CEE6D9BeA516d12bE128": { + "index": 9, + "amount": "0x01", + "proof": [ + "0x06580fa4b164f4a5cde7cd6f52c8214ecaa9ce00f3354b5012defce2e9d6d110", + "0x0da5bed0ed10480b1f9409585b066664609fd1a7ab0395fa316df787bd246bb8", + "0xef3e188be48472229eb3622a3f77d88d03b3620ddda48812c5754fb71bb560dd", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x7DEc37c03ea5ca2C47ad2509BE6abAf8C63CDB39": { + "index": 10, + "amount": "0x01", + "proof": [ + "0x6b7f18931435bd2c2ab917f40057b7edba50c6090a78efa252df57391a304c89", + "0x1a3db094f7de64c3dfe4dedd0360b7266a837ad16e6fb99fac67ecc066980657", + "0x621df1bc34e33be295591e7cafdc4c3a84291509d7c21843281d059e52c0d553", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x88157aCff3FAfD9696D7CA005291fB0b6e4dc833": { + "index": 11, + "amount": "0x01", + "proof": [ + "0xc3212357459a52c591070681f656ad0d764363bb27af7bd41f21340eadcde95a", + "0x939977d3bdbc92fa58e356e3465d2a01b059c4d1d8d448aeaaabea487466d510", + "0x22e0263b6b89c154b32e6ba58e1eb32c9f0b6211bb550420021c9a757c4a31c9", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0x93B63028Dd964318Ce6C8c0437Be0097F35bc366": { + "index": 12, + "amount": "0x01", + "proof": [ + "0x11c720926087f5963d61d24d2c065c7a272957c944a99cbe498ea62ac188216c", + "0x02e08c7ed0827ebcb27bf6eedb4c5d6eaed7c7ccc5cc3bff7346ce939a479433", + "0xef3e188be48472229eb3622a3f77d88d03b3620ddda48812c5754fb71bb560dd", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0xD84708b4d3c9a3B26c22C62511236190C5a30e8c": { + "index": 13, + "amount": "0x01", + "proof": [ + "0x49e20fc4ac967531a4036bd224b71e6268d5b20a40894b245b7edbcc9df33e7e", + "0x816fcb90778d16efdcf5dbbf8d16f6ccbc55a67698178474219b8de19aa134f0" + ] + }, + "0xE27Dc3AA4352244Dd8bAAB17e8813339456f8a2C": { + "index": 14, + "amount": "0x01", + "proof": [ + "0xbc1268fc5aa2ccd560e8c801c0688f4658646a84d6453736d092c0d2e34a7eb9", + "0xacea1b3e069509e3309d60fcb6a6b10ec5cbe9d7a5a2ee8e5ced4a6c9e1174bf", + "0x22e0263b6b89c154b32e6ba58e1eb32c9f0b6211bb550420021c9a757c4a31c9", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0xFc8e2EA4f20E08b6124FDEb6813561349BC1F599": { + "index": 15, + "amount": "0x01", + "proof": [ + "0x09942ed963a21c9b0265cd11ac3266294e4800fc1cfd7351014eb8cf2109f969", + "0x0da5bed0ed10480b1f9409585b066664609fd1a7ab0395fa316df787bd246bb8", + "0xef3e188be48472229eb3622a3f77d88d03b3620ddda48812c5754fb71bb560dd", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0xd514f2065fde42a02c73c913735E8E5a2FcC085E": { + "index": 16, + "amount": "0x01", + "proof": [ + "0xf1bb4f979f1d42947b797aed870a13661690a9be8832e31246ba2a47829dd0da", + "0xfe7ea77620572d769ffb7d06cae4a9e9cba69cbe414359c3d842796e8488ad63", + "0x816fcb90778d16efdcf5dbbf8d16f6ccbc55a67698178474219b8de19aa134f0" + ] + }, + "0xd9c575163C3fC0948490b02cCe19aCf8D9eC8427": { + "index": 17, + "amount": "0x01", + "proof": [ + "0x64127c57c54f8f135bf194be08ea08b0f97c8f7664f3d27571ba5c25bddc9f0a", + "0xedfab723d2db17c400aadbd8763725884353bb10d205260039fe2e1acb6e4baa", + "0x621df1bc34e33be295591e7cafdc4c3a84291509d7c21843281d059e52c0d553", + "0x8d1a46501113e815c31ea090fa3dabdd3e99c301ef0168b93c79a56039abbf58", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + }, + "0xf7C088582dcd4B2CA1e629de63699034D2cE7880": { + "index": 18, + "amount": "0x01", + "proof": [ + "0x6077039788d8b7dc9caa605a10429708170e190d107d692583abec5defcaba14", + "0xbc54e7bbe9557d3814e31d2cd172bde1e0b79c5be4df30ca89d4daaa38b984a7", + "0x689c7ba9846d3e77970a3efa5d644519ea770bed9691636daace62e4244c1daa", + "0xdf6d7d77c260d7c80d36132db0461f8f5ee70b2df1bf836ecf43cecabb53b03f", + "0x0e1807c4e48c7285b0c465303f4d801e422ddecb98ebeee5b885c187624d9c08" + ] + } + } + } +} \ No newline at end of file diff --git a/scripts/scratch-pad/x_setup_gated_sale_with_phases.js b/scripts/scratch-pad/x_setup_gated_sale_with_phases.js index 3b4a7c8b..cfa5083e 100644 --- a/scripts/scratch-pad/x_setup_gated_sale_with_phases.js +++ b/scripts/scratch-pad/x_setup_gated_sale_with_phases.js @@ -1,92 +1,204 @@ const prompt = require('prompt-sync')(); const hre = require('hardhat'); -const {ethers, upgrades} = hre; +const {ethers} = hre; +const {BigNumber} = ethers; +const moment = require('moment') + +const fs = require('fs'); +const _ = require('lodash'); +const path = require('path') +const axios = require('axios') + +const pinataSDK = require('@pinata/sdk'); +const pinata = pinataSDK(process.env.KO_PINATA_API_KEY, process.env.KO_PINATA_API_SECRET); +const {parseBalanceMap} = require('../../test/utils/parse-balance-map'); + +const MintingFactoryV2 = require('../../artifacts/contracts/minter/MintingFactoryV2.sol/MintingFactoryV2.json'); const KODAV3UpgradableGatedMarketplace = require('../../artifacts/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol/KODAV3UpgradableGatedMarketplace.json'); +const _6_MONTHS = 15780000; +const TOKEN_URI = 'ipfs://ipfs/Qmd9xQFBfqMZLG7RA2rXor7SA7qyJ1Pk2F2mSYzRQ2siMv'; + +async function createMerkle(inFileName, outFileName, artistAddress) { + try { + + if(!inFileName || !outFileName || !artistAddress) { + throw new Error('missing input variables for createMerkle') + } + + const merkleConfig = JSON.parse(fs.readFileSync(path.resolve(__dirname, `../data/merkle-and-ipfs/in/${inFileName}`))); + const merkleTree = parseBalanceMap(merkleConfig); + + const totalAddresses = parseInt(ethers.utils.formatUnits(merkleTree.tokenTotal, 'wei')); + + console.log(` + Generated merkle root: ${merkleTree.merkleRoot} + + Total: ${totalAddresses} + `); + + fs.writeFileSync(path.resolve(__dirname, `../data/merkle-and-ipfs/out/${outFileName}`), JSON.stringify({ + generateMerkleProofs: merkleTree + }, null, 2)); + + console.log(` +Results written to ../data/merkle-and-ipfs/out/${outFileName} + `); + + const results = await pinata.pinFileToIPFS(fs.createReadStream(path.resolve(__dirname, `../data/merkle-and-ipfs/out/${outFileName}`))); + console.log(`Pinning IPFS hash with proofs ${results.IpfsHash}`); + + return { + merkleRoot: merkleTree.merkleRoot, + ipfsHash: results.IpfsHash, + artistIndex: merkleTree.claims[artistAddress].index, + artistProof: merkleTree.claims[artistAddress].proof + } + } catch (err) { + console.error(err) + throw err + } +} + +async function getEditionId(contract, web3, tx) { + try { + await tx.wait(1) + + const txReceipt = await web3.getTransactionReceipt(tx.hash); + + const results = await contract.queryFilter( + state.mintingFactory.interface.events['EditionMintedAndListed(uint256, SaleType);'], + txReceipt.blockNumber, + txReceipt.blockNumber + ); + + return results[0].args._editionId + + } catch (err) { + console.error(err) + throw err + } +} + +async function getMerkleApiDetails(network, address) { + network = network === 'rinkeby' ? 4 : 1 + let url = `https://us-central1-known-origin-io.cloudfunctions.net/main/api/network/${network}/merklevault/metadata/${address}` + + let res = await axios({ + method: 'get', + url + }) + + return { + index: res.data.merkleProofAndIndex.index, + proof: res.data.merkleProofAndIndex.proof + } + +} + async function main() { - const [deployer] = await ethers.getSigners(); - console.log('Signer account:', await deployer.getAddress()); - const {name: network} = hre.network; - console.log(`Running on network [${network}]`); - - const kodaV3GatedMarketplaceAddress = prompt('KodaV3GatedMarketplaceAddress address? '); - const kodaV3GatedMarketplaceDeployment = new ethers.Contract( - kodaV3GatedMarketplaceAddress, - KODAV3UpgradableGatedMarketplace.abi, - deployer - ); - prompt(`Found Gated marketplace [${kodaV3GatedMarketplaceDeployment.address}] for network [${network}] - click enter to continue ... ?`); - - const _6_MONTHS = 15780000; - - ///////////// - // PHASE 1 // - ///////////// - - // Tuesday 1st March - // MASTER WORK 1 x 1 - reserve auction - // (rinkeby) 329000 - - // T+/- SERIES 1 - 1x5 - // (rinkeby) 330000 (this is edition of 25) - - // T+/- SERIES 2 - 1x5 - // T+/- SERIES 3 - 1x5 - // T+/- SERIES 4 - 1x5 - // T+/- SERIES 5 - 1x5 - - // const PHASE_1_1 = { - // editionId: '330000', - // startTime: 1645542000, - // endTime: 1645542000 + _6_MONTHS, // TODO confirm end time - // walletMintLimits: '2', - // merkleRoots: '0x0f5201869424745eea087a0123e8eb29c2754e14655ebbc05fb48177852cedb5', - // merkleIPFSHashes: 'QmbiUuNAi6DfJrQcnzpJBvQNkRAbkdB8JyVgPLka1dkeMv', - // pricesInWei: '100000000000000000', - // mintCaps: '25', - // }; - // - // const phase1Txs = await kodaV3GatedMarketplaceDeployment.createSaleWithPhases( - // PHASE_1_1.editionId, - // [PHASE_1_1.startTime], - // [PHASE_1_1.endTime], - // [PHASE_1_1.walletMintLimits], - // [PHASE_1_1.merkleRoots], - // [PHASE_1_1.merkleIPFSHashes], - // [PHASE_1_1.pricesInWei], - // [PHASE_1_1.mintCaps] - // ); - // console.log('Phase 1 TXS', phase1Txs); - - // TELEMETRY DATA PAINTINGS 1 x 100 - // (rinkeby) 331000 - - // const PHASE_1_2 = { - // editionId: 331000, - // startTime: 1645542000, - // endTime: 1645542000 + _6_MONTHS, // TODO confirm end time - // walletMintLimits: '3', - // merkleRoots: '0x0f5201869424745eea087a0123e8eb29c2754e14655ebbc05fb48177852cedb5', - // merkleIPFSHashes: 'QmbiUuNAi6DfJrQcnzpJBvQNkRAbkdB8JyVgPLka1dkeMv', - // pricesInWei: '100000000000000000', - // mintCaps: '100', - // }; - // - // const phase2Txs = await kodaV3GatedMarketplaceDeployment.createSaleWithPhases( - // PHASE_1_2.editionId, - // [PHASE_1_2.startTime], - // [PHASE_1_2.endTime], - // [PHASE_1_2.walletMintLimits], - // [PHASE_1_2.merkleRoots], - // [PHASE_1_2.merkleIPFSHashes], - // [PHASE_1_2.pricesInWei], - // [PHASE_1_2.mintCaps] - // ); - - console.log('Phase 2 TXS', phase2Txs); - - console.log('Finished!'); + try { + const rootTime = moment() + + console.log(`Starting process at ${rootTime.unix()}`) + + const [deployer] = await ethers.getSigners(); + console.log('Signer account:', await deployer.getAddress()); + const {name: network} = hre.network; + console.log(`Running on network [${network}]`); + + const web3 = new ethers.getDefaultProvider(`${network}`); + + // STEP 1 - get the contracts + const mintingFactoryV2Address = prompt('MintingFactoryV2Address address? ', '0x32f43177CB70EB482cFD5DD1f3D48A760241A36F'); + const mintingFactoryDeployment = new ethers.Contract( + mintingFactoryV2Address, + MintingFactoryV2.abi, + deployer + ) + prompt(`Found Minting Factory V2 [${mintingFactoryDeployment.address}] for network [${network}] - click enter to continue ... ?`); + + const kodaV3GatedMarketplaceAddress = prompt('KodaV3GatedMarketplaceAddress address? ', '0xB3563C45E45714d9B1a61171c0774a6deb07123D'); + const kodaV3GatedMarketplaceDeployment = new ethers.Contract( + kodaV3GatedMarketplaceAddress, + KODAV3UpgradableGatedMarketplace.abi, + deployer + ); + prompt(`Found Gated marketplace [${kodaV3GatedMarketplaceDeployment.address}] for network [${network}] - click enter to continue ... ?`); + + // STEP 2 - generate a merkle tree + const merkleInFileName = prompt('File Name for merkle tree addresses - IN file? ', 'ko-staff-list.json') + const merkleOutFileName = prompt('File Name for generated merkle tree - OUT file? ', 'ko-merkle.json') + const merkleArtistAddress = prompt('Artist address for merkle tree? ', '0x681A7040477Be268A4b9A02c5e8263fd9fEbf0a9') + + console.log('Artist Address : ', merkleArtistAddress) + + let merkleTree = await createMerkle(merkleInFileName, merkleOutFileName, merkleArtistAddress) + let artistMerkleInfo = await getMerkleApiDetails(network, merkleArtistAddress) + + console.log( + `Merkle generated and merkle artist information extracted: + + MerkleRoot: ${merkleTree.merkleRoot}, + IPFSHash: ${merkleTree.ipfsHash}, + `) + + console.log('ARTIST MERKLE INFO : ', merkleArtistAddress, artistMerkleInfo.index, artistMerkleInfo.proof) + + const batchEditionSize = prompt('Edition size for batch edition? ', 100) + const publicStartDate = prompt('Start date for public sale? ', rootTime.add(1, 'd').unix()) + const publicPrice = prompt('Price for public sale in eth? ', '0.2') + + // const mintEstimateGas = await mintingFactoryDeployment.connect(merkleArtistAddress.toLowerCase()).estimateGas.mintBatchEditionGatedAndPublic( + // batchEditionSize, + // publicStartDate, + // ethers.utils.parseEther(publicPrice).toString(), + // artistMerkleInfo.index, + // artistMerkleInfo.proof, + // ethers.constants.AddressZero, + // TOKEN_URI, + // ) + + const mintTx = await mintingFactoryDeployment.connect(merkleArtistAddress).mintBatchEditionGatedAndPublic( + batchEditionSize, + publicStartDate, + ethers.utils.parseEther(publicPrice).toString(), + artistMerkleInfo.index, + artistMerkleInfo.proof, + ethers.constants.AddressZero, + TOKEN_URI, + // {gasLimit: mintEstimateGas.add(10000)} + ) + + console.log(`Mint transaction: ${mintTx}`) + // + // const editionID = await getEditionId(web3, mintTx) + // + // console.log(`Edition ID extracted: ${editionID}`) + // + // const phaseStartDate = prompt('Start date for phase? ', rootTime.add(time.duration.hours(1))) + // const phasePrice = prompt('Price for phase? ', ether('0.1').toString()) + // const phaseTotalMintCap = prompt('Total mint cap for phase? ', Math.floor(batchEditionSize / 2)) + // const phaseWalletMintCap = prompt('Wallet mint cap for phase? ', 1) + // + // const phaseTx = await kodaV3GatedMarketplaceDeployment.createPhase( + // editionID.toString(), + // phaseStartDate, + // publicStartDate, + // phasePrice, + // phaseTotalMintCap, + // phaseWalletMintCap, + // merkleInfo.merkleRoot, + // merkleInfo.ipfsHash + // ) + // + // console.log(`Phase transaction: ${phaseTx}`) + // + // console.log('Finished!'); + } catch (err) { + console.error('ERROR ! : ', err) + } } main() From 63de86900ccca328fb4cbb2ab59953199c4dccc8 Mon Sep 17 00:00:00 2001 From: James Morgan Date: Wed, 23 Mar 2022 14:26:14 +0000 Subject: [PATCH 2/7] Adding more tests --- .../KODAV3UpgradableGatedMarketplace.sol | 16 +++--- .../KODAV3GatedMarketplace.complex.test.js | 52 +++++++++++++++++++ 2 files changed, 60 insertions(+), 8 deletions(-) diff --git a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol index 3836b716..9dea07a4 100644 --- a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol +++ b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol @@ -363,14 +363,14 @@ contract KODAV3UpgradableGatedMarketplace is IKODAV3GatedMarketplace, BaseUpgrad // Add the phase to the phases mapping phases[_saleId].push(Phase({ - startTime : _startTime, - endTime : _endTime, - priceInWei : _priceInWei, - mintCounter : 0, - mintCap : _mintCap, - walletMintLimit : _walletMintLimit, - merkleRoot : _merkleRoot, - merkleIPFSHash : _merkleIPFSHash + startTime : _startTime, + endTime : _endTime, + priceInWei : _priceInWei, + mintCounter : 0, + mintCap : _mintCap, + walletMintLimit : _walletMintLimit, + merkleRoot : _merkleRoot, + merkleIPFSHash : _merkleIPFSHash })); emit PhaseCreated(_saleId, phases[_saleId].length - 1); diff --git a/test/marketplace/KODAV3GatedMarketplace.complex.test.js b/test/marketplace/KODAV3GatedMarketplace.complex.test.js index 23b2565c..16bdc812 100644 --- a/test/marketplace/KODAV3GatedMarketplace.complex.test.js +++ b/test/marketplace/KODAV3GatedMarketplace.complex.test.js @@ -470,6 +470,58 @@ contract('BasicGatedSale complex tests...', function () { _recipient: buyer1.address }); }); + + it('can sellout a gated sale fully', async () => { + const creationReceipt = await this.basicGatedSale.connect(artist).createSaleWithPhases( + FIRST_MINTED_TOKEN_ID.toString(), + [this.phase1Start.toString()], + [this.phase1End.toString()], + [ether('0.1').toString()], + ['29'], + ['29'], + [this.merkleProof1.merkleRoot], + [MOCK_MERKLE_HASH], + ); + + await time.increaseTo(this.phase1Start.add(time.duration.minutes(1))); + + await expectEvent.inTransaction(creationReceipt.hash, KODAV3UpgradableGatedMarketplace, 'SaleWithPhaseCreated', { + _saleId: ONE + }); + + for (let i = 29; i > 0; --i) { + const receipt = await this.basicGatedSale.connect(buyer2).mint( + ONE.toString(), + ZERO.toString(), + ONE.toString(), + this.merkleProof1.claims[buyer2.address].index, + this.merkleProof1.claims[buyer2.address].proof, + { + value: ether('0.1').toString() + }); + + const expectedTokenId = FIRST_MINTED_TOKEN_ID.add(new BN(i.toString())).sub(ONE); + + await expectEvent.inTransaction(receipt.hash, KODAV3UpgradableGatedMarketplace, 'MintFromSale', { + _saleId: ONE, + _phaseId: ZERO, + _tokenId: expectedTokenId, + _recipient: buyer2.address + }); + + expect(await this.token.ownerOf(expectedTokenId)).to.be.equal(buyer2.address); + } + + await expectRevert(this.basicGatedSale.connect(buyer1).mint( + ONE.toString(), + ZERO.toString(), + ONE.toString(), + this.merkleProof1.claims[buyer1.address].index, + this.merkleProof1.claims[buyer1.address].proof, + { + value: ether('0.1').toString() + }), 'Phase mint cap reached'); + }); }); describe('Gated sales with mid-sequence burns/transfer', async () => { From 5c8b8e05b96b2439b65abea52a0d30112dc97ed9 Mon Sep 17 00:00:00 2001 From: James Morgan Date: Wed, 23 Mar 2022 14:30:13 +0000 Subject: [PATCH 3/7] Formatting --- contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol index 9dea07a4..774ee52b 100644 --- a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol +++ b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol @@ -313,7 +313,7 @@ contract KODAV3UpgradableGatedMarketplace is IKODAV3GatedMarketplace, BaseUpgrad function getNextAvailablePrimarySaleToken(uint256 _startId, uint256 _editionId, address creator) internal view returns (uint256 _tokenId) { for (uint256 tokenId = _startId; tokenId >= _editionId; --tokenId) { - if(koda.ownerOf(tokenId) == creator){ + if (koda.ownerOf(tokenId) == creator) { return tokenId; } } From 3e2c11b7d937b0607d403f1fd6a191750b49ef6a Mon Sep 17 00:00:00 2001 From: James Morgan Date: Wed, 23 Mar 2022 16:37:09 +0000 Subject: [PATCH 4/7] Adding latest scripts for making gated sales --- .openzeppelin/rinkeby.json | 536 ++- README.md | 8 +- contracts-flat/ClaimableFundsReceiverV1.sol | 27 +- contracts-flat/ClaimableFundsSplitterV1.sol | 31 +- contracts-flat/CollabRoyaltiesRegistry.sol | 60 +- contracts-flat/KOAccessControls.sol | 32 +- contracts-flat/KODAV3PrimaryMarketplace.sol | 101 +- contracts-flat/KODAV3SecondaryMarketplace.sol | 101 +- .../KODAV3UpgradableGatedMarketplace.sol | 3732 +++++++++++++++++ contracts-flat/KnownOriginDigitalAssetV3.sol | 79 +- contracts-flat/MintingFactory.sol | 112 +- contracts-flat/MintingFactoryV2.sol | 1385 ++++++ flatten.sh | 18 +- ...reate_sample_merkle_tree_for_gated_sale.js | 10 +- .../merkle-and-ipfs/in/ko-staff-list.json | 1 + .../merkle-and-ipfs/in/prelist-phase-1.json | 3 +- .../merkle-and-ipfs/out/phase-1-ipfs.json | 7 +- scripts/data/merkle-and-ipfs/out/phase-1.json | 181 +- .../get_upgrdable_gated_marketplace_data.js | 2 +- .../get_upgrdable_minting_factory_data.js | 2 +- .../gated/mint_batch_and_setup_sale.js | 93 + .../setup_hardcoded_gated_sale_with_phases.js | 73 + .../x_setup_gated_sale_with_phases.js | 209 - 23 files changed, 6108 insertions(+), 695 deletions(-) create mode 100644 contracts-flat/KODAV3UpgradableGatedMarketplace.sol create mode 100644 contracts-flat/MintingFactoryV2.sol rename scripts/scratch-pad/{ => gated}/get_upgrdable_gated_marketplace_data.js (93%) rename scripts/scratch-pad/{ => gated}/get_upgrdable_minting_factory_data.js (93%) create mode 100644 scripts/scratch-pad/gated/mint_batch_and_setup_sale.js create mode 100644 scripts/scratch-pad/gated/setup_hardcoded_gated_sale_with_phases.js delete mode 100644 scripts/scratch-pad/x_setup_gated_sale_with_phases.js diff --git a/.openzeppelin/rinkeby.json b/.openzeppelin/rinkeby.json index e122e83d..3d87a82a 100644 --- a/.openzeppelin/rinkeby.json +++ b/.openzeppelin/rinkeby.json @@ -2,429 +2,571 @@ "manifestVersion": "3.2", "proxies": [ { - "address": "0xB3563C45E45714d9B1a61171c0774a6deb07123D", - "txHash": "0x44a8492b68198c722ba482da8f319a3d7d7f764805a9a5f3e1b170fead876ff8", + "address": "0x048b36a7cc30127cE2C2C8E1C6AF9c3d0D8787eC", + "txHash": "0xc9c84c669144bc059b56d05d4d39334c92ecddfae8076f4aad439f5e9ff17964", "kind": "uups" }, { - "address": "0x32f43177CB70EB482cFD5DD1f3D48A760241A36F", - "txHash": "0x86c8dc173ecca05ea9af92e824b9cc4508277135a1b6166ccc8604452c52f7a3", + "address": "0x2346b3949F8742f4e2a8B6F26D72ef358683820d", + "txHash": "0x04c1c121d964be7b7466e16e8309806d2ea14fa084d8faa19b63459dc6c45a71", "kind": "uups" } ], "impls": { - "aded78bdfcb6ca6996ad61b760f5e54d6136c863431ff9e2919c8a2218e5d1fc": { - "address": "0x683EF105882C0AB65E9bcFA00eB3191004b97819", - "txHash": "0xc43f2a9cc3b3a8f6ff1fbe560aa408eb2c60ed1b563e1ca49a6f4a67e0976a22", + "db5fac7c5799e736679c8b1c3100c3264caf8055b4f8378df5df9ffac1d3231a": { + "address": "0x061e6F05a85DA169AE47BE835E5dfC8f19E2D377", + "txHash": "0x6cf0e44a21972bc5da782a61b2dccf4c73422ef00a4361c09d318facf892f528", "layout": { "storage": [ { - "contract": "Initializable", "label": "_initialized", + "offset": 0, + "slot": "0", "type": "t_bool", + "contract": "Initializable", "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:39" }, { - "contract": "Initializable", "label": "_initializing", + "offset": 1, + "slot": "0", "type": "t_bool", + "contract": "Initializable", "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:44" }, { - "contract": "ReentrancyGuardUpgradeable", "label": "_status", + "offset": 0, + "slot": "1", "type": "t_uint256", + "contract": "ReentrancyGuardUpgradeable", "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:38" }, { - "contract": "ReentrancyGuardUpgradeable", "label": "__gap", + "offset": 0, + "slot": "2", "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:68" + "contract": "ReentrancyGuardUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol:74" }, { - "contract": "ContextUpgradeable", "label": "__gap", + "offset": 0, + "slot": "51", "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:31" + "contract": "ContextUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol:36" }, { - "contract": "PausableUpgradeable", "label": "_paused", + "offset": 0, + "slot": "101", "type": "t_bool", + "contract": "PausableUpgradeable", "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:29" }, { - "contract": "PausableUpgradeable", "label": "__gap", + "offset": 0, + "slot": "102", "type": "t_array(t_uint256)49_storage", - "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:97" + "contract": "PausableUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol:102" }, { - "contract": "ERC1967UpgradeUpgradeable", "label": "__gap", + "offset": 0, + "slot": "151", "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:215" + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" }, { - "contract": "UUPSUpgradeable", "label": "__gap", + "offset": 0, + "slot": "201", "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:81" + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" }, { - "contract": "BaseUpgradableMarketplace", "label": "accessControls", - "type": "t_contract(IKOAccessControlsLookup)5291", + "offset": 0, + "slot": "251", + "type": "t_contract(IKOAccessControlsLookup)5292", + "contract": "BaseUpgradableMarketplace", "src": "contracts/marketplace/BaseUpgradableMarketplace.sol:49" }, { - "contract": "BaseUpgradableMarketplace", "label": "koda", - "type": "t_contract(IKODAV3)8127", + "offset": 0, + "slot": "252", + "type": "t_contract(IKODAV3)8128", + "contract": "BaseUpgradableMarketplace", "src": "contracts/marketplace/BaseUpgradableMarketplace.sol:52" }, { - "contract": "BaseUpgradableMarketplace", "label": "platformAccount", + "offset": 0, + "slot": "253", "type": "t_address", + "contract": "BaseUpgradableMarketplace", "src": "contracts/marketplace/BaseUpgradableMarketplace.sol:55" }, { - "contract": "BaseUpgradableMarketplace", "label": "modulo", + "offset": 0, + "slot": "254", "type": "t_uint256", + "contract": "BaseUpgradableMarketplace", "src": "contracts/marketplace/BaseUpgradableMarketplace.sol:58" }, { - "contract": "BaseUpgradableMarketplace", "label": "minBidAmount", + "offset": 0, + "slot": "255", "type": "t_uint256", + "contract": "BaseUpgradableMarketplace", "src": "contracts/marketplace/BaseUpgradableMarketplace.sol:61" }, { - "contract": "BaseUpgradableMarketplace", "label": "bidLockupPeriod", + "offset": 0, + "slot": "256", "type": "t_uint256", + "contract": "BaseUpgradableMarketplace", "src": "contracts/marketplace/BaseUpgradableMarketplace.sol:64" }, { - "contract": "BaseUpgradableMarketplace", "label": "platformPrimaryCommission", + "offset": 0, + "slot": "257", "type": "t_uint256", + "contract": "BaseUpgradableMarketplace", "src": "contracts/marketplace/BaseUpgradableMarketplace.sol:67" }, { - "contract": "KODAV3UpgradableGatedMarketplace", "label": "koCommissionOverrideForSale", - "type": "t_mapping(t_uint256,t_struct(KOCommissionOverride)12230_storage)", - "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:70" + "offset": 0, + "slot": "258", + "type": "t_mapping(t_uint256,t_struct(KOCommissionOverride)12231_storage)", + "contract": "KODAV3UpgradableGatedMarketplace", + "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:72" }, { - "contract": "KODAV3UpgradableGatedMarketplace", "label": "saleIdCounter", + "offset": 0, + "slot": "259", "type": "t_uint256", - "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:73" + "contract": "KODAV3UpgradableGatedMarketplace", + "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:75" }, { - "contract": "KODAV3UpgradableGatedMarketplace", "label": "totalMints", + "offset": 0, + "slot": "260", "type": "t_mapping(t_bytes32,t_uint256)", - "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:76" + "contract": "KODAV3UpgradableGatedMarketplace", + "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:78" }, { - "contract": "KODAV3UpgradableGatedMarketplace", "label": "editionToSale", + "offset": 0, + "slot": "261", "type": "t_mapping(t_uint256,t_uint256)", - "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:79" + "contract": "KODAV3UpgradableGatedMarketplace", + "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:81" }, { - "contract": "KODAV3UpgradableGatedMarketplace", "label": "sales", - "type": "t_mapping(t_uint256,t_struct(Sale)16342_storage)", - "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:82" + "offset": 0, + "slot": "262", + "type": "t_mapping(t_uint256,t_struct(Sale)16344_storage)", + "contract": "KODAV3UpgradableGatedMarketplace", + "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:84" }, { - "contract": "KODAV3UpgradableGatedMarketplace", "label": "phases", - "type": "t_mapping(t_uint256,t_array(t_struct(Phase)16327_storage)dyn_storage)", - "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:85" + "offset": 0, + "slot": "263", + "type": "t_mapping(t_uint256,t_array(t_struct(Phase)16329_storage)dyn_storage)", + "contract": "KODAV3UpgradableGatedMarketplace", + "src": "contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol:87" } ], "types": { - "t_mapping(t_uint256,t_struct(KOCommissionOverride)12230_storage)": { - "label": "mapping(uint256 => struct BaseUpgradableMarketplace.KOCommissionOverride)" + "t_address": { + "label": "address", + "numberOfBytes": "20" }, - "t_uint256": { - "label": "uint256" + "t_array(t_struct(Phase)16329_storage)dyn_storage": { + "label": "struct KODAV3UpgradableGatedMarketplace.Phase[]", + "numberOfBytes": "32" }, - "t_struct(KOCommissionOverride)12230_storage": { - "label": "struct BaseUpgradableMarketplace.KOCommissionOverride", - "members": [ - { - "label": "active", - "type": "t_bool" - }, - { - "label": "koCommission", - "type": "t_uint256" - } - ] + "t_array(t_uint256)49_storage": { + "label": "uint256[49]", + "numberOfBytes": "1568" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" }, "t_bool": { - "label": "bool" + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IKOAccessControlsLookup)5292": { + "label": "contract IKOAccessControlsLookup", + "numberOfBytes": "20" + }, + "t_contract(IKODAV3)8128": { + "label": "contract IKODAV3", + "numberOfBytes": "20" }, "t_mapping(t_bytes32,t_uint256)": { - "label": "mapping(bytes32 => uint256)" + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32" }, - "t_bytes32": { - "label": "bytes32" + "t_mapping(t_uint256,t_array(t_struct(Phase)16329_storage)dyn_storage)": { + "label": "mapping(uint256 => struct KODAV3UpgradableGatedMarketplace.Phase[])", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_struct(KOCommissionOverride)12231_storage)": { + "label": "mapping(uint256 => struct BaseUpgradableMarketplace.KOCommissionOverride)", + "numberOfBytes": "32" + }, + "t_mapping(t_uint256,t_struct(Sale)16344_storage)": { + "label": "mapping(uint256 => struct KODAV3UpgradableGatedMarketplace.Sale)", + "numberOfBytes": "32" }, "t_mapping(t_uint256,t_uint256)": { - "label": "mapping(uint256 => uint256)" + "label": "mapping(uint256 => uint256)", + "numberOfBytes": "32" }, - "t_mapping(t_uint256,t_struct(Sale)16342_storage)": { - "label": "mapping(uint256 => struct KODAV3UpgradableGatedMarketplace.Sale)" + "t_string_storage": { + "label": "string", + "numberOfBytes": "32" }, - "t_struct(Sale)16342_storage": { - "label": "struct KODAV3UpgradableGatedMarketplace.Sale", + "t_struct(KOCommissionOverride)12231_storage": { + "label": "struct BaseUpgradableMarketplace.KOCommissionOverride", "members": [ { - "label": "id", - "type": "t_uint256" - }, - { - "label": "editionId", - "type": "t_uint256" - }, - { - "label": "creator", - "type": "t_address" - }, - { - "label": "fundsReceiver", - "type": "t_address" - }, - { - "label": "maxEditionId", - "type": "t_uint256" - }, - { - "label": "mintCounter", - "type": "t_uint16" + "label": "active", + "type": "t_bool", + "offset": 0, + "slot": "0" }, { - "label": "paused", - "type": "t_uint8" + "label": "koCommission", + "type": "t_uint256", + "offset": 0, + "slot": "1" } - ] - }, - "t_address": { - "label": "address" - }, - "t_uint16": { - "label": "uint16" - }, - "t_uint8": { - "label": "uint8" + ], + "numberOfBytes": "64" }, - "t_mapping(t_uint256,t_array(t_struct(Phase)16327_storage)dyn_storage)": { - "label": "mapping(uint256 => struct KODAV3UpgradableGatedMarketplace.Phase[])" - }, - "t_array(t_struct(Phase)16327_storage)dyn_storage": { - "label": "struct KODAV3UpgradableGatedMarketplace.Phase[]" - }, - "t_struct(Phase)16327_storage": { + "t_struct(Phase)16329_storage": { "label": "struct KODAV3UpgradableGatedMarketplace.Phase", "members": [ { "label": "startTime", - "type": "t_uint128" + "type": "t_uint128", + "offset": 0, + "slot": "0" }, { "label": "endTime", - "type": "t_uint128" + "type": "t_uint128", + "offset": 16, + "slot": "0" }, { "label": "priceInWei", - "type": "t_uint128" + "type": "t_uint128", + "offset": 0, + "slot": "1" }, { "label": "mintCounter", - "type": "t_uint16" + "type": "t_uint16", + "offset": 16, + "slot": "1" }, { "label": "mintCap", - "type": "t_uint16" + "type": "t_uint16", + "offset": 18, + "slot": "1" }, { "label": "walletMintLimit", - "type": "t_uint16" + "type": "t_uint16", + "offset": 20, + "slot": "1" }, { "label": "merkleRoot", - "type": "t_bytes32" + "type": "t_bytes32", + "offset": 0, + "slot": "2" }, { "label": "merkleIPFSHash", - "type": "t_string_storage" + "type": "t_string_storage", + "offset": 0, + "slot": "3" } - ] - }, - "t_uint128": { - "label": "uint128" + ], + "numberOfBytes": "128" }, - "t_string_storage": { - "label": "string" + "t_struct(Sale)16344_storage": { + "label": "struct KODAV3UpgradableGatedMarketplace.Sale", + "members": [ + { + "label": "id", + "type": "t_uint256", + "offset": 0, + "slot": "0" + }, + { + "label": "editionId", + "type": "t_uint256", + "offset": 0, + "slot": "1" + }, + { + "label": "creator", + "type": "t_address", + "offset": 0, + "slot": "2" + }, + { + "label": "fundsReceiver", + "type": "t_address", + "offset": 0, + "slot": "3" + }, + { + "label": "maxEditionId", + "type": "t_uint256", + "offset": 0, + "slot": "4" + }, + { + "label": "mintCounter", + "type": "t_uint16", + "offset": 0, + "slot": "5" + }, + { + "label": "paused", + "type": "t_uint8", + "offset": 2, + "slot": "5" + } + ], + "numberOfBytes": "192" }, - "t_contract(IKOAccessControlsLookup)5291": { - "label": "contract IKOAccessControlsLookup" + "t_uint128": { + "label": "uint128", + "numberOfBytes": "16" }, - "t_contract(IKODAV3)8127": { - "label": "contract IKODAV3" + "t_uint16": { + "label": "uint16", + "numberOfBytes": "2" }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" }, - "t_array(t_uint256)49_storage": { - "label": "uint256[49]" + "t_uint8": { + "label": "uint8", + "numberOfBytes": "1" } } } }, - "c644528e7d9d31fcbdd741dbea92ad9b17848aac657a6d9d386868a43a1b5dd2": { - "address": "0xf96c5B12534DBa8D884C611DbC95354dFB31611E", - "txHash": "0x2c9d71a0ca9390a3bac02c3cca9308228bde0115ee973b78cd2f706f0d07861f", + "29bf19a3462aad0fa84426ae8dfbc83ac3c08bc588c120bc22af8c364a85f64a": { + "address": "0xa6De199f1bC051d16F8F08E8ac18514534bFdA48", + "txHash": "0xd1a8dba52c32fe503ff5e2b271b5f751e1b2d1e50692822b94861c712f806624", "layout": { "storage": [ { - "contract": "Initializable", "label": "_initialized", + "offset": 0, + "slot": "0", "type": "t_bool", + "contract": "Initializable", "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:39" }, { - "contract": "Initializable", "label": "_initializing", + "offset": 1, + "slot": "0", "type": "t_bool", + "contract": "Initializable", "src": "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol:44" }, { - "contract": "ERC1967UpgradeUpgradeable", "label": "__gap", + "offset": 0, + "slot": "1", "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:215" + "contract": "ERC1967UpgradeUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol:211" }, { - "contract": "UUPSUpgradeable", "label": "__gap", + "offset": 0, + "slot": "51", "type": "t_array(t_uint256)50_storage", - "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:81" + "contract": "UUPSUpgradeable", + "src": "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol:107" }, { - "contract": "MintingFactoryV2", "label": "mintingPeriod", + "offset": 0, + "slot": "101", "type": "t_uint256", - "src": "contracts/minter/MintingFactoryV2.sol:45" + "contract": "MintingFactoryV2", + "src": "contracts/minter/MintingFactoryV2.sol:44" }, { - "contract": "MintingFactoryV2", "label": "maxMintsInPeriod", + "offset": 0, + "slot": "102", "type": "t_uint256", - "src": "contracts/minter/MintingFactoryV2.sol:48" + "contract": "MintingFactoryV2", + "src": "contracts/minter/MintingFactoryV2.sol:47" }, { - "contract": "MintingFactoryV2", "label": "frequencyOverride", + "offset": 0, + "slot": "103", "type": "t_mapping(t_address,t_bool)", - "src": "contracts/minter/MintingFactoryV2.sol:51" + "contract": "MintingFactoryV2", + "src": "contracts/minter/MintingFactoryV2.sol:50" }, { - "contract": "MintingFactoryV2", "label": "mintingPeriodConfig", - "type": "t_mapping(t_address,t_struct(MintingPeriod)19282_storage)", - "src": "contracts/minter/MintingFactoryV2.sol:54" + "offset": 0, + "slot": "104", + "type": "t_mapping(t_address,t_struct(MintingPeriod)19265_storage)", + "contract": "MintingFactoryV2", + "src": "contracts/minter/MintingFactoryV2.sol:53" }, { - "contract": "MintingFactoryV2", "label": "accessControls", - "type": "t_contract(IKOAccessControlsLookup)5291", + "offset": 0, + "slot": "105", + "type": "t_contract(IKOAccessControlsLookup)5292", + "contract": "MintingFactoryV2", + "src": "contracts/minter/MintingFactoryV2.sol:55" + }, + { + "label": "koda", + "offset": 0, + "slot": "106", + "type": "t_contract(IKODAV3Minter)8170", + "contract": "MintingFactoryV2", "src": "contracts/minter/MintingFactoryV2.sol:56" }, { + "label": "marketplace", + "offset": 0, + "slot": "107", + "type": "t_contract(IKODAV3PrimarySaleMarketplace)13263", "contract": "MintingFactoryV2", - "label": "koda", - "type": "t_contract(IKODAV3Minter)8169", "src": "contracts/minter/MintingFactoryV2.sol:57" }, { + "label": "gatedMarketplace", + "offset": 0, + "slot": "108", + "type": "t_contract(IKODAV3GatedMarketplace)13505", "contract": "MintingFactoryV2", - "label": "marketplace", - "type": "t_contract(IKODAV3PrimarySaleMarketplace)13262", "src": "contracts/minter/MintingFactoryV2.sol:58" }, { + "label": "royaltiesRegistry", + "offset": 0, + "slot": "109", + "type": "t_contract(ICollabRoyaltiesRegistry)6547", "contract": "MintingFactoryV2", - "label": "gatedMarketplace", - "type": "t_contract(IKODAV3GatedMarketplace)13504", "src": "contracts/minter/MintingFactoryV2.sol:59" - }, - { - "contract": "MintingFactoryV2", - "label": "royaltiesRegistry", - "type": "t_contract(ICollabRoyaltiesRegistry)6546", - "src": "contracts/minter/MintingFactoryV2.sol:60" } ], "types": { - "t_uint256": { - "label": "uint256" - }, - "t_mapping(t_address,t_bool)": { - "label": "mapping(address => bool)" - }, "t_address": { - "label": "address" + "label": "address", + "numberOfBytes": "20" + }, + "t_array(t_uint256)50_storage": { + "label": "uint256[50]", + "numberOfBytes": "1600" }, "t_bool": { - "label": "bool" + "label": "bool", + "numberOfBytes": "1" + }, + "t_contract(ICollabRoyaltiesRegistry)6547": { + "label": "contract ICollabRoyaltiesRegistry", + "numberOfBytes": "20" + }, + "t_contract(IKOAccessControlsLookup)5292": { + "label": "contract IKOAccessControlsLookup", + "numberOfBytes": "20" + }, + "t_contract(IKODAV3GatedMarketplace)13505": { + "label": "contract IKODAV3GatedMarketplace", + "numberOfBytes": "20" }, - "t_mapping(t_address,t_struct(MintingPeriod)19282_storage)": { - "label": "mapping(address => struct MintingFactoryV2.MintingPeriod)" + "t_contract(IKODAV3Minter)8170": { + "label": "contract IKODAV3Minter", + "numberOfBytes": "20" }, - "t_struct(MintingPeriod)19282_storage": { + "t_contract(IKODAV3PrimarySaleMarketplace)13263": { + "label": "contract IKODAV3PrimarySaleMarketplace", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "label": "mapping(address => bool)", + "numberOfBytes": "32" + }, + "t_mapping(t_address,t_struct(MintingPeriod)19265_storage)": { + "label": "mapping(address => struct MintingFactoryV2.MintingPeriod)", + "numberOfBytes": "32" + }, + "t_struct(MintingPeriod)19265_storage": { "label": "struct MintingFactoryV2.MintingPeriod", "members": [ { "label": "mints", - "type": "t_uint128" + "type": "t_uint128", + "offset": 0, + "slot": "0" }, { "label": "firstMintInPeriod", - "type": "t_uint128" + "type": "t_uint128", + "offset": 16, + "slot": "0" } - ] + ], + "numberOfBytes": "32" }, "t_uint128": { - "label": "uint128" - }, - "t_contract(IKOAccessControlsLookup)5291": { - "label": "contract IKOAccessControlsLookup" - }, - "t_contract(IKODAV3Minter)8169": { - "label": "contract IKODAV3Minter" + "label": "uint128", + "numberOfBytes": "16" }, - "t_contract(IKODAV3PrimarySaleMarketplace)13262": { - "label": "contract IKODAV3PrimarySaleMarketplace" - }, - "t_contract(IKODAV3GatedMarketplace)13504": { - "label": "contract IKODAV3GatedMarketplace" - }, - "t_contract(ICollabRoyaltiesRegistry)6546": { - "label": "contract ICollabRoyaltiesRegistry" - }, - "t_array(t_uint256)50_storage": { - "label": "uint256[50]" + "t_uint256": { + "label": "uint256", + "numberOfBytes": "32" } } } diff --git a/README.md b/README.md index e71b0bbc..c3183e39 100644 --- a/README.md +++ b/README.md @@ -83,14 +83,14 @@ V1 funds receiver - 0xb4bb0960b5095e5a0abd07d18803f45c4c4eadf6 = (verif #### Gated marketplace (upgradable) ``` -KODAV3GatedMarketplace Proxy - 0xB3563C45E45714d9B1a61171c0774a6deb07123D - - v1 - git commit e0e67033dd9e31a9ba4f27cf3e2d4e9faa8ea1ef +KODAV3GatedMarketplace Proxy - 0x048b36a7cc30127cE2C2C8E1C6AF9c3d0D8787eC + - v1 - git commit 5c8b8e05b96b2439b65abea52a0d30112dc97ed9 ``` #### Minting Factory (upgradable) ``` -MintingFactoryV2 Proxy - 0x32f43177CB70EB482cFD5DD1f3D48A760241A36F - - v1 - git commit e0e67033dd9e31a9ba4f27cf3e2d4e9faa8ea1ef +MintingFactoryV2 Proxy - 0x2346b3949F8742f4e2a8B6F26D72ef358683820d + - v1 - git commit 5c8b8e05b96b2439b65abea52a0d30112dc97ed9 ``` ### Mainnet diff --git a/contracts-flat/ClaimableFundsReceiverV1.sol b/contracts-flat/ClaimableFundsReceiverV1.sol index 12602287..bb0d751d 100644 --- a/contracts-flat/ClaimableFundsReceiverV1.sol +++ b/contracts-flat/ClaimableFundsReceiverV1.sol @@ -1,4 +1,6 @@ -// File: @openzeppelin/contracts/token/ERC20/IERC20.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 // SPDX-License-Identifier: MIT @@ -82,9 +84,10 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -// File: @openzeppelin/contracts/utils/Address.sol +// File @openzeppelin/contracts/utils/Address.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -295,9 +298,10 @@ library Address { } } -// File: @openzeppelin/contracts/security/ReentrancyGuard.sol +// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -360,9 +364,10 @@ abstract contract ReentrancyGuard { } } -// File: contracts/collab/handlers/ICollabFundsHandler.sol +// File contracts/collab/handlers/ICollabFundsHandler.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -375,13 +380,13 @@ interface ICollabFundsHandler { function shareAtIndex(uint256 index) external view returns (address _recipient, uint256 _split); } -// File: contracts/collab/handlers/CollabFundsHandlerBase.sol +// File contracts/collab/handlers/CollabFundsHandlerBase.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - abstract contract CollabFundsHandlerBase is ICollabFundsHandler { /// @notice in line with EIP-2981 format - precision 100.00000% @@ -423,13 +428,13 @@ abstract contract CollabFundsHandlerBase is ICollabFundsHandler { } } -// File: contracts/collab/handlers/ICollabFundsDrainable.sol +// File contracts/collab/handlers/ICollabFundsDrainable.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - // Drain all funds for all parties interface ICollabFundsDrainable { @@ -447,9 +452,10 @@ interface ICollabFundsShareDrainable is ICollabFundsDrainable { function drainShareERC20(IERC20 token) external; } -// File: contracts/collab/handlers/ClaimableFundsReceiverV1.sol +// File contracts/collab/handlers/ClaimableFundsReceiverV1.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -457,10 +463,9 @@ pragma solidity 0.8.4; - /// @title Allows funds to be received and then split later on using a pull pattern, holding a balance until drained. /// @notice Supports claiming/draining all balances at one -/// @notice Doe not an individual shares +/// @notice Does not an individual shares /// /// @author KnownOrigin Labs - https://knownorigin.io/ contract ClaimableFundsReceiverV1 is ReentrancyGuard, CollabFundsHandlerBase, ICollabFundsDrainable { diff --git a/contracts-flat/ClaimableFundsSplitterV1.sol b/contracts-flat/ClaimableFundsSplitterV1.sol index e4e3fc2a..ef0b58d7 100644 --- a/contracts-flat/ClaimableFundsSplitterV1.sol +++ b/contracts-flat/ClaimableFundsSplitterV1.sol @@ -1,4 +1,6 @@ -// File: @openzeppelin/contracts/token/ERC20/IERC20.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 // SPDX-License-Identifier: MIT @@ -82,9 +84,10 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -// File: @openzeppelin/contracts/utils/Address.sol +// File @openzeppelin/contracts/utils/Address.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -295,9 +298,10 @@ library Address { } } -// File: @openzeppelin/contracts/security/ReentrancyGuard.sol +// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -360,9 +364,10 @@ abstract contract ReentrancyGuard { } } -// File: contracts/collab/handlers/ICollabFundsHandler.sol +// File contracts/collab/handlers/ICollabFundsHandler.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -375,13 +380,13 @@ interface ICollabFundsHandler { function shareAtIndex(uint256 index) external view returns (address _recipient, uint256 _split); } -// File: contracts/collab/handlers/CollabFundsHandlerBase.sol +// File contracts/collab/handlers/CollabFundsHandlerBase.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - abstract contract CollabFundsHandlerBase is ICollabFundsHandler { /// @notice in line with EIP-2981 format - precision 100.00000% @@ -423,13 +428,13 @@ abstract contract CollabFundsHandlerBase is ICollabFundsHandler { } } -// File: contracts/collab/handlers/ICollabFundsDrainable.sol +// File contracts/collab/handlers/ICollabFundsDrainable.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - // Drain all funds for all parties interface ICollabFundsDrainable { @@ -447,9 +452,10 @@ interface ICollabFundsShareDrainable is ICollabFundsDrainable { function drainShareERC20(IERC20 token) external; } -// File: contracts/collab/handlers/ClaimableFundsReceiverV1.sol +// File contracts/collab/handlers/ClaimableFundsReceiverV1.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -457,10 +463,9 @@ pragma solidity 0.8.4; - /// @title Allows funds to be received and then split later on using a pull pattern, holding a balance until drained. /// @notice Supports claiming/draining all balances at one -/// @notice Doe not an individual shares +/// @notice Does not an individual shares /// /// @author KnownOrigin Labs - https://knownorigin.io/ contract ClaimableFundsReceiverV1 is ReentrancyGuard, CollabFundsHandlerBase, ICollabFundsDrainable { @@ -534,9 +539,10 @@ contract ClaimableFundsReceiverV1 is ReentrancyGuard, CollabFundsHandlerBase, IC } -// File: contracts/collab/handlers/ClaimableFundsSplitterV1.sol +// File contracts/collab/handlers/ClaimableFundsSplitterV1.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -545,7 +551,6 @@ pragma solidity 0.8.4; - /// @title Allows funds to be split on receiving the funds /// @notice This should not be used for large number of collaborators due to the potential of out of gas errors /// when splitting between many participants when natively receiving ETH diff --git a/contracts-flat/CollabRoyaltiesRegistry.sol b/contracts-flat/CollabRoyaltiesRegistry.sol index e9360871..2b3be6ce 100644 --- a/contracts-flat/CollabRoyaltiesRegistry.sol +++ b/contracts-flat/CollabRoyaltiesRegistry.sol @@ -1,4 +1,6 @@ -// File: @openzeppelin/contracts/utils/Context.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/utils/Context.sol@v4.2.0 // SPDX-License-Identifier: MIT @@ -24,9 +26,10 @@ abstract contract Context { } } -// File: @openzeppelin/contracts/utils/introspection/IERC165.sol +// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -51,13 +54,13 @@ interface IERC165 { function supportsInterface(bytes4 interfaceId) external view returns (bool); } -// File: @openzeppelin/contracts/utils/introspection/ERC165.sol +// File @openzeppelin/contracts/utils/introspection/ERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Implementation of the {IERC165} interface. * @@ -81,13 +84,13 @@ abstract contract ERC165 is IERC165 { } } -// File: @openzeppelin/contracts/utils/introspection/ERC165Storage.sol +// File @openzeppelin/contracts/utils/introspection/ERC165Storage.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Storage based implementation of the {IERC165} interface. * @@ -124,9 +127,10 @@ abstract contract ERC165Storage is ERC165 { } } -// File: @openzeppelin/contracts/proxy/Clones.sol +// File @openzeppelin/contracts/proxy/Clones.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -210,9 +214,10 @@ library Clones { } } -// File: @openzeppelin/contracts/utils/Address.sol +// File @openzeppelin/contracts/utils/Address.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -423,13 +428,13 @@ library Address { } } -// File: @openzeppelin/contracts/security/Pausable.sol +// File @openzeppelin/contracts/security/Pausable.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. @@ -515,13 +520,13 @@ abstract contract Pausable is Context { } } -// File: @openzeppelin/contracts/token/ERC721/IERC721.sol +// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Required interface of an ERC721 compliant contract. */ @@ -659,9 +664,10 @@ interface IERC721 is IERC165 { ) external; } -// File: contracts/core/IERC2309.sol +// File contracts/core/IERC2309.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -688,13 +694,13 @@ interface IERC2309 { event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress); } -// File: contracts/core/IERC2981.sol +// File contracts/core/IERC2981.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @notice This is purely an extension for the KO platform /// @notice Royalties on KO are defined at an edition level for all tokens from the same edition interface IERC2981EditionExtension { @@ -733,13 +739,13 @@ interface IERC2981 is IERC165, IERC2981EditionExtension { } -// File: contracts/core/IHasSecondarySaleFees.sol +// File contracts/core/IHasSecondarySaleFees.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @title Royalties formats required for use on the Rarible platform /// @dev https://docs.rarible.com/asset/royalties-schema interface IHasSecondarySaleFees is IERC165 { @@ -751,9 +757,10 @@ interface IHasSecondarySaleFees is IERC165 { function getFeeBps(uint256 id) external returns (uint[] memory); } -// File: contracts/core/IKODAV3.sol +// File contracts/core/IKODAV3.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -761,7 +768,6 @@ pragma solidity 0.8.4; - /// @title Core KODA V3 functionality interface IKODAV3 is IERC165, // Contract introspection @@ -830,9 +836,10 @@ IHasSecondarySaleFees // Rariable / Foundation royalties } -// File: contracts/core/Konstants.sol +// File contracts/core/Konstants.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -847,9 +854,10 @@ contract Konstants { } } -// File: contracts/access/IKOAccessControlsLookup.sol +// File contracts/access/IKOAccessControlsLookup.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -867,9 +875,10 @@ interface IKOAccessControlsLookup { function hasContractOrAdminRole(address _address) external view returns (bool); } -// File: contracts/collab/ICollabRoyaltiesRegistry.sol +// File contracts/collab/ICollabRoyaltiesRegistry.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; /// @notice Common interface to the edition royalties registry @@ -911,9 +920,10 @@ interface ICollabRoyaltiesRegistry { } -// File: contracts/collab/handlers/ICollabFundsHandler.sol +// File contracts/collab/handlers/ICollabFundsHandler.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -926,9 +936,10 @@ interface ICollabFundsHandler { function shareAtIndex(uint256 index) external view returns (address _recipient, uint256 _split); } -// File: contracts/collab/CollabRoyaltiesRegistry.sol +// File contracts/collab/CollabRoyaltiesRegistry.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -941,7 +952,6 @@ pragma solidity 0.8.4; - contract CollabRoyaltiesRegistry is Pausable, Konstants, ERC165Storage, IERC2981, ICollabRoyaltiesRegistry { // Admin Events diff --git a/contracts-flat/KOAccessControls.sol b/contracts-flat/KOAccessControls.sol index 268012ed..a21e929d 100644 --- a/contracts-flat/KOAccessControls.sol +++ b/contracts-flat/KOAccessControls.sol @@ -1,4 +1,6 @@ -// File: @openzeppelin/contracts/utils/Context.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/utils/Context.sol@v4.2.0 // SPDX-License-Identifier: MIT @@ -24,9 +26,10 @@ abstract contract Context { } } -// File: @openzeppelin/contracts/utils/Strings.sol +// File @openzeppelin/contracts/utils/Strings.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -93,9 +96,10 @@ library Strings { } } -// File: @openzeppelin/contracts/utils/introspection/IERC165.sol +// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -120,13 +124,13 @@ interface IERC165 { function supportsInterface(bytes4 interfaceId) external view returns (bool); } -// File: @openzeppelin/contracts/utils/introspection/ERC165.sol +// File @openzeppelin/contracts/utils/introspection/ERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Implementation of the {IERC165} interface. * @@ -150,15 +154,15 @@ abstract contract ERC165 is IERC165 { } } -// File: @openzeppelin/contracts/access/AccessControl.sol +// File @openzeppelin/contracts/access/AccessControl.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev External interface of AccessControl declared to support ERC165 detection. */ @@ -402,9 +406,10 @@ abstract contract AccessControl is Context, IAccessControl, ERC165 { } } -// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol +// File @openzeppelin/contracts/utils/cryptography/MerkleProof.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -448,9 +453,10 @@ library MerkleProof { } } -// File: contracts/access/IKOAccessControlsLookup.sol +// File contracts/access/IKOAccessControlsLookup.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -468,9 +474,10 @@ interface IKOAccessControlsLookup { function hasContractOrAdminRole(address _address) external view returns (bool); } -// File: contracts/access/legacy/ISelfServiceAccessControls.sol +// File contracts/access/legacy/ISelfServiceAccessControls.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface ISelfServiceAccessControls { @@ -479,17 +486,16 @@ interface ISelfServiceAccessControls { } -// File: contracts/access/KOAccessControls.sol +// File contracts/access/KOAccessControls.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - contract KOAccessControls is AccessControl, IKOAccessControlsLookup { event AdminUpdateArtistAccessMerkleRoot(bytes32 _artistAccessMerkleRoot); diff --git a/contracts-flat/KODAV3PrimaryMarketplace.sol b/contracts-flat/KODAV3PrimaryMarketplace.sol index effc59d6..f4339749 100644 --- a/contracts-flat/KODAV3PrimaryMarketplace.sol +++ b/contracts-flat/KODAV3PrimaryMarketplace.sol @@ -1,4 +1,6 @@ -// File: contracts/access/IKOAccessControlsLookup.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File contracts/access/IKOAccessControlsLookup.sol // SPDX-License-Identifier: MIT @@ -18,9 +20,10 @@ interface IKOAccessControlsLookup { function hasContractOrAdminRole(address _address) external view returns (bool); } -// File: @openzeppelin/contracts/utils/introspection/IERC165.sol +// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -45,13 +48,13 @@ interface IERC165 { function supportsInterface(bytes4 interfaceId) external view returns (bool); } -// File: @openzeppelin/contracts/token/ERC721/IERC721.sol +// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Required interface of an ERC721 compliant contract. */ @@ -189,9 +192,10 @@ interface IERC721 is IERC165 { ) external; } -// File: contracts/core/IERC2309.sol +// File contracts/core/IERC2309.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -218,13 +222,13 @@ interface IERC2309 { event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress); } -// File: contracts/core/IERC2981.sol +// File contracts/core/IERC2981.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @notice This is purely an extension for the KO platform /// @notice Royalties on KO are defined at an edition level for all tokens from the same edition interface IERC2981EditionExtension { @@ -263,13 +267,13 @@ interface IERC2981 is IERC165, IERC2981EditionExtension { } -// File: contracts/core/IHasSecondarySaleFees.sol +// File contracts/core/IHasSecondarySaleFees.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @title Royalties formats required for use on the Rarible platform /// @dev https://docs.rarible.com/asset/royalties-schema interface IHasSecondarySaleFees is IERC165 { @@ -281,9 +285,10 @@ interface IHasSecondarySaleFees is IERC165 { function getFeeBps(uint256 id) external returns (uint[] memory); } -// File: contracts/core/IKODAV3.sol +// File contracts/core/IKODAV3.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -291,7 +296,6 @@ pragma solidity 0.8.4; - /// @title Core KODA V3 functionality interface IKODAV3 is IERC165, // Contract introspection @@ -360,9 +364,10 @@ IHasSecondarySaleFees // Rariable / Foundation royalties } -// File: contracts/marketplace/IKODAV3Marketplace.sol +// File contracts/marketplace/IKODAV3Marketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface IBuyNowMarketplace { @@ -492,9 +497,50 @@ interface IKODAV3SecondarySaleMarketplace is ITokenBuyNowMarketplace, ITokenOffe function convertReserveAuctionToOffers(uint256 _tokenId) external; } -// File: @openzeppelin/contracts/security/ReentrancyGuard.sol +interface IKODAV3GatedMarketplace { + + function createSale(uint256 _editionId) external; + + function createPhase( + uint256 _editionId, + uint128 _startTime, + uint128 _endTime, + uint128 _priceInWei, + uint16 _mintCap, + uint16 _walletMintLimit, + bytes32 _merkleRoot, + string calldata _merkleIPFSHash + ) external; + + function createSaleWithPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function createPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function removePhase(uint256 _editionId, uint256 _phaseId) external; +} + +// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -557,9 +603,10 @@ abstract contract ReentrancyGuard { } } -// File: @openzeppelin/contracts/utils/Context.sol +// File @openzeppelin/contracts/utils/Context.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -583,13 +630,13 @@ abstract contract Context { } } -// File: @openzeppelin/contracts/security/Pausable.sol +// File @openzeppelin/contracts/security/Pausable.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. @@ -675,9 +722,10 @@ abstract contract Pausable is Context { } } -// File: @openzeppelin/contracts/token/ERC20/IERC20.sol +// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -759,17 +807,16 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -// File: contracts/marketplace/BaseMarketplace.sol +// File contracts/marketplace/BaseMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - /// @notice Core logic and state shared between both marketplaces abstract contract BaseMarketplace is ReentrancyGuard, Pausable { @@ -900,14 +947,14 @@ abstract contract BaseMarketplace is ReentrancyGuard, Pausable { function _isListingPermitted(uint256 _id) internal virtual returns (bool); } -// File: contracts/marketplace/BuyNowMarketplace.sol +// File contracts/marketplace/BuyNowMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - // "buy now" sale flow abstract contract BuyNowMarketplace is IBuyNowMarketplace, BaseMarketplace { // Buy now listing definition @@ -987,16 +1034,15 @@ abstract contract BuyNowMarketplace is IBuyNowMarketplace, BaseMarketplace { function _isBuyNowListingPermitted(uint256 _id) internal virtual returns (bool); } -// File: contracts/marketplace/ReserveAuctionMarketplace.sol +// File contracts/marketplace/ReserveAuctionMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - abstract contract ReserveAuctionMarketplace is IReserveAuctionMarketplace, BaseMarketplace { event AdminUpdateReserveAuctionBidExtensionWindow(uint128 _reserveAuctionBidExtensionWindow); event AdminUpdateReserveAuctionLengthOnceReserveMet(uint128 _reserveAuctionLengthOnceReserveMet); @@ -1230,9 +1276,10 @@ abstract contract ReserveAuctionMarketplace is IReserveAuctionMarketplace, BaseM } } -// File: contracts/marketplace/KODAV3PrimaryMarketplace.sol +// File contracts/marketplace/KODAV3PrimaryMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1240,8 +1287,6 @@ pragma solidity 0.8.4; - - /// @title KnownOrigin Primary Marketplace for all V3 tokens /// @notice The following listing types are supported: Buy now, Stepped, Reserve and Offers /// @dev The contract is pausable and has reentrancy guards diff --git a/contracts-flat/KODAV3SecondaryMarketplace.sol b/contracts-flat/KODAV3SecondaryMarketplace.sol index 248d6aeb..eea7cd0a 100644 --- a/contracts-flat/KODAV3SecondaryMarketplace.sol +++ b/contracts-flat/KODAV3SecondaryMarketplace.sol @@ -1,7 +1,8 @@ -// File: contracts/marketplace/IKODAV3Marketplace.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org -// SPDX-License-Identifier: MIT +// File contracts/marketplace/IKODAV3Marketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface IBuyNowMarketplace { @@ -131,10 +132,51 @@ interface IKODAV3SecondarySaleMarketplace is ITokenBuyNowMarketplace, ITokenOffe function convertReserveAuctionToOffers(uint256 _tokenId) external; } -// File: contracts/access/IKOAccessControlsLookup.sol +interface IKODAV3GatedMarketplace { + + function createSale(uint256 _editionId) external; + + function createPhase( + uint256 _editionId, + uint128 _startTime, + uint128 _endTime, + uint128 _priceInWei, + uint16 _mintCap, + uint16 _walletMintLimit, + bytes32 _merkleRoot, + string calldata _merkleIPFSHash + ) external; + + function createSaleWithPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + function createPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function removePhase(uint256 _editionId, uint256 _phaseId) external; +} +// File contracts/access/IKOAccessControlsLookup.sol + +// SPDX-License-Identifier: MIT + pragma solidity 0.8.4; interface IKOAccessControlsLookup { @@ -151,9 +193,10 @@ interface IKOAccessControlsLookup { function hasContractOrAdminRole(address _address) external view returns (bool); } -// File: @openzeppelin/contracts/utils/introspection/IERC165.sol +// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -178,13 +221,13 @@ interface IERC165 { function supportsInterface(bytes4 interfaceId) external view returns (bool); } -// File: @openzeppelin/contracts/token/ERC721/IERC721.sol +// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Required interface of an ERC721 compliant contract. */ @@ -322,9 +365,10 @@ interface IERC721 is IERC165 { ) external; } -// File: contracts/core/IERC2309.sol +// File contracts/core/IERC2309.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -351,13 +395,13 @@ interface IERC2309 { event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress); } -// File: contracts/core/IERC2981.sol +// File contracts/core/IERC2981.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @notice This is purely an extension for the KO platform /// @notice Royalties on KO are defined at an edition level for all tokens from the same edition interface IERC2981EditionExtension { @@ -396,13 +440,13 @@ interface IERC2981 is IERC165, IERC2981EditionExtension { } -// File: contracts/core/IHasSecondarySaleFees.sol +// File contracts/core/IHasSecondarySaleFees.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @title Royalties formats required for use on the Rarible platform /// @dev https://docs.rarible.com/asset/royalties-schema interface IHasSecondarySaleFees is IERC165 { @@ -414,9 +458,10 @@ interface IHasSecondarySaleFees is IERC165 { function getFeeBps(uint256 id) external returns (uint[] memory); } -// File: contracts/core/IKODAV3.sol +// File contracts/core/IKODAV3.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -424,7 +469,6 @@ pragma solidity 0.8.4; - /// @title Core KODA V3 functionality interface IKODAV3 is IERC165, // Contract introspection @@ -493,9 +537,10 @@ IHasSecondarySaleFees // Rariable / Foundation royalties } -// File: @openzeppelin/contracts/security/ReentrancyGuard.sol +// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -558,9 +603,10 @@ abstract contract ReentrancyGuard { } } -// File: @openzeppelin/contracts/utils/Context.sol +// File @openzeppelin/contracts/utils/Context.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -584,13 +630,13 @@ abstract contract Context { } } -// File: @openzeppelin/contracts/security/Pausable.sol +// File @openzeppelin/contracts/security/Pausable.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. @@ -676,9 +722,10 @@ abstract contract Pausable is Context { } } -// File: @openzeppelin/contracts/token/ERC20/IERC20.sol +// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -760,17 +807,16 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -// File: contracts/marketplace/BaseMarketplace.sol +// File contracts/marketplace/BaseMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - /// @notice Core logic and state shared between both marketplaces abstract contract BaseMarketplace is ReentrancyGuard, Pausable { @@ -901,14 +947,14 @@ abstract contract BaseMarketplace is ReentrancyGuard, Pausable { function _isListingPermitted(uint256 _id) internal virtual returns (bool); } -// File: contracts/marketplace/BuyNowMarketplace.sol +// File contracts/marketplace/BuyNowMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - // "buy now" sale flow abstract contract BuyNowMarketplace is IBuyNowMarketplace, BaseMarketplace { // Buy now listing definition @@ -988,16 +1034,15 @@ abstract contract BuyNowMarketplace is IBuyNowMarketplace, BaseMarketplace { function _isBuyNowListingPermitted(uint256 _id) internal virtual returns (bool); } -// File: contracts/marketplace/ReserveAuctionMarketplace.sol +// File contracts/marketplace/ReserveAuctionMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - abstract contract ReserveAuctionMarketplace is IReserveAuctionMarketplace, BaseMarketplace { event AdminUpdateReserveAuctionBidExtensionWindow(uint128 _reserveAuctionBidExtensionWindow); event AdminUpdateReserveAuctionLengthOnceReserveMet(uint128 _reserveAuctionLengthOnceReserveMet); @@ -1231,9 +1276,10 @@ abstract contract ReserveAuctionMarketplace is IReserveAuctionMarketplace, BaseM } } -// File: contracts/marketplace/KODAV3SecondaryMarketplace.sol +// File contracts/marketplace/KODAV3SecondaryMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1242,7 +1288,6 @@ pragma solidity 0.8.4; - /// @title KnownOrigin Secondary Marketplace for all V3 tokens /// @notice The following listing types are supported: Buy now, Reserve and Offers /// @dev The contract is pausable and has reentrancy guards diff --git a/contracts-flat/KODAV3UpgradableGatedMarketplace.sol b/contracts-flat/KODAV3UpgradableGatedMarketplace.sol new file mode 100644 index 00000000..8c4e9a65 --- /dev/null +++ b/contracts-flat/KODAV3UpgradableGatedMarketplace.sol @@ -0,0 +1,3732 @@ +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/utils/cryptography/MerkleProof.sol@v4.2.0 + +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev These functions deal with verification of Merkle Trees proofs. + * + * The proofs can be generated using the JavaScript library + * https://github.com/miguelmota/merkletreejs[merkletreejs]. + * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. + * + * See `test/utils/cryptography/MerkleProof.test.js` for some examples. + */ +library MerkleProof { + /** + * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree + * defined by `root`. For this, a `proof` must be provided, containing + * sibling hashes on the branch from the leaf to the root of the tree. Each + * pair of leaves and each pair of pre-images are assumed to be sorted. + */ + function verify( + bytes32[] memory proof, + bytes32 root, + bytes32 leaf + ) internal pure returns (bool) { + bytes32 computedHash = leaf; + + for (uint256 i = 0; i < proof.length; i++) { + bytes32 proofElement = proof[i]; + + if (computedHash <= proofElement) { + // Hash(current computed hash + current element of the proof) + computedHash = keccak256(abi.encodePacked(computedHash, proofElement)); + } else { + // Hash(current element of the proof + current computed hash) + computedHash = keccak256(abi.encodePacked(proofElement, computedHash)); + } + } + + // Check if the computed hash (root) is equal to the provided root + return computedHash == root; + } +} + + +// File @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) + +pragma solidity ^0.8.1; + +/** + * @dev Collection of functions related to the address type + */ +library AddressUpgradeable { + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + * + * [IMPORTANT] + * ==== + * You shouldn't rely on `isContract` to protect against flash loan attacks! + * + * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets + * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract + * constructor. + * ==== + */ + function isContract(address account) internal view returns (bool) { + // This method relies on extcodesize/address.code.length, which returns 0 + // for contracts in construction, since the code is only stored at the end + // of the constructor execution. + + return account.code.length > 0; + } + + /** + * @dev Replacement for Solidity's `transfer`: sends `amount` wei to + * `recipient`, forwarding all available gas and reverting on errors. + * + * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost + * of certain opcodes, possibly making contracts go over the 2300 gas limit + * imposed by `transfer`, making them unable to receive funds via + * `transfer`. {sendValue} removes this limitation. + * + * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. + * + * IMPORTANT: because control is transferred to `recipient`, care must be + * taken to not create reentrancy vulnerabilities. Consider using + * {ReentrancyGuard} or the + * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. + */ + function sendValue(address payable recipient, uint256 amount) internal { + require(address(this).balance >= amount, "Address: insufficient balance"); + + (bool success, ) = recipient.call{value: amount}(""); + require(success, "Address: unable to send value, recipient may have reverted"); + } + + /** + * @dev Performs a Solidity function call using a low level `call`. A + * plain `call` is an unsafe replacement for a function call: use this + * function instead. + * + * If `target` reverts with a revert reason, it is bubbled up by this + * function (like regular Solidity function calls). + * + * Returns the raw returned data. To convert to the expected return value, + * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. + * + * Requirements: + * + * - `target` must be a contract. + * - calling `target` with `data` must not revert. + * + * _Available since v3.1._ + */ + function functionCall(address target, bytes memory data) internal returns (bytes memory) { + return functionCall(target, data, "Address: low-level call failed"); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with + * `errorMessage` as a fallback revert reason when `target` reverts. + * + * _Available since v3.1._ + */ + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, 0, errorMessage); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but also transferring `value` wei to `target`. + * + * Requirements: + * + * - the calling contract must have an ETH balance of at least `value`. + * - the called Solidity function must be `payable`. + * + * _Available since v3.1._ + */ + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); + } + + /** + * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but + * with `errorMessage` as a fallback revert reason when `target` reverts. + * + * _Available since v3.1._ + */ + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) internal returns (bytes memory) { + require(address(this).balance >= value, "Address: insufficient balance for call"); + require(isContract(target), "Address: call to non-contract"); + + (bool success, bytes memory returndata) = target.call{value: value}(data); + return verifyCallResult(success, returndata, errorMessage); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a static call. + * + * _Available since v3.3._ + */ + function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { + return functionStaticCall(target, data, "Address: low-level static call failed"); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], + * but performing a static call. + * + * _Available since v3.3._ + */ + function functionStaticCall( + address target, + bytes memory data, + string memory errorMessage + ) internal view returns (bytes memory) { + require(isContract(target), "Address: static call to non-contract"); + + (bool success, bytes memory returndata) = target.staticcall(data); + return verifyCallResult(success, returndata, errorMessage); + } + + /** + * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the + * revert reason using the provided one. + * + * _Available since v4.3._ + */ + function verifyCallResult( + bool success, + bytes memory returndata, + string memory errorMessage + ) internal pure returns (bytes memory) { + if (success) { + return returndata; + } else { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(errorMessage); + } + } + } +} + + +// File @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) + +pragma solidity ^0.8.0; + +/** + * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed + * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an + * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer + * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. + * + * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as + * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. + * + * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure + * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. + * + * [CAUTION] + * ==== + * Avoid leaving a contract uninitialized. + * + * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation + * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the + * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: + * + * [.hljs-theme-light.nopadding] + * ``` + * /// @custom:oz-upgrades-unsafe-allow constructor + * constructor() initializer {} + * ``` + * ==== + */ +abstract contract Initializable { + /** + * @dev Indicates that the contract has been initialized. + */ + bool private _initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private _initializing; + + /** + * @dev Modifier to protect an initializer function from being invoked twice. + */ + modifier initializer() { + // If the contract is initializing we ignore whether _initialized is set in order to support multiple + // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the + // contract may have been reentered. + require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); + + bool isTopLevelCall = !_initializing; + if (isTopLevelCall) { + _initializing = true; + _initialized = true; + } + + _; + + if (isTopLevelCall) { + _initializing = false; + } + } + + /** + * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the + * {initializer} modifier, directly or indirectly. + */ + modifier onlyInitializing() { + require(_initializing, "Initializable: contract is not initializing"); + _; + } + + function _isConstructor() private view returns (bool) { + return !AddressUpgradeable.isContract(address(this)); + } +} + + +// File @openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Contract module that helps prevent reentrant calls to a function. + * + * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier + * available, which can be applied to functions to make sure there are no nested + * (reentrant) calls to them. + * + * Note that because there is a single `nonReentrant` guard, functions marked as + * `nonReentrant` may not call one another. This can be worked around by making + * those functions `private`, and then adding `external` `nonReentrant` entry + * points to them. + * + * TIP: If you would like to learn more about reentrancy and alternative ways + * to protect against it, check out our blog post + * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. + */ +abstract contract ReentrancyGuardUpgradeable is Initializable { + // Booleans are more expensive than uint256 or any type that takes up a full + // word because each write operation emits an extra SLOAD to first read the + // slot's contents, replace the bits taken up by the boolean, and then write + // back. This is the compiler's defense against contract upgrades and + // pointer aliasing, and it cannot be disabled. + + // The values being non-zero value makes deployment a bit more expensive, + // but in exchange the refund on every call to nonReentrant will be lower in + // amount. Since refunds are capped to a percentage of the total + // transaction's gas, it is best to keep them low in cases like this one, to + // increase the likelihood of the full refund coming into effect. + uint256 private constant _NOT_ENTERED = 1; + uint256 private constant _ENTERED = 2; + + uint256 private _status; + + function __ReentrancyGuard_init() internal onlyInitializing { + __ReentrancyGuard_init_unchained(); + } + + function __ReentrancyGuard_init_unchained() internal onlyInitializing { + _status = _NOT_ENTERED; + } + + /** + * @dev Prevents a contract from calling itself, directly or indirectly. + * Calling a `nonReentrant` function from another `nonReentrant` + * function is not supported. It is possible to prevent this from happening + * by making the `nonReentrant` function external, and making it call a + * `private` function that does the actual work. + */ + modifier nonReentrant() { + // On the first call to nonReentrant, _notEntered will be true + require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); + + // Any calls to nonReentrant after this point will fail + _status = _ENTERED; + + _; + + // By storing the original value once again, a refund is triggered (see + // https://eips.ethereum.org/EIPS/eip-2200) + _status = _NOT_ENTERED; + } + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[49] private __gap; +} + + +// File @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (utils/Context.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + */ +abstract contract ContextUpgradeable is Initializable { + function __Context_init() internal onlyInitializing { + } + + function __Context_init_unchained() internal onlyInitializing { + } + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[50] private __gap; +} + + +// File @openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) + +pragma solidity ^0.8.0; + + +/** + * @dev Contract module which allows children to implement an emergency stop + * mechanism that can be triggered by an authorized account. + * + * This module is used through inheritance. It will make available the + * modifiers `whenNotPaused` and `whenPaused`, which can be applied to + * the functions of your contract. Note that they will not be pausable by + * simply including this module, only once the modifiers are put in place. + */ +abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { + /** + * @dev Emitted when the pause is triggered by `account`. + */ + event Paused(address account); + + /** + * @dev Emitted when the pause is lifted by `account`. + */ + event Unpaused(address account); + + bool private _paused; + + /** + * @dev Initializes the contract in unpaused state. + */ + function __Pausable_init() internal onlyInitializing { + __Pausable_init_unchained(); + } + + function __Pausable_init_unchained() internal onlyInitializing { + _paused = false; + } + + /** + * @dev Returns true if the contract is paused, and false otherwise. + */ + function paused() public view virtual returns (bool) { + return _paused; + } + + /** + * @dev Modifier to make a function callable only when the contract is not paused. + * + * Requirements: + * + * - The contract must not be paused. + */ + modifier whenNotPaused() { + require(!paused(), "Pausable: paused"); + _; + } + + /** + * @dev Modifier to make a function callable only when the contract is paused. + * + * Requirements: + * + * - The contract must be paused. + */ + modifier whenPaused() { + require(paused(), "Pausable: not paused"); + _; + } + + /** + * @dev Triggers stopped state. + * + * Requirements: + * + * - The contract must not be paused. + */ + function _pause() internal virtual whenNotPaused { + _paused = true; + emit Paused(_msgSender()); + } + + /** + * @dev Returns to normal state. + * + * Requirements: + * + * - The contract must be paused. + */ + function _unpause() internal virtual whenPaused { + _paused = false; + emit Unpaused(_msgSender()); + } + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[49] private __gap; +} + + +// File @openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) + +pragma solidity ^0.8.0; + +/** + * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified + * proxy whose upgrades are fully controlled by the current implementation. + */ +interface IERC1822ProxiableUpgradeable { + /** + * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation + * address. + * + * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks + * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this + * function revert if invoked through a proxy. + */ + function proxiableUUID() external view returns (bytes32); +} + + +// File @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) + +pragma solidity ^0.8.0; + +/** + * @dev This is the interface that {BeaconProxy} expects of its beacon. + */ +interface IBeaconUpgradeable { + /** + * @dev Must return an address that can be used as a delegate call target. + * + * {BeaconProxy} will check that this address is a contract. + */ + function implementation() external view returns (address); +} + + +// File @openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Library for reading and writing primitive types to specific storage slots. + * + * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. + * This library helps with reading and writing to such slots without the need for inline assembly. + * + * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. + * + * Example usage to set ERC1967 implementation slot: + * ``` + * contract ERC1967 { + * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + * + * function _getImplementation() internal view returns (address) { + * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + * } + * + * function _setImplementation(address newImplementation) internal { + * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); + * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + * } + * } + * ``` + * + * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ + */ +library StorageSlotUpgradeable { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + /** + * @dev Returns an `AddressSlot` with member `value` located at `slot`. + */ + function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BooleanSlot` with member `value` located at `slot`. + */ + function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. + */ + function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Uint256Slot` with member `value` located at `slot`. + */ + function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { + assembly { + r.slot := slot + } + } +} + + +// File @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) + +pragma solidity ^0.8.2; + + + + + +/** + * @dev This abstract contract provides getters and event emitting update functions for + * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. + * + * _Available since v4.1._ + * + * @custom:oz-upgrades-unsafe-allow delegatecall + */ +abstract contract ERC1967UpgradeUpgradeable is Initializable { + function __ERC1967Upgrade_init() internal onlyInitializing { + } + + function __ERC1967Upgrade_init_unchained() internal onlyInitializing { + } + // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 + bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; + + /** + * @dev Storage slot with the address of the current implementation. + * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is + * validated in the constructor. + */ + bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + /** + * @dev Emitted when the implementation is upgraded. + */ + event Upgraded(address indexed implementation); + + /** + * @dev Returns the current implementation address. + */ + function _getImplementation() internal view returns (address) { + return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; + } + + /** + * @dev Stores a new address in the EIP1967 implementation slot. + */ + function _setImplementation(address newImplementation) private { + require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); + StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + } + + /** + * @dev Perform implementation upgrade + * + * Emits an {Upgraded} event. + */ + function _upgradeTo(address newImplementation) internal { + _setImplementation(newImplementation); + emit Upgraded(newImplementation); + } + + /** + * @dev Perform implementation upgrade with additional setup call. + * + * Emits an {Upgraded} event. + */ + function _upgradeToAndCall( + address newImplementation, + bytes memory data, + bool forceCall + ) internal { + _upgradeTo(newImplementation); + if (data.length > 0 || forceCall) { + _functionDelegateCall(newImplementation, data); + } + } + + /** + * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. + * + * Emits an {Upgraded} event. + */ + function _upgradeToAndCallUUPS( + address newImplementation, + bytes memory data, + bool forceCall + ) internal { + // Upgrades from old implementations will perform a rollback test. This test requires the new + // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing + // this special case will break upgrade paths from old UUPS implementation to new ones. + if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { + _setImplementation(newImplementation); + } else { + try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { + require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); + } catch { + revert("ERC1967Upgrade: new implementation is not UUPS"); + } + _upgradeToAndCall(newImplementation, data, forceCall); + } + } + + /** + * @dev Storage slot with the admin of the contract. + * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is + * validated in the constructor. + */ + bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + /** + * @dev Emitted when the admin account has changed. + */ + event AdminChanged(address previousAdmin, address newAdmin); + + /** + * @dev Returns the current admin. + */ + function _getAdmin() internal view returns (address) { + return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; + } + + /** + * @dev Stores a new address in the EIP1967 admin slot. + */ + function _setAdmin(address newAdmin) private { + require(newAdmin != address(0), "ERC1967: new admin is the zero address"); + StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; + } + + /** + * @dev Changes the admin of the proxy. + * + * Emits an {AdminChanged} event. + */ + function _changeAdmin(address newAdmin) internal { + emit AdminChanged(_getAdmin(), newAdmin); + _setAdmin(newAdmin); + } + + /** + * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. + * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. + */ + bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; + + /** + * @dev Emitted when the beacon is upgraded. + */ + event BeaconUpgraded(address indexed beacon); + + /** + * @dev Returns the current beacon. + */ + function _getBeacon() internal view returns (address) { + return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; + } + + /** + * @dev Stores a new beacon in the EIP1967 beacon slot. + */ + function _setBeacon(address newBeacon) private { + require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); + require( + AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), + "ERC1967: beacon implementation is not a contract" + ); + StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; + } + + /** + * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does + * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). + * + * Emits a {BeaconUpgraded} event. + */ + function _upgradeBeaconToAndCall( + address newBeacon, + bytes memory data, + bool forceCall + ) internal { + _setBeacon(newBeacon); + emit BeaconUpgraded(newBeacon); + if (data.length > 0 || forceCall) { + _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); + } + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], + * but performing a delegate call. + * + * _Available since v3.4._ + */ + function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { + require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = target.delegatecall(data); + return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); + } + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[50] private __gap; +} + + +// File @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) + +pragma solidity ^0.8.0; + + + +/** + * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an + * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. + * + * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is + * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing + * `UUPSUpgradeable` with a custom implementation of upgrades. + * + * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. + * + * _Available since v4.1._ + */ +abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { + function __UUPSUpgradeable_init() internal onlyInitializing { + } + + function __UUPSUpgradeable_init_unchained() internal onlyInitializing { + } + /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment + address private immutable __self = address(this); + + /** + * @dev Check that the execution is being performed through a delegatecall call and that the execution context is + * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case + * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a + * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to + * fail. + */ + modifier onlyProxy() { + require(address(this) != __self, "Function must be called through delegatecall"); + require(_getImplementation() == __self, "Function must be called through active proxy"); + _; + } + + /** + * @dev Check that the execution is not being performed through a delegate call. This allows a function to be + * callable on the implementing contract but not through proxies. + */ + modifier notDelegated() { + require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); + _; + } + + /** + * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the + * implementation. It is used to validate that the this implementation remains valid after an upgrade. + * + * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks + * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this + * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. + */ + function proxiableUUID() external view virtual override notDelegated returns (bytes32) { + return _IMPLEMENTATION_SLOT; + } + + /** + * @dev Upgrade the implementation of the proxy to `newImplementation`. + * + * Calls {_authorizeUpgrade}. + * + * Emits an {Upgraded} event. + */ + function upgradeTo(address newImplementation) external virtual onlyProxy { + _authorizeUpgrade(newImplementation); + _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); + } + + /** + * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call + * encoded in `data`. + * + * Calls {_authorizeUpgrade}. + * + * Emits an {Upgraded} event. + */ + function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { + _authorizeUpgrade(newImplementation); + _upgradeToAndCallUUPS(newImplementation, data, true); + } + + /** + * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by + * {upgradeTo} and {upgradeToAndCall}. + * + * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. + * + * ```solidity + * function _authorizeUpgrade(address) internal override onlyOwner {} + * ``` + */ + function _authorizeUpgrade(address newImplementation) internal virtual; + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[50] private __gap; +} + + +// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 + +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Interface of the ERC20 standard as defined in the EIP. + */ +interface IERC20 { + /** + * @dev Returns the amount of tokens in existence. + */ + function totalSupply() external view returns (uint256); + + /** + * @dev Returns the amount of tokens owned by `account`. + */ + function balanceOf(address account) external view returns (uint256); + + /** + * @dev Moves `amount` tokens from the caller's account to `recipient`. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transfer(address recipient, uint256 amount) external returns (bool); + + /** + * @dev Returns the remaining number of tokens that `spender` will be + * allowed to spend on behalf of `owner` through {transferFrom}. This is + * zero by default. + * + * This value changes when {approve} or {transferFrom} are called. + */ + function allowance(address owner, address spender) external view returns (uint256); + + /** + * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * IMPORTANT: Beware that changing an allowance with this method brings the risk + * that someone may use both the old and the new allowance by unfortunate + * transaction ordering. One possible solution to mitigate this race + * condition is to first reduce the spender's allowance to 0 and set the + * desired value afterwards: + * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 + * + * Emits an {Approval} event. + */ + function approve(address spender, uint256 amount) external returns (bool); + + /** + * @dev Moves `amount` tokens from `sender` to `recipient` using the + * allowance mechanism. `amount` is then deducted from the caller's + * allowance. + * + * Returns a boolean value indicating whether the operation succeeded. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address sender, + address recipient, + uint256 amount + ) external returns (bool); + + /** + * @dev Emitted when `value` tokens are moved from one account (`from`) to + * another (`to`). + * + * Note that `value` may be zero. + */ + event Transfer(address indexed from, address indexed to, uint256 value); + + /** + * @dev Emitted when the allowance of a `spender` for an `owner` is set by + * a call to {approve}. `value` is the new allowance. + */ + event Approval(address indexed owner, address indexed spender, uint256 value); +} + + +// File contracts/access/IKOAccessControlsLookup.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + +interface IKOAccessControlsLookup { + function hasAdminRole(address _address) external view returns (bool); + + function isVerifiedArtist(uint256 _index, address _account, bytes32[] calldata _merkleProof) external view returns (bool); + + function isVerifiedArtistProxy(address _artist, address _proxy) external view returns (bool); + + function hasLegacyMinterRole(address _address) external view returns (bool); + + function hasContractRole(address _address) external view returns (bool); + + function hasContractOrAdminRole(address _address) external view returns (bool); +} + + +// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 + +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @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`. See the corresponding + * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] + * to learn more about how these ids are created. + * + * This function call must use less than 30 000 gas. + */ + function supportsInterface(bytes4 interfaceId) external view returns (bool); +} + + +// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.2.0 + +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/** + * @dev Required interface of an ERC721 compliant contract. + */ +interface IERC721 is IERC165 { + /** + * @dev Emitted when `tokenId` token is transferred from `from` to `to`. + */ + event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); + + /** + * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. + */ + event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); + + /** + * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. + */ + event ApprovalForAll(address indexed owner, address indexed operator, bool approved); + + /** + * @dev Returns the number of tokens in ``owner``'s account. + */ + function balanceOf(address owner) external view returns (uint256 balance); + + /** + * @dev Returns the owner of the `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function ownerOf(uint256 tokenId) external view returns (address owner); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients + * are aware of the ERC721 protocol to prevent tokens from being forever locked. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId + ) external; + + /** + * @dev Transfers `tokenId` token from `from` to `to`. + * + * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * + * Emits a {Transfer} event. + */ + function transferFrom( + address from, + address to, + uint256 tokenId + ) external; + + /** + * @dev Gives permission to `to` to transfer `tokenId` token to another account. + * The approval is cleared when the token is transferred. + * + * Only a single account can be approved at a time, so approving the zero address clears previous approvals. + * + * Requirements: + * + * - The caller must own the token or be an approved operator. + * - `tokenId` must exist. + * + * Emits an {Approval} event. + */ + function approve(address to, uint256 tokenId) external; + + /** + * @dev Returns the account approved for `tokenId` token. + * + * Requirements: + * + * - `tokenId` must exist. + */ + function getApproved(uint256 tokenId) external view returns (address operator); + + /** + * @dev Approve or remove `operator` as an operator for the caller. + * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. + * + * Requirements: + * + * - The `operator` cannot be the caller. + * + * Emits an {ApprovalForAll} event. + */ + function setApprovalForAll(address operator, bool _approved) external; + + /** + * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. + * + * See {setApprovalForAll} + */ + function isApprovedForAll(address owner, address operator) external view returns (bool); + + /** + * @dev Safely transfers `tokenId` token from `from` to `to`. + * + * Requirements: + * + * - `from` cannot be the zero address. + * - `to` cannot be the zero address. + * - `tokenId` token must exist and be owned by `from`. + * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. + * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. + * + * Emits a {Transfer} event. + */ + function safeTransferFrom( + address from, + address to, + uint256 tokenId, + bytes calldata data + ) external; +} + + +// File contracts/core/IERC2309.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + +/** + @title ERC-2309: ERC-721 Batch Mint Extension + @dev https://github.com/ethereum/EIPs/issues/2309 + */ +interface IERC2309 { + /** + @notice This event is emitted when ownership of a batch of tokens changes by any mechanism. + This includes minting, transferring, and burning. + + @dev The address executing the transaction MUST own all the tokens within the range of + fromTokenId and toTokenId, or MUST be an approved operator to act on the owners behalf. + The fromTokenId and toTokenId MUST be a sequential range of tokens IDs. + When minting/creating tokens, the `fromAddress` argument MUST be set to `0x0` (i.e. zero address). + When burning/destroying tokens, the `toAddress` argument MUST be set to `0x0` (i.e. zero address). + + @param fromTokenId The token ID that begins the batch of tokens being transferred + @param toTokenId The token ID that ends the batch of tokens being transferred + @param fromAddress The address transferring ownership of the specified range of tokens + @param toAddress The address receiving ownership of the specified range of tokens. + */ + event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress); +} + + +// File contracts/core/IERC2981.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + +/// @notice This is purely an extension for the KO platform +/// @notice Royalties on KO are defined at an edition level for all tokens from the same edition +interface IERC2981EditionExtension { + + /// @notice Does the edition have any royalties defined + function hasRoyalties(uint256 _editionId) external view returns (bool); + + /// @notice Get the royalty receiver - all royalties should be sent to this account if not zero address + function getRoyaltiesReceiver(uint256 _editionId) external view returns (address); +} + +/** + * ERC2981 standards interface for royalties + */ +interface IERC2981 is IERC165, IERC2981EditionExtension { + /// ERC165 bytes to add to interface array - set in parent contract + /// implementing this standard + /// + /// bytes4(keccak256("royaltyInfo(uint256,uint256)")) == 0x2a55205a + /// bytes4 private constant _INTERFACE_ID_ERC2981 = 0x2a55205a; + /// _registerInterface(_INTERFACE_ID_ERC2981); + + /// @notice Called with the sale price to determine how much royalty + // is owed and to whom. + /// @param _tokenId - the NFT asset queried for royalty information + /// @param _value - the sale price of the NFT asset specified by _tokenId + /// @return _receiver - address of who should be sent the royalty payment + /// @return _royaltyAmount - the royalty payment amount for _value sale price + function royaltyInfo( + uint256 _tokenId, + uint256 _value + ) external view returns ( + address _receiver, + uint256 _royaltyAmount + ); + +} + + +// File contracts/core/IHasSecondarySaleFees.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + +/// @title Royalties formats required for use on the Rarible platform +/// @dev https://docs.rarible.com/asset/royalties-schema +interface IHasSecondarySaleFees is IERC165 { + + event SecondarySaleFees(uint256 tokenId, address[] recipients, uint[] bps); + + function getFeeRecipients(uint256 id) external returns (address payable[] memory); + + function getFeeBps(uint256 id) external returns (uint[] memory); +} + + +// File contracts/core/IKODAV3.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + + + + + +/// @title Core KODA V3 functionality +interface IKODAV3 is +IERC165, // Contract introspection +IERC721, // Core NFTs +IERC2309, // Consecutive batch mint +IERC2981, // Royalties +IHasSecondarySaleFees // Rariable / Foundation royalties +{ + // edition utils + + function getCreatorOfEdition(uint256 _editionId) external view returns (address _originalCreator); + + function getCreatorOfToken(uint256 _tokenId) external view returns (address _originalCreator); + + function getSizeOfEdition(uint256 _editionId) external view returns (uint256 _size); + + function getEditionSizeOfToken(uint256 _tokenId) external view returns (uint256 _size); + + function editionExists(uint256 _editionId) external view returns (bool); + + // Has the edition been disabled / soft burnt + function isEditionSalesDisabled(uint256 _editionId) external view returns (bool); + + // Has the edition been disabled / soft burnt OR sold out + function isSalesDisabledOrSoldOut(uint256 _editionId) external view returns (bool); + + // Work out the max token ID for an edition ID + function maxTokenIdOfEdition(uint256 _editionId) external view returns (uint256 _tokenId); + + // Helper method for getting the next primary sale token from an edition starting low to high token IDs + function getNextAvailablePrimarySaleToken(uint256 _editionId) external returns (uint256 _tokenId); + + // Helper method for getting the next primary sale token from an edition starting high to low token IDs + function getReverseAvailablePrimarySaleToken(uint256 _editionId) external view returns (uint256 _tokenId); + + // Utility method to get all data needed for the next primary sale, low token ID to high + function facilitateNextPrimarySale(uint256 _editionId) external returns (address _receiver, address _creator, uint256 _tokenId); + + // Utility method to get all data needed for the next primary sale, high token ID to low + function facilitateReversePrimarySale(uint256 _editionId) external returns (address _receiver, address _creator, uint256 _tokenId); + + // Expanded royalty method for the edition, not token + function royaltyAndCreatorInfo(uint256 _editionId, uint256 _value) external returns (address _receiver, address _creator, uint256 _amount); + + // Allows the creator to correct mistakes until the first token from an edition is sold + function updateURIIfNoSaleMade(uint256 _editionId, string calldata _newURI) external; + + // Has any primary transfer happened from an edition + function hasMadePrimarySale(uint256 _editionId) external view returns (bool); + + // Has the edition sold out + function isEditionSoldOut(uint256 _editionId) external view returns (bool); + + // Toggle on/off the edition from being able to make sales + function toggleEditionSalesDisabled(uint256 _editionId) external; + + // token utils + + function exists(uint256 _tokenId) external view returns (bool); + + function getEditionIdOfToken(uint256 _tokenId) external pure returns (uint256 _editionId); + + function getEditionDetails(uint256 _tokenId) external view returns (address _originalCreator, address _owner, uint16 _size, uint256 _editionId, string memory _uri); + + function hadPrimarySaleOfToken(uint256 _tokenId) external view returns (bool); + +} + + +// File contracts/marketplace/BaseUpgradableMarketplace.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + + + + + +/// @notice Core logic and state shared between upgradable marketplaces +abstract contract BaseUpgradableMarketplace is ReentrancyGuardUpgradeable, PausableUpgradeable, UUPSUpgradeable { + + event AdminUpdateModulo(uint256 _modulo); + event AdminUpdatePlatformPrimaryCommission(uint256 newAmount); + event AdminUpdateMinBidAmount(uint256 _minBidAmount); + event AdminUpdateAccessControls(IKOAccessControlsLookup indexed _oldAddress, IKOAccessControlsLookup indexed _newAddress); + event AdminUpdateBidLockupPeriod(uint256 _bidLockupPeriod); + event AdminUpdatePlatformAccount(address indexed _oldAddress, address indexed _newAddress); + event AdminRecoverERC20(IERC20 indexed _token, address indexed _recipient, uint256 _amount); + event AdminRecoverETH(address payable indexed _recipient, uint256 _amount); + + event BidderRefunded(uint256 indexed _id, address _bidder, uint256 _bid, address _newBidder, uint256 _newOffer); + event BidderRefundedFailed(uint256 indexed _id, address _bidder, uint256 _bid, address _newBidder, uint256 _newOffer); + + // KO Commission override definition for a given item + struct KOCommissionOverride { + bool active; + uint256 koCommission; + } + + // Only admin defined in the access controls contract + modifier onlyAdmin() { + require(accessControls.hasAdminRole(_msgSender()), "Caller not admin"); + _; + } + + modifier onlyCreatorContractOrAdmin(uint256 _editionId) { + require( + koda.getCreatorOfEdition(_editionId) == _msgSender() || accessControls.hasContractOrAdminRole(_msgSender()), + "Caller not creator or admin" + ); + _; + } + + /// @notice Address of the access control contract + IKOAccessControlsLookup public accessControls; + + /// @notice KODA V3 token + IKODAV3 public koda; + + /// @notice platform funds collector + address public platformAccount; + + /// @notice precision 100.00000% + uint256 public modulo; + + /// @notice Minimum bid / minimum list amount + uint256 public minBidAmount; + + /// @notice Bid lockup period + uint256 public bidLockupPeriod; + + /// @notice Primary commission percentage + uint256 public platformPrimaryCommission; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() initializer {} + + function initialize(IKOAccessControlsLookup _accessControls, IKODAV3 _koda, address _platformAccount) public initializer { + __ReentrancyGuard_init(); + __Pausable_init(); + + accessControls = _accessControls; + koda = _koda; + platformAccount = _platformAccount; + + // initial values for adjustable vars + modulo = 100_00000; + platformPrimaryCommission = 15_00000; + minBidAmount = 0.01 ether; + bidLockupPeriod = 6 hours; + } + + function _authorizeUpgrade(address newImplementation) internal view override { + require(accessControls.hasAdminRole(msg.sender), "Only admin can upgrade"); + } + + function recoverERC20(IERC20 _token, address _recipient, uint256 _amount) public onlyAdmin { + _token.transfer(_recipient, _amount); + emit AdminRecoverERC20(_token, _recipient, _amount); + } + + function recoverStuckETH(address payable _recipient, uint256 _amount) public onlyAdmin { + (bool success,) = _recipient.call{value : _amount}(""); + require(success, "Unable to send recipient ETH"); + emit AdminRecoverETH(_recipient, _amount); + } + + function updatePlatformPrimaryCommission(uint256 _newAmount) external onlyAdmin { + platformPrimaryCommission = _newAmount; + emit AdminUpdatePlatformPrimaryCommission(_newAmount); + } + + function updateAccessControls(IKOAccessControlsLookup _accessControls) public onlyAdmin { + require(_accessControls.hasAdminRole(_msgSender()), "Sender must have admin role in new contract"); + emit AdminUpdateAccessControls(accessControls, _accessControls); + accessControls = _accessControls; + } + + function updateModulo(uint256 _modulo) public onlyAdmin { + require(_modulo > 0, "Modulo point cannot be zero"); + modulo = _modulo; + emit AdminUpdateModulo(_modulo); + } + + function updateMinBidAmount(uint256 _minBidAmount) public onlyAdmin { + minBidAmount = _minBidAmount; + emit AdminUpdateMinBidAmount(_minBidAmount); + } + + function updateBidLockupPeriod(uint256 _bidLockupPeriod) public onlyAdmin { + bidLockupPeriod = _bidLockupPeriod; + emit AdminUpdateBidLockupPeriod(_bidLockupPeriod); + } + + function updatePlatformAccount(address _newPlatformAccount) public onlyAdmin { + emit AdminUpdatePlatformAccount(platformAccount, _newPlatformAccount); + platformAccount = _newPlatformAccount; + } + + function pause() public onlyAdmin { + super._pause(); + } + + function unpause() public onlyAdmin { + super._unpause(); + } + + function _getLockupTime() internal view returns (uint256 lockupUntil) { + lockupUntil = block.timestamp + bidLockupPeriod; + } + + function _handleSaleFunds(address _fundsReceiver, uint256 _platformCommission) internal { + uint256 koCommission = (msg.value / modulo) * _platformCommission; + if (koCommission > 0) { + (bool koCommissionSuccess,) = platformAccount.call{value : koCommission}(""); + require(koCommissionSuccess, "commission payment failed"); + } + (bool success,) = _fundsReceiver.call{value : msg.value - koCommission}(""); + require(success, "payment failed"); + } + + function _refundBidder(uint256 _id, address _receiver, uint256 _paymentAmount, address _newBidder, uint256 _newOffer) internal { + (bool success,) = _receiver.call{value : _paymentAmount}(""); + if (!success) { + emit BidderRefundedFailed(_id, _receiver, _paymentAmount, _newBidder, _newOffer); + } else { + emit BidderRefunded(_id, _receiver, _paymentAmount, _newBidder, _newOffer); + } + } + +} + + +// File contracts/marketplace/IKODAV3Marketplace.sol + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; + +interface IBuyNowMarketplace { + event ListedForBuyNow(uint256 indexed _id, uint256 _price, address _currentOwner, uint256 _startDate); + event BuyNowPriceChanged(uint256 indexed _id, uint256 _price); + event BuyNowDeListed(uint256 indexed _id); + event BuyNowPurchased(uint256 indexed _tokenId, address _buyer, address _currentOwner, uint256 _price); + + function listForBuyNow(address _creator, uint256 _id, uint128 _listingPrice, uint128 _startDate) external; + + function buyEditionToken(uint256 _id) external payable; + function buyEditionTokenFor(uint256 _id, address _recipient) external payable; + + function setBuyNowPriceListing(uint256 _editionId, uint128 _listingPrice) external; +} + +interface IEditionOffersMarketplace { + event EditionAcceptingOffer(uint256 indexed _editionId, uint128 _startDate); + event EditionBidPlaced(uint256 indexed _editionId, address _bidder, uint256 _amount); + event EditionBidWithdrawn(uint256 indexed _editionId, address _bidder); + event EditionBidAccepted(uint256 indexed _editionId, uint256 indexed _tokenId, address _bidder, uint256 _amount); + event EditionBidRejected(uint256 indexed _editionId, address _bidder, uint256 _amount); + event EditionConvertedFromOffersToBuyItNow(uint256 _editionId, uint128 _price, uint128 _startDate); + + function enableEditionOffers(uint256 _editionId, uint128 _startDate) external; + + function placeEditionBid(uint256 _editionId) external payable; + function placeEditionBidFor(uint256 _editionId, address _bidder) external payable; + + function withdrawEditionBid(uint256 _editionId) external; + + function rejectEditionBid(uint256 _editionId) external; + + function acceptEditionBid(uint256 _editionId, uint256 _offerPrice) external; + + function convertOffersToBuyItNow(uint256 _editionId, uint128 _listingPrice, uint128 _startDate) external; +} + +interface IEditionSteppedMarketplace { + event EditionSteppedSaleListed(uint256 indexed _editionId, uint128 _basePrice, uint128 _stepPrice, uint128 _startDate); + event EditionSteppedSaleBuy(uint256 indexed _editionId, uint256 indexed _tokenId, address _buyer, uint256 _price, uint16 _currentStep); + event EditionSteppedAuctionUpdated(uint256 indexed _editionId, uint128 _basePrice, uint128 _stepPrice); + + function listSteppedEditionAuction(address _creator, uint256 _editionId, uint128 _basePrice, uint128 _stepPrice, uint128 _startDate) external; + + function buyNextStep(uint256 _editionId) external payable; + function buyNextStepFor(uint256 _editionId, address _buyer) external payable; + + function convertSteppedAuctionToListing(uint256 _editionId, uint128 _listingPrice, uint128 _startDate) external; + + function convertSteppedAuctionToOffers(uint256 _editionId, uint128 _startDate) external; + + function updateSteppedAuction(uint256 _editionId, uint128 _basePrice, uint128 _stepPrice) external; +} + +interface IReserveAuctionMarketplace { + event ListedForReserveAuction(uint256 indexed _id, uint256 _reservePrice, uint128 _startDate); + event BidPlacedOnReserveAuction(uint256 indexed _id, address _currentOwner, address _bidder, uint256 _amount, uint256 _originalBiddingEnd, uint256 _currentBiddingEnd); + event ReserveAuctionResulted(uint256 indexed _id, uint256 _finalPrice, address _currentOwner, address _winner, address _resulter); + event BidWithdrawnFromReserveAuction(uint256 _id, address _bidder, uint128 _bid); + event ReservePriceUpdated(uint256 indexed _id, uint256 _reservePrice); + event ReserveAuctionConvertedToBuyItNow(uint256 indexed _id, uint128 _listingPrice, uint128 _startDate); + event EmergencyBidWithdrawFromReserveAuction(uint256 indexed _id, address _bidder, uint128 _bid); + + function placeBidOnReserveAuction(uint256 _id) external payable; + function placeBidOnReserveAuctionFor(uint256 _id, address _bidder) external payable; + + function listForReserveAuction(address _creator, uint256 _id, uint128 _reservePrice, uint128 _startDate) external; + + function resultReserveAuction(uint256 _id) external; + + function withdrawBidFromReserveAuction(uint256 _id) external; + + function updateReservePriceForReserveAuction(uint256 _id, uint128 _reservePrice) external; + + function emergencyExitBidFromReserveAuction(uint256 _id) external; +} + +interface IKODAV3PrimarySaleMarketplace is IEditionSteppedMarketplace, IEditionOffersMarketplace, IBuyNowMarketplace, IReserveAuctionMarketplace { + function convertReserveAuctionToBuyItNow(uint256 _editionId, uint128 _listingPrice, uint128 _startDate) external; + + function convertReserveAuctionToOffers(uint256 _editionId, uint128 _startDate) external; +} + +interface ITokenBuyNowMarketplace { + event TokenDeListed(uint256 indexed _tokenId); + + function delistToken(uint256 _tokenId) external; +} + +interface ITokenOffersMarketplace { + event TokenBidPlaced(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + event TokenBidAccepted(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + event TokenBidRejected(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + event TokenBidWithdrawn(uint256 indexed _tokenId, address _bidder); + + function acceptTokenBid(uint256 _tokenId, uint256 _offerPrice) external; + + function rejectTokenBid(uint256 _tokenId) external; + + function withdrawTokenBid(uint256 _tokenId) external; + + function placeTokenBid(uint256 _tokenId) external payable; + function placeTokenBidFor(uint256 _tokenId, address _bidder) external payable; +} + +interface IBuyNowSecondaryMarketplace { + function listTokenForBuyNow(uint256 _tokenId, uint128 _listingPrice, uint128 _startDate) external; +} + +interface IEditionOffersSecondaryMarketplace { + event EditionBidPlaced(uint256 indexed _editionId, address indexed _bidder, uint256 _bid); + event EditionBidWithdrawn(uint256 indexed _editionId, address _bidder); + event EditionBidAccepted(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + + function placeEditionBid(uint256 _editionId) external payable; + function placeEditionBidFor(uint256 _editionId, address _bidder) external payable; + + function withdrawEditionBid(uint256 _editionId) external; + + function acceptEditionBid(uint256 _tokenId, uint256 _offerPrice) external; +} + +interface IKODAV3SecondarySaleMarketplace is ITokenBuyNowMarketplace, ITokenOffersMarketplace, IEditionOffersSecondaryMarketplace, IBuyNowSecondaryMarketplace { + function convertReserveAuctionToBuyItNow(uint256 _tokenId, uint128 _listingPrice, uint128 _startDate) external; + + function convertReserveAuctionToOffers(uint256 _tokenId) external; +} + +interface IKODAV3GatedMarketplace { + + function createSale(uint256 _editionId) external; + + function createPhase( + uint256 _editionId, + uint128 _startTime, + uint128 _endTime, + uint128 _priceInWei, + uint16 _mintCap, + uint16 _walletMintLimit, + bytes32 _merkleRoot, + string calldata _merkleIPFSHash + ) external; + + function createSaleWithPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function createPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function removePhase(uint256 _editionId, uint256 _phaseId) external; +} + + +// File hardhat/console.sol@v2.9.1 + +// SPDX-License-Identifier: MIT +pragma solidity >= 0.4.22 <0.9.0; + +library console { + address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); + + function _sendLogPayload(bytes memory payload) private view { + uint256 payloadLength = payload.length; + address consoleAddress = CONSOLE_ADDRESS; + assembly { + let payloadStart := add(payload, 32) + let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) + } + } + + function log() internal view { + _sendLogPayload(abi.encodeWithSignature("log()")); + } + + function logInt(int p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); + } + + function logUint(uint p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); + } + + function logString(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function logBool(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function logAddress(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function logBytes(bytes memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); + } + + function logBytes1(bytes1 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); + } + + function logBytes2(bytes2 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); + } + + function logBytes3(bytes3 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); + } + + function logBytes4(bytes4 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); + } + + function logBytes5(bytes5 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); + } + + function logBytes6(bytes6 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); + } + + function logBytes7(bytes7 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); + } + + function logBytes8(bytes8 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); + } + + function logBytes9(bytes9 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); + } + + function logBytes10(bytes10 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); + } + + function logBytes11(bytes11 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); + } + + function logBytes12(bytes12 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); + } + + function logBytes13(bytes13 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); + } + + function logBytes14(bytes14 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); + } + + function logBytes15(bytes15 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); + } + + function logBytes16(bytes16 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); + } + + function logBytes17(bytes17 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); + } + + function logBytes18(bytes18 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); + } + + function logBytes19(bytes19 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); + } + + function logBytes20(bytes20 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); + } + + function logBytes21(bytes21 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); + } + + function logBytes22(bytes22 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); + } + + function logBytes23(bytes23 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); + } + + function logBytes24(bytes24 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); + } + + function logBytes25(bytes25 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); + } + + function logBytes26(bytes26 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); + } + + function logBytes27(bytes27 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); + } + + function logBytes28(bytes28 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); + } + + function logBytes29(bytes29 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); + } + + function logBytes30(bytes30 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); + } + + function logBytes31(bytes31 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); + } + + function logBytes32(bytes32 p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); + } + + function log(uint p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); + } + + function log(string memory p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); + } + + function log(bool p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); + } + + function log(address p0) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); + } + + function log(uint p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); + } + + function log(uint p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); + } + + function log(uint p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); + } + + function log(uint p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); + } + + function log(string memory p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); + } + + function log(string memory p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); + } + + function log(string memory p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); + } + + function log(string memory p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); + } + + function log(bool p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); + } + + function log(bool p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); + } + + function log(bool p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); + } + + function log(bool p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); + } + + function log(address p0, uint p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); + } + + function log(address p0, string memory p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); + } + + function log(address p0, bool p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); + } + + function log(address p0, address p1) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); + } + + function log(uint p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); + } + + function log(uint p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); + } + + function log(uint p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); + } + + function log(uint p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); + } + + function log(uint p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); + } + + function log(uint p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); + } + + function log(uint p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); + } + + function log(uint p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); + } + + function log(uint p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); + } + + function log(uint p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); + } + + function log(uint p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); + } + + function log(uint p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); + } + + function log(uint p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); + } + + function log(string memory p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); + } + + function log(string memory p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); + } + + function log(string memory p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); + } + + function log(string memory p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); + } + + function log(string memory p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); + } + + function log(string memory p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); + } + + function log(string memory p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); + } + + function log(bool p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); + } + + function log(bool p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); + } + + function log(bool p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); + } + + function log(bool p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); + } + + function log(bool p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); + } + + function log(bool p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); + } + + function log(bool p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); + } + + function log(bool p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); + } + + function log(bool p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); + } + + function log(bool p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); + } + + function log(bool p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); + } + + function log(bool p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); + } + + function log(bool p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); + } + + function log(address p0, uint p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); + } + + function log(address p0, uint p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); + } + + function log(address p0, uint p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); + } + + function log(address p0, uint p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); + } + + function log(address p0, string memory p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); + } + + function log(address p0, string memory p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); + } + + function log(address p0, string memory p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); + } + + function log(address p0, string memory p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); + } + + function log(address p0, bool p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); + } + + function log(address p0, bool p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); + } + + function log(address p0, bool p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); + } + + function log(address p0, bool p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); + } + + function log(address p0, address p1, uint p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); + } + + function log(address p0, address p1, string memory p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); + } + + function log(address p0, address p1, bool p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); + } + + function log(address p0, address p1, address p2) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); + } + + function log(uint p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); + } + + function log(uint p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); + } + + function log(string memory p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); + } + + function log(bool p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, uint p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, string memory p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, bool p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, uint p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, string memory p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, bool p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, uint p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, string memory p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, bool p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); + } + + function log(address p0, address p1, address p2, address p3) internal view { + _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); + } + +} + + +// File contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; + + + + +contract KODAV3UpgradableGatedMarketplace is IKODAV3GatedMarketplace, BaseUpgradableMarketplace { + + /// @notice emitted when admin updates funds receiver + event AdminUpdateFundReceiver(uint256 indexed _saleId, address _newFundsReceiver); + + /// @notice emitted when admin updates max edition ID + event AdminUpdateMaxEditionId(uint256 indexed _saleId, uint256 _newMaxEditionId); + + /// @notice emitted when admin updates creator + event AdminUpdateCreator(uint256 indexed _saleId, address _newCreator); + + /// @notice emitted when gated sale commission is updated for a given sale + event AdminSetKoCommissionOverrideForSale(uint256 indexed _saleId, uint256 _platformPrimarySaleCommission); + + /// @notice emitted when a sale is paused + event SalePaused(uint256 indexed _saleId); + + /// @notice emitted when a sale is resumed + event SaleResumed(uint256 indexed _saleId); + + /// @notice emitted when a sale and its phases are created + event SaleWithPhaseCreated(uint256 indexed _saleId); + + /// @notice emitted when a sale without any phases created + event SaleCreated(uint256 indexed _saleId); + + /// @notice emitted when a new phase is added to a sale + event PhaseCreated(uint256 indexed _saleId, uint256 indexed _phaseId); + + /// @notice emitted when a phase is removed from a sale + event PhaseRemoved(uint256 indexed _saleId, uint256 indexed _phaseId); + + /// @notice emitted when someone mints from a sale + event MintFromSale(uint256 indexed _saleId, uint256 indexed _phaseId, uint256 indexed _tokenId, address _recipient); + + /// @notice Phase represents a time structured part of a sale, i.e. VIP, pre sale or open sale + struct Phase { + uint128 startTime; // The start time of the sale as a whole + uint128 endTime; // The end time of the sale phase, also the beginning of the next phase if applicable + uint128 priceInWei; // Price in wei for one mint + uint16 mintCounter; // The current amount of items minted + uint16 mintCap; // The maximum amount of mints for the phase + uint16 walletMintLimit; // The mint limit per wallet for the phase + bytes32 merkleRoot; // The merkle tree root for the phase + string merkleIPFSHash; // The IPFS hash referencing the merkle tree + } + + /// @notice Sale represents a gated sale, with mapping links to different sale phases + struct Sale { + uint256 id; // The ID of the sale + uint256 editionId; // The ID of the edition the sale will mint + address creator; // Set on creation to save gas - the original edition creator + address fundsReceiver; // Where are the funds set + uint256 maxEditionId; // Stores the max edition ID for the edition - used when assigning tokens + uint16 mintCounter; // Keeps a pointer to the overall mint count for the full sale + uint8 paused; // Whether the sale is currently paused > 0 is paused + } + + /// @notice sale Id -> KO commission override + mapping(uint256 => KOCommissionOverride) public koCommissionOverrideForSale; + + /// @dev incremental counter for the ID of a sale + uint256 public saleIdCounter; + + /// @dev totalMints is a mapping of hash(sale id, phase id, address) => total minted by that address + mapping(bytes32 => uint256) public totalMints; + + /// @dev edition to sale is a mapping of edition id => sale id + mapping(uint256 => uint256) public editionToSale; + + /// @dev sales is a mapping of sale id => Sale + mapping(uint256 => Sale) public sales; + + /// @dev phases is a mapping of sale id => array of associated phases + mapping(uint256 => Phase[]) public phases; + + /// @notice Allow an artist or admin to create a sale with 1 or more phases + function createSaleWithPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external override whenNotPaused { + address creator = koda.getCreatorOfEdition(_editionId); + require( + creator == _msgSender() || accessControls.hasContractOrAdminRole(_msgSender()), + "Caller not creator or admin" + ); + + // Check no existing sale in place + require(editionToSale[_editionId] == 0, "Sale exists for this edition"); + + uint256 saleId = _createSale(_editionId, creator); + + _addMultiplePhasesToSale( + saleId, + _startTimes, + _endTimes, + _pricesInWei, + _mintCaps, + _walletMintLimits, + _merkleRoots, + _merkleIPFSHashes + ); + + emit SaleWithPhaseCreated(saleId); + } + + /// @notice Allow an artist or admin to create a sale with 0 phases + function createSale(uint256 _editionId) external override whenNotPaused { + address creator = koda.getCreatorOfEdition(_editionId); + require( + creator == _msgSender() || accessControls.hasContractOrAdminRole(_msgSender()), + "Caller not creator or admin" + ); + + // Check no existing sale in place + require(editionToSale[_editionId] == 0, "Sale exists for this edition"); + + uint256 saleId = _createSale(_editionId, creator); + + emit SaleCreated(saleId); + } + + function _createSale(uint256 _editionId, address _creator) internal returns (uint256) { + uint256 saleId = ++saleIdCounter; + + // Assign the sale to the sales and editionToSale mappings + sales[saleId] = Sale({ + id : saleId, + creator : _creator, + fundsReceiver : koda.getRoyaltiesReceiver(_editionId), + editionId : _editionId, + maxEditionId : koda.maxTokenIdOfEdition(_editionId) - 1, + paused : 0, + mintCounter : 0 + }); + + editionToSale[_editionId] = saleId; + + return saleId; + } + + /// @notice Mint an NFT from the gated list + function mint( + uint256 _saleId, + uint256 _phaseId, + uint16 _mintCount, + uint256 _index, + bytes32[] calldata _merkleProof + ) payable external nonReentrant whenNotPaused { + Sale storage sale = sales[_saleId]; + require(sale.paused == 0, 'Sale is paused'); + + Phase storage phase = phases[_saleId][_phaseId]; + + require(block.timestamp >= phase.startTime && block.timestamp < phase.endTime, 'Sale phase not in progress'); + require(phase.mintCounter + _mintCount <= phase.mintCap, 'Phase mint cap reached'); + + bytes32 totalMintsKey = keccak256(abi.encode(_saleId, _phaseId, _msgSender())); + + require(totalMints[totalMintsKey] + _mintCount <= phase.walletMintLimit, 'Cannot exceed total mints for sale phase'); + require(msg.value >= phase.priceInWei * _mintCount, 'Not enough wei sent to complete mint'); + require(onPhaseMintList(_saleId, _phaseId, _index, _msgSender(), _merkleProof), 'Address not able to mint from sale'); + + handleMint(_saleId, _phaseId, sale.editionId, _mintCount, _msgSender()); + + // Up the mint count for the user and the phase mint counter + totalMints[totalMintsKey] += _mintCount; + phase.mintCounter += _mintCount; + sale.mintCounter += _mintCount; + } + + function createPhase( + uint256 _editionId, + uint128 _startTime, + uint128 _endTime, + uint128 _priceInWei, + uint16 _mintCap, + uint16 _walletMintLimit, + bytes32 _merkleRoot, + string calldata _merkleIPFSHash + ) + external override whenNotPaused onlyCreatorContractOrAdmin(_editionId) { + uint256 saleId = editionToSale[_editionId]; + require(saleId > 0, 'No sale associated with edition id'); + + _addPhaseToSale( + saleId, + _startTime, + _endTime, + _priceInWei, + _mintCap, + _walletMintLimit, + _merkleRoot, + _merkleIPFSHash + ); + } + + function createPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) + external override onlyCreatorContractOrAdmin(_editionId) whenNotPaused { + + // Ensure sale is valid + uint256 saleId = editionToSale[_editionId]; + require(saleId > 0, 'No sale associated with edition id'); + + _addMultiplePhasesToSale( + saleId, + _startTimes, + _endTimes, + _pricesInWei, + _mintCaps, + _walletMintLimits, + _merkleRoots, + _merkleIPFSHashes + ); + } + + function removePhase(uint256 _editionId, uint256 _phaseId) + external override onlyCreatorContractOrAdmin(_editionId) { + require(koda.editionExists(_editionId), 'Edition does not exist'); + + uint256 saleId = editionToSale[_editionId]; + require(saleId > 0, 'No sale associated with edition id'); + + delete phases[saleId][_phaseId]; + + emit PhaseRemoved(saleId, _phaseId); + } + + /// @dev checks whether a given user is on the list to mint from a phase + function onPhaseMintList(uint256 _saleId, uint256 _phaseId, uint256 _index, address _account, bytes32[] calldata _merkleProof) + public view returns (bool) { + Phase storage phase = phases[_saleId][_phaseId]; + // assume balance of 1 for enabled with access to the sale + bytes32 node = keccak256(abi.encodePacked(_index, _account, uint256(1))); + return MerkleProof.verify(_merkleProof, phase.merkleRoot, node); + } + + function toggleSalePause(uint256 _saleId, uint256 _editionId) external onlyCreatorContractOrAdmin(_editionId) { + if (sales[_saleId].paused != 0) { + sales[_saleId].paused = 0; + emit SaleResumed(_saleId); + } else { + sales[_saleId].paused = 1; + emit SalePaused(_saleId); + } + } + + function remainingPhaseMintAllowance(uint256 _saleId, uint256 _phaseId, uint256 _index, address _account, bytes32[] calldata _merkleProof) + external view returns (uint256) { + require(onPhaseMintList(_saleId, _phaseId, _index, _account, _merkleProof), 'Address not able to mint from sale'); + + return phases[_saleId][_phaseId].walletMintLimit - totalMints[keccak256(abi.encode(_saleId, _phaseId, _account))]; + } + + function handleMint( + uint256 _saleId, + uint256 _phaseId, + uint256 _editionId, + uint16 _mintCount, + address _recipient + ) internal { + require(_mintCount > 0, "Nothing being minted"); + + address creator = sales[_saleId].creator; + uint256 startId = sales[_saleId].maxEditionId - sales[_saleId].mintCounter; + + for (uint256 i; i < _mintCount; ++i) { + uint256 tokenId = getNextAvailablePrimarySaleToken(startId, _editionId, creator); + + // send token to buyer (assumes approval has been made, if not then this will fail) + koda.safeTransferFrom(creator, _recipient, tokenId); + + emit MintFromSale(_saleId, _phaseId, tokenId, _recipient); + + unchecked {startId = tokenId--;} + } + _handleSaleFunds(sales[_saleId].fundsReceiver, getPlatformSaleCommissionForSale(_saleId)); + } + + function getPlatformSaleCommissionForSale(uint256 _saleId) internal view returns (uint256) { + if (koCommissionOverrideForSale[_saleId].active) { + return koCommissionOverrideForSale[_saleId].koCommission; + } + return platformPrimaryCommission; + } + + function getNextAvailablePrimarySaleToken(uint256 _startId, uint256 _editionId, address creator) internal view returns (uint256 _tokenId) { + for (uint256 tokenId = _startId; tokenId >= _editionId; --tokenId) { + if (koda.ownerOf(tokenId) == creator) { + return tokenId; + } + } + revert("Primary market exhausted"); + } + + function _addMultiplePhasesToSale( + uint256 _saleId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) internal { + uint256 numOfPhases = _startTimes.length; + for (uint256 i; i < numOfPhases; ++i) { + _addPhaseToSale( + _saleId, + _startTimes[i], + _endTimes[i], + _pricesInWei[i], + _mintCaps[i], + _walletMintLimits[i], + _merkleRoots[i], + _merkleIPFSHashes[i] + ); + } + } + + function _addPhaseToSale( + uint256 _saleId, + uint128 _startTime, + uint128 _endTime, + uint128 _priceInWei, + uint16 _mintCap, + uint16 _walletMintLimit, + bytes32 _merkleRoot, + string memory _merkleIPFSHash + ) internal { + require(_endTime > _startTime, 'Phase end time must be after start time'); + require(_walletMintLimit > 0, 'Zero mint limit'); + require(_mintCap > 0, "Zero mint cap"); + require(_merkleRoot != bytes32(0), "Zero merkle root"); + require(bytes(_merkleIPFSHash).length == 46, "Invalid IPFS hash"); + + // Add the phase to the phases mapping + phases[_saleId].push(Phase({ + startTime : _startTime, + endTime : _endTime, + priceInWei : _priceInWei, + mintCounter : 0, + mintCap : _mintCap, + walletMintLimit : _walletMintLimit, + merkleRoot : _merkleRoot, + merkleIPFSHash : _merkleIPFSHash + })); + + emit PhaseCreated(_saleId, phases[_saleId].length - 1); + } + + function updateFundsReceiver(uint256 _saleId, address _newFundsReceiver) public onlyAdmin { + require(_newFundsReceiver != address(0), "Unable to send funds to invalid address"); + sales[_saleId].fundsReceiver = _newFundsReceiver; + emit AdminUpdateFundReceiver(_saleId, _newFundsReceiver); + } + + function updateMaxEditionId(uint256 _saleId, uint256 _newMaxEditionId) public onlyAdmin { + require(_newMaxEditionId >= 1, "Unable to set max edition"); + sales[_saleId].maxEditionId = _newMaxEditionId; + emit AdminUpdateMaxEditionId(_saleId, _newMaxEditionId); + } + + function updateCreator(uint256 _saleId, address _newCreator) public onlyAdmin { + require(_newCreator != address(0), "Unable to make invalid address creator"); + sales[_saleId].creator = _newCreator; + emit AdminUpdateCreator(_saleId, _newCreator); + } + + function setKoCommissionOverrideForSale(uint256 _saleId, bool _active, uint256 _koCommission) public onlyAdmin { + KOCommissionOverride storage koCommissionOverride = koCommissionOverrideForSale[_saleId]; + koCommissionOverride.active = _active; + koCommissionOverride.koCommission = _koCommission; + emit AdminSetKoCommissionOverrideForSale(_saleId, _koCommission); + } +} diff --git a/contracts-flat/KnownOriginDigitalAssetV3.sol b/contracts-flat/KnownOriginDigitalAssetV3.sol index fabc3738..a7eb1c7f 100644 --- a/contracts-flat/KnownOriginDigitalAssetV3.sol +++ b/contracts-flat/KnownOriginDigitalAssetV3.sol @@ -1,4 +1,6 @@ -// File: @openzeppelin/contracts/utils/introspection/IERC165.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 // SPDX-License-Identifier: MIT @@ -25,13 +27,13 @@ interface IERC165 { function supportsInterface(bytes4 interfaceId) external view returns (bool); } -// File: @openzeppelin/contracts/utils/introspection/ERC165.sol +// File @openzeppelin/contracts/utils/introspection/ERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Implementation of the {IERC165} interface. * @@ -55,13 +57,13 @@ abstract contract ERC165 is IERC165 { } } -// File: @openzeppelin/contracts/utils/introspection/ERC165Storage.sol +// File @openzeppelin/contracts/utils/introspection/ERC165Storage.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Storage based implementation of the {IERC165} interface. * @@ -98,9 +100,10 @@ abstract contract ERC165Storage is ERC165 { } } -// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol +// File @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -127,9 +130,10 @@ interface IERC721Receiver { ) external returns (bytes4); } -// File: @openzeppelin/contracts/utils/Address.sol +// File @openzeppelin/contracts/utils/Address.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -340,9 +344,10 @@ library Address { } } -// File: contracts/access/IKOAccessControlsLookup.sol +// File contracts/access/IKOAccessControlsLookup.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -360,13 +365,13 @@ interface IKOAccessControlsLookup { function hasContractOrAdminRole(address _address) external view returns (bool); } -// File: contracts/core/IERC2981.sol +// File contracts/core/IERC2981.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @notice This is purely an extension for the KO platform /// @notice Royalties on KO are defined at an edition level for all tokens from the same edition interface IERC2981EditionExtension { @@ -405,9 +410,10 @@ interface IERC2981 is IERC165, IERC2981EditionExtension { } -// File: contracts/core/IKODAV3Minter.sol +// File contracts/core/IKODAV3Minter.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -420,9 +426,10 @@ interface IKODAV3Minter { function mintConsecutiveBatchEdition(uint16 _editionSize, address _to, string calldata _uri) external returns (uint256 _editionId); } -// File: contracts/programmable/ITokenUriResolver.sol +// File contracts/programmable/ITokenUriResolver.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -435,9 +442,10 @@ interface ITokenUriResolver { function isDefined(uint256 _editionId, uint256 _tokenId) external view returns (bool); } -// File: @openzeppelin/contracts/token/ERC20/IERC20.sol +// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -519,13 +527,13 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -// File: @openzeppelin/contracts/token/ERC721/IERC721.sol +// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Required interface of an ERC721 compliant contract. */ @@ -663,9 +671,10 @@ interface IERC721 is IERC165 { ) external; } -// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol +// File @openzeppelin/contracts/utils/structs/EnumerableSet.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -960,9 +969,10 @@ library EnumerableSet { } } -// File: @openzeppelin/contracts/security/ReentrancyGuard.sol +// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -1025,9 +1035,10 @@ abstract contract ReentrancyGuard { } } -// File: @openzeppelin/contracts/utils/Context.sol +// File @openzeppelin/contracts/utils/Context.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -1051,9 +1062,10 @@ abstract contract Context { } } -// File: contracts/core/IERC2309.sol +// File contracts/core/IERC2309.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1080,13 +1092,13 @@ interface IERC2309 { event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress); } -// File: contracts/core/IHasSecondarySaleFees.sol +// File contracts/core/IHasSecondarySaleFees.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @title Royalties formats required for use on the Rarible platform /// @dev https://docs.rarible.com/asset/royalties-schema interface IHasSecondarySaleFees is IERC165 { @@ -1098,9 +1110,10 @@ interface IHasSecondarySaleFees is IERC165 { function getFeeBps(uint256 id) external returns (uint[] memory); } -// File: contracts/core/IKODAV3.sol +// File contracts/core/IKODAV3.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1108,7 +1121,6 @@ pragma solidity 0.8.4; - /// @title Core KODA V3 functionality interface IKODAV3 is IERC165, // Contract introspection @@ -1177,9 +1189,10 @@ IHasSecondarySaleFees // Rariable / Foundation royalties } -// File: contracts/core/composable/TopDownERC20Composable.sol +// File contracts/core/composable/TopDownERC20Composable.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1188,7 +1201,6 @@ pragma solidity 0.8.4; - interface ERC998ERC20TopDown { event ReceivedERC20(address indexed _from, uint256 indexed _tokenId, address indexed _erc20Contract, uint256 _value); event ReceivedERC20ForEdition(address indexed _from, uint256 indexed _editionId, address indexed _erc20Contract, uint256 _value); @@ -1385,14 +1397,14 @@ abstract contract TopDownERC20Composable is ERC998ERC20TopDown, ERC998ERC20TopDo } } -// File: contracts/core/composable/TopDownSimpleERC721Composable.sol +// File contracts/core/composable/TopDownSimpleERC721Composable.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - abstract contract TopDownSimpleERC721Composable is Context { struct ComposedNFT { address nft; @@ -1453,9 +1465,10 @@ abstract contract TopDownSimpleERC721Composable is Context { } } -// File: contracts/core/Konstants.sol +// File contracts/core/Konstants.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1470,17 +1483,16 @@ contract Konstants { } } -// File: contracts/core/BaseKoda.sol +// File contracts/core/BaseKoda.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - abstract contract BaseKoda is Konstants, Context, IKODAV3 { bytes4 constant internal ERC721_RECEIVED = bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")); @@ -1572,9 +1584,10 @@ abstract contract BaseKoda is Konstants, Context, IKODAV3 { } } -// File: contracts/core/KnownOriginDigitalAssetV3.sol +// File contracts/core/KnownOriginDigitalAssetV3.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1586,8 +1599,6 @@ pragma solidity 0.8.4; - - /// @title A ERC-721 compliant contract which has a focus on being GAS efficient along with being able to support /// both unique tokens and multi-editions sharing common traits but of limited supply /// diff --git a/contracts-flat/MintingFactory.sol b/contracts-flat/MintingFactory.sol index eeac896e..dc75fb9c 100644 --- a/contracts-flat/MintingFactory.sol +++ b/contracts-flat/MintingFactory.sol @@ -1,4 +1,6 @@ -// File: @openzeppelin/contracts/utils/Context.sol +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/utils/Context.sol@v4.2.0 // SPDX-License-Identifier: MIT @@ -24,9 +26,10 @@ abstract contract Context { } } -// File: contracts/core/IKODAV3Minter.sol +// File contracts/core/IKODAV3Minter.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -39,9 +42,10 @@ interface IKODAV3Minter { function mintConsecutiveBatchEdition(uint16 _editionSize, address _to, string calldata _uri) external returns (uint256 _editionId); } -// File: contracts/access/IKOAccessControlsLookup.sol +// File contracts/access/IKOAccessControlsLookup.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -59,9 +63,10 @@ interface IKOAccessControlsLookup { function hasContractOrAdminRole(address _address) external view returns (bool); } -// File: @openzeppelin/contracts/utils/introspection/IERC165.sol +// File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -86,13 +91,13 @@ interface IERC165 { function supportsInterface(bytes4 interfaceId) external view returns (bool); } -// File: @openzeppelin/contracts/token/ERC721/IERC721.sol +// File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Required interface of an ERC721 compliant contract. */ @@ -230,9 +235,10 @@ interface IERC721 is IERC165 { ) external; } -// File: contracts/core/IERC2309.sol +// File contracts/core/IERC2309.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -259,13 +265,13 @@ interface IERC2309 { event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed fromAddress, address indexed toAddress); } -// File: contracts/core/IERC2981.sol +// File contracts/core/IERC2981.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @notice This is purely an extension for the KO platform /// @notice Royalties on KO are defined at an edition level for all tokens from the same edition interface IERC2981EditionExtension { @@ -304,13 +310,13 @@ interface IERC2981 is IERC165, IERC2981EditionExtension { } -// File: contracts/core/IHasSecondarySaleFees.sol +// File contracts/core/IHasSecondarySaleFees.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - /// @title Royalties formats required for use on the Rarible platform /// @dev https://docs.rarible.com/asset/royalties-schema interface IHasSecondarySaleFees is IERC165 { @@ -322,9 +328,10 @@ interface IHasSecondarySaleFees is IERC165 { function getFeeBps(uint256 id) external returns (uint[] memory); } -// File: contracts/core/IKODAV3.sol +// File contracts/core/IKODAV3.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -332,7 +339,6 @@ pragma solidity 0.8.4; - /// @title Core KODA V3 functionality interface IKODAV3 is IERC165, // Contract introspection @@ -401,9 +407,10 @@ IHasSecondarySaleFees // Rariable / Foundation royalties } -// File: contracts/marketplace/IKODAV3Marketplace.sol +// File contracts/marketplace/IKODAV3Marketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; interface IBuyNowMarketplace { @@ -533,9 +540,50 @@ interface IKODAV3SecondarySaleMarketplace is ITokenBuyNowMarketplace, ITokenOffe function convertReserveAuctionToOffers(uint256 _tokenId) external; } -// File: @openzeppelin/contracts/security/ReentrancyGuard.sol +interface IKODAV3GatedMarketplace { + + function createSale(uint256 _editionId) external; + + function createPhase( + uint256 _editionId, + uint128 _startTime, + uint128 _endTime, + uint128 _priceInWei, + uint16 _mintCap, + uint16 _walletMintLimit, + bytes32 _merkleRoot, + string calldata _merkleIPFSHash + ) external; + + function createSaleWithPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function createPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function removePhase(uint256 _editionId, uint256 _phaseId) external; +} + +// File @openzeppelin/contracts/security/ReentrancyGuard.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -598,13 +646,13 @@ abstract contract ReentrancyGuard { } } -// File: @openzeppelin/contracts/security/Pausable.sol +// File @openzeppelin/contracts/security/Pausable.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; - /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. @@ -690,9 +738,10 @@ abstract contract Pausable is Context { } } -// File: @openzeppelin/contracts/token/ERC20/IERC20.sol +// File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 +// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; @@ -774,17 +823,16 @@ interface IERC20 { event Approval(address indexed owner, address indexed spender, uint256 value); } -// File: contracts/marketplace/BaseMarketplace.sol +// File contracts/marketplace/BaseMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - /// @notice Core logic and state shared between both marketplaces abstract contract BaseMarketplace is ReentrancyGuard, Pausable { @@ -915,14 +963,14 @@ abstract contract BaseMarketplace is ReentrancyGuard, Pausable { function _isListingPermitted(uint256 _id) internal virtual returns (bool); } -// File: contracts/marketplace/BuyNowMarketplace.sol +// File contracts/marketplace/BuyNowMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - // "buy now" sale flow abstract contract BuyNowMarketplace is IBuyNowMarketplace, BaseMarketplace { // Buy now listing definition @@ -1002,16 +1050,15 @@ abstract contract BuyNowMarketplace is IBuyNowMarketplace, BaseMarketplace { function _isBuyNowListingPermitted(uint256 _id) internal virtual returns (bool); } -// File: contracts/marketplace/ReserveAuctionMarketplace.sol +// File contracts/marketplace/ReserveAuctionMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - abstract contract ReserveAuctionMarketplace is IReserveAuctionMarketplace, BaseMarketplace { event AdminUpdateReserveAuctionBidExtensionWindow(uint128 _reserveAuctionBidExtensionWindow); event AdminUpdateReserveAuctionLengthOnceReserveMet(uint128 _reserveAuctionLengthOnceReserveMet); @@ -1245,9 +1292,10 @@ abstract contract ReserveAuctionMarketplace is IReserveAuctionMarketplace, BaseM } } -// File: contracts/marketplace/KODAV3PrimaryMarketplace.sol +// File contracts/marketplace/KODAV3PrimaryMarketplace.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; @@ -1255,8 +1303,6 @@ pragma solidity 0.8.4; - - /// @title KnownOrigin Primary Marketplace for all V3 tokens /// @notice The following listing types are supported: Buy now, Stepped, Reserve and Offers /// @dev The contract is pausable and has reentrancy guards @@ -1794,9 +1840,10 @@ BuyNowMarketplace { } } -// File: contracts/collab/ICollabRoyaltiesRegistry.sol +// File contracts/collab/ICollabRoyaltiesRegistry.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; /// @notice Common interface to the edition royalties registry @@ -1838,17 +1885,16 @@ interface ICollabRoyaltiesRegistry { } -// File: contracts/minter/MintingFactory.sol +// File contracts/minter/MintingFactory.sol +// SPDX-License-Identifier: MIT pragma solidity 0.8.4; - - contract MintingFactory is Context { event EditionMintedAndListed(uint256 indexed _editionId, SaleType _saleType); diff --git a/contracts-flat/MintingFactoryV2.sol b/contracts-flat/MintingFactoryV2.sol new file mode 100644 index 00000000..33b10cff --- /dev/null +++ b/contracts-flat/MintingFactoryV2.sol @@ -0,0 +1,1385 @@ +// Sources flattened with hardhat v2.9.1 https://hardhat.org + +// File @openzeppelin/contracts/utils/Context.sol@v4.2.0 + +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +/* + * @dev Provides information about the current execution context, including the + * sender of the transaction and its data. While these are generally available + * via msg.sender and msg.data, they should not be accessed in such a direct + * manner, since when dealing with meta-transactions the account sending and + * paying for execution may not be the actual sender (as far as an application + * is concerned). + * + * This contract is only required for intermediate, library-like contracts. + */ +abstract contract Context { + function _msgSender() internal view virtual returns (address) { + return msg.sender; + } + + function _msgData() internal view virtual returns (bytes calldata) { + return msg.data; + } +} + + +// File @openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) + +pragma solidity ^0.8.0; + +/** + * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified + * proxy whose upgrades are fully controlled by the current implementation. + */ +interface IERC1822ProxiableUpgradeable { + /** + * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation + * address. + * + * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks + * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this + * function revert if invoked through a proxy. + */ + function proxiableUUID() external view returns (bytes32); +} + + +// File @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) + +pragma solidity ^0.8.0; + +/** + * @dev This is the interface that {BeaconProxy} expects of its beacon. + */ +interface IBeaconUpgradeable { + /** + * @dev Must return an address that can be used as a delegate call target. + * + * {BeaconProxy} will check that this address is a contract. + */ + function implementation() external view returns (address); +} + + +// File @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) + +pragma solidity ^0.8.1; + +/** + * @dev Collection of functions related to the address type + */ +library AddressUpgradeable { + /** + * @dev Returns true if `account` is a contract. + * + * [IMPORTANT] + * ==== + * It is unsafe to assume that an address for which this function returns + * false is an externally-owned account (EOA) and not a contract. + * + * Among others, `isContract` will return false for the following + * types of addresses: + * + * - an externally-owned account + * - a contract in construction + * - an address where a contract will be created + * - an address where a contract lived, but was destroyed + * ==== + * + * [IMPORTANT] + * ==== + * You shouldn't rely on `isContract` to protect against flash loan attacks! + * + * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets + * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract + * constructor. + * ==== + */ + function isContract(address account) internal view returns (bool) { + // This method relies on extcodesize/address.code.length, which returns 0 + // for contracts in construction, since the code is only stored at the end + // of the constructor execution. + + return account.code.length > 0; + } + + /** + * @dev Replacement for Solidity's `transfer`: sends `amount` wei to + * `recipient`, forwarding all available gas and reverting on errors. + * + * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost + * of certain opcodes, possibly making contracts go over the 2300 gas limit + * imposed by `transfer`, making them unable to receive funds via + * `transfer`. {sendValue} removes this limitation. + * + * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. + * + * IMPORTANT: because control is transferred to `recipient`, care must be + * taken to not create reentrancy vulnerabilities. Consider using + * {ReentrancyGuard} or the + * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. + */ + function sendValue(address payable recipient, uint256 amount) internal { + require(address(this).balance >= amount, "Address: insufficient balance"); + + (bool success, ) = recipient.call{value: amount}(""); + require(success, "Address: unable to send value, recipient may have reverted"); + } + + /** + * @dev Performs a Solidity function call using a low level `call`. A + * plain `call` is an unsafe replacement for a function call: use this + * function instead. + * + * If `target` reverts with a revert reason, it is bubbled up by this + * function (like regular Solidity function calls). + * + * Returns the raw returned data. To convert to the expected return value, + * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. + * + * Requirements: + * + * - `target` must be a contract. + * - calling `target` with `data` must not revert. + * + * _Available since v3.1._ + */ + function functionCall(address target, bytes memory data) internal returns (bytes memory) { + return functionCall(target, data, "Address: low-level call failed"); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with + * `errorMessage` as a fallback revert reason when `target` reverts. + * + * _Available since v3.1._ + */ + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, 0, errorMessage); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but also transferring `value` wei to `target`. + * + * Requirements: + * + * - the calling contract must have an ETH balance of at least `value`. + * - the called Solidity function must be `payable`. + * + * _Available since v3.1._ + */ + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); + } + + /** + * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but + * with `errorMessage` as a fallback revert reason when `target` reverts. + * + * _Available since v3.1._ + */ + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) internal returns (bytes memory) { + require(address(this).balance >= value, "Address: insufficient balance for call"); + require(isContract(target), "Address: call to non-contract"); + + (bool success, bytes memory returndata) = target.call{value: value}(data); + return verifyCallResult(success, returndata, errorMessage); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], + * but performing a static call. + * + * _Available since v3.3._ + */ + function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { + return functionStaticCall(target, data, "Address: low-level static call failed"); + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], + * but performing a static call. + * + * _Available since v3.3._ + */ + function functionStaticCall( + address target, + bytes memory data, + string memory errorMessage + ) internal view returns (bytes memory) { + require(isContract(target), "Address: static call to non-contract"); + + (bool success, bytes memory returndata) = target.staticcall(data); + return verifyCallResult(success, returndata, errorMessage); + } + + /** + * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the + * revert reason using the provided one. + * + * _Available since v4.3._ + */ + function verifyCallResult( + bool success, + bytes memory returndata, + string memory errorMessage + ) internal pure returns (bytes memory) { + if (success) { + return returndata; + } else { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(errorMessage); + } + } + } +} + + +// File @openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) + +pragma solidity ^0.8.0; + +/** + * @dev Library for reading and writing primitive types to specific storage slots. + * + * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. + * This library helps with reading and writing to such slots without the need for inline assembly. + * + * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. + * + * Example usage to set ERC1967 implementation slot: + * ``` + * contract ERC1967 { + * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + * + * function _getImplementation() internal view returns (address) { + * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + * } + * + * function _setImplementation(address newImplementation) internal { + * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); + * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + * } + * } + * ``` + * + * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ + */ +library StorageSlotUpgradeable { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + /** + * @dev Returns an `AddressSlot` with member `value` located at `slot`. + */ + function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `BooleanSlot` with member `value` located at `slot`. + */ + function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. + */ + function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { + assembly { + r.slot := slot + } + } + + /** + * @dev Returns an `Uint256Slot` with member `value` located at `slot`. + */ + function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { + assembly { + r.slot := slot + } + } +} + + +// File @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) + +pragma solidity ^0.8.0; + +/** + * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed + * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an + * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer + * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. + * + * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as + * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. + * + * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure + * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. + * + * [CAUTION] + * ==== + * Avoid leaving a contract uninitialized. + * + * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation + * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the + * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: + * + * [.hljs-theme-light.nopadding] + * ``` + * /// @custom:oz-upgrades-unsafe-allow constructor + * constructor() initializer {} + * ``` + * ==== + */ +abstract contract Initializable { + /** + * @dev Indicates that the contract has been initialized. + */ + bool private _initialized; + + /** + * @dev Indicates that the contract is in the process of being initialized. + */ + bool private _initializing; + + /** + * @dev Modifier to protect an initializer function from being invoked twice. + */ + modifier initializer() { + // If the contract is initializing we ignore whether _initialized is set in order to support multiple + // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the + // contract may have been reentered. + require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); + + bool isTopLevelCall = !_initializing; + if (isTopLevelCall) { + _initializing = true; + _initialized = true; + } + + _; + + if (isTopLevelCall) { + _initializing = false; + } + } + + /** + * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the + * {initializer} modifier, directly or indirectly. + */ + modifier onlyInitializing() { + require(_initializing, "Initializable: contract is not initializing"); + _; + } + + function _isConstructor() private view returns (bool) { + return !AddressUpgradeable.isContract(address(this)); + } +} + + +// File @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) + +pragma solidity ^0.8.2; + + + + + +/** + * @dev This abstract contract provides getters and event emitting update functions for + * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. + * + * _Available since v4.1._ + * + * @custom:oz-upgrades-unsafe-allow delegatecall + */ +abstract contract ERC1967UpgradeUpgradeable is Initializable { + function __ERC1967Upgrade_init() internal onlyInitializing { + } + + function __ERC1967Upgrade_init_unchained() internal onlyInitializing { + } + // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 + bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; + + /** + * @dev Storage slot with the address of the current implementation. + * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is + * validated in the constructor. + */ + bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + /** + * @dev Emitted when the implementation is upgraded. + */ + event Upgraded(address indexed implementation); + + /** + * @dev Returns the current implementation address. + */ + function _getImplementation() internal view returns (address) { + return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; + } + + /** + * @dev Stores a new address in the EIP1967 implementation slot. + */ + function _setImplementation(address newImplementation) private { + require(AddressUpgradeable.isContract(newImplementation), "ERC1967: new implementation is not a contract"); + StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; + } + + /** + * @dev Perform implementation upgrade + * + * Emits an {Upgraded} event. + */ + function _upgradeTo(address newImplementation) internal { + _setImplementation(newImplementation); + emit Upgraded(newImplementation); + } + + /** + * @dev Perform implementation upgrade with additional setup call. + * + * Emits an {Upgraded} event. + */ + function _upgradeToAndCall( + address newImplementation, + bytes memory data, + bool forceCall + ) internal { + _upgradeTo(newImplementation); + if (data.length > 0 || forceCall) { + _functionDelegateCall(newImplementation, data); + } + } + + /** + * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. + * + * Emits an {Upgraded} event. + */ + function _upgradeToAndCallUUPS( + address newImplementation, + bytes memory data, + bool forceCall + ) internal { + // Upgrades from old implementations will perform a rollback test. This test requires the new + // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing + // this special case will break upgrade paths from old UUPS implementation to new ones. + if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { + _setImplementation(newImplementation); + } else { + try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { + require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID"); + } catch { + revert("ERC1967Upgrade: new implementation is not UUPS"); + } + _upgradeToAndCall(newImplementation, data, forceCall); + } + } + + /** + * @dev Storage slot with the admin of the contract. + * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is + * validated in the constructor. + */ + bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + /** + * @dev Emitted when the admin account has changed. + */ + event AdminChanged(address previousAdmin, address newAdmin); + + /** + * @dev Returns the current admin. + */ + function _getAdmin() internal view returns (address) { + return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; + } + + /** + * @dev Stores a new address in the EIP1967 admin slot. + */ + function _setAdmin(address newAdmin) private { + require(newAdmin != address(0), "ERC1967: new admin is the zero address"); + StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; + } + + /** + * @dev Changes the admin of the proxy. + * + * Emits an {AdminChanged} event. + */ + function _changeAdmin(address newAdmin) internal { + emit AdminChanged(_getAdmin(), newAdmin); + _setAdmin(newAdmin); + } + + /** + * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. + * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. + */ + bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; + + /** + * @dev Emitted when the beacon is upgraded. + */ + event BeaconUpgraded(address indexed beacon); + + /** + * @dev Returns the current beacon. + */ + function _getBeacon() internal view returns (address) { + return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; + } + + /** + * @dev Stores a new beacon in the EIP1967 beacon slot. + */ + function _setBeacon(address newBeacon) private { + require(AddressUpgradeable.isContract(newBeacon), "ERC1967: new beacon is not a contract"); + require( + AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation()), + "ERC1967: beacon implementation is not a contract" + ); + StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; + } + + /** + * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does + * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). + * + * Emits a {BeaconUpgraded} event. + */ + function _upgradeBeaconToAndCall( + address newBeacon, + bytes memory data, + bool forceCall + ) internal { + _setBeacon(newBeacon); + emit BeaconUpgraded(newBeacon); + if (data.length > 0 || forceCall) { + _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); + } + } + + /** + * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], + * but performing a delegate call. + * + * _Available since v3.4._ + */ + function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { + require(AddressUpgradeable.isContract(target), "Address: delegate call to non-contract"); + + // solhint-disable-next-line avoid-low-level-calls + (bool success, bytes memory returndata) = target.delegatecall(data); + return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); + } + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[50] private __gap; +} + + +// File @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol@v4.5.2 + +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) + +pragma solidity ^0.8.0; + + + +/** + * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an + * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. + * + * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is + * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing + * `UUPSUpgradeable` with a custom implementation of upgrades. + * + * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. + * + * _Available since v4.1._ + */ +abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { + function __UUPSUpgradeable_init() internal onlyInitializing { + } + + function __UUPSUpgradeable_init_unchained() internal onlyInitializing { + } + /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment + address private immutable __self = address(this); + + /** + * @dev Check that the execution is being performed through a delegatecall call and that the execution context is + * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case + * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a + * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to + * fail. + */ + modifier onlyProxy() { + require(address(this) != __self, "Function must be called through delegatecall"); + require(_getImplementation() == __self, "Function must be called through active proxy"); + _; + } + + /** + * @dev Check that the execution is not being performed through a delegate call. This allows a function to be + * callable on the implementing contract but not through proxies. + */ + modifier notDelegated() { + require(address(this) == __self, "UUPSUpgradeable: must not be called through delegatecall"); + _; + } + + /** + * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the + * implementation. It is used to validate that the this implementation remains valid after an upgrade. + * + * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks + * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this + * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. + */ + function proxiableUUID() external view virtual override notDelegated returns (bytes32) { + return _IMPLEMENTATION_SLOT; + } + + /** + * @dev Upgrade the implementation of the proxy to `newImplementation`. + * + * Calls {_authorizeUpgrade}. + * + * Emits an {Upgraded} event. + */ + function upgradeTo(address newImplementation) external virtual onlyProxy { + _authorizeUpgrade(newImplementation); + _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); + } + + /** + * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call + * encoded in `data`. + * + * Calls {_authorizeUpgrade}. + * + * Emits an {Upgraded} event. + */ + function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { + _authorizeUpgrade(newImplementation); + _upgradeToAndCallUUPS(newImplementation, data, true); + } + + /** + * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by + * {upgradeTo} and {upgradeToAndCall}. + * + * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. + * + * ```solidity + * function _authorizeUpgrade(address) internal override onlyOwner {} + * ``` + */ + function _authorizeUpgrade(address newImplementation) internal virtual; + + /** + * @dev This empty reserved space is put in place to allow future versions to add new + * variables without shifting down storage in the inheritance chain. + * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps + */ + uint256[50] private __gap; +} + + +// File contracts/core/IKODAV3Minter.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + +interface IKODAV3Minter { + + function mintBatchEdition(uint16 _editionSize, address _to, string calldata _uri) external returns (uint256 _editionId); + + function mintBatchEditionAndComposeERC20s(uint16 _editionSize, address _to, string calldata _uri, address[] calldata _erc20s, uint256[] calldata _amounts) external returns (uint256 _editionId); + + function mintConsecutiveBatchEdition(uint16 _editionSize, address _to, string calldata _uri) external returns (uint256 _editionId); +} + + +// File contracts/marketplace/IKODAV3Marketplace.sol + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; + +interface IBuyNowMarketplace { + event ListedForBuyNow(uint256 indexed _id, uint256 _price, address _currentOwner, uint256 _startDate); + event BuyNowPriceChanged(uint256 indexed _id, uint256 _price); + event BuyNowDeListed(uint256 indexed _id); + event BuyNowPurchased(uint256 indexed _tokenId, address _buyer, address _currentOwner, uint256 _price); + + function listForBuyNow(address _creator, uint256 _id, uint128 _listingPrice, uint128 _startDate) external; + + function buyEditionToken(uint256 _id) external payable; + function buyEditionTokenFor(uint256 _id, address _recipient) external payable; + + function setBuyNowPriceListing(uint256 _editionId, uint128 _listingPrice) external; +} + +interface IEditionOffersMarketplace { + event EditionAcceptingOffer(uint256 indexed _editionId, uint128 _startDate); + event EditionBidPlaced(uint256 indexed _editionId, address _bidder, uint256 _amount); + event EditionBidWithdrawn(uint256 indexed _editionId, address _bidder); + event EditionBidAccepted(uint256 indexed _editionId, uint256 indexed _tokenId, address _bidder, uint256 _amount); + event EditionBidRejected(uint256 indexed _editionId, address _bidder, uint256 _amount); + event EditionConvertedFromOffersToBuyItNow(uint256 _editionId, uint128 _price, uint128 _startDate); + + function enableEditionOffers(uint256 _editionId, uint128 _startDate) external; + + function placeEditionBid(uint256 _editionId) external payable; + function placeEditionBidFor(uint256 _editionId, address _bidder) external payable; + + function withdrawEditionBid(uint256 _editionId) external; + + function rejectEditionBid(uint256 _editionId) external; + + function acceptEditionBid(uint256 _editionId, uint256 _offerPrice) external; + + function convertOffersToBuyItNow(uint256 _editionId, uint128 _listingPrice, uint128 _startDate) external; +} + +interface IEditionSteppedMarketplace { + event EditionSteppedSaleListed(uint256 indexed _editionId, uint128 _basePrice, uint128 _stepPrice, uint128 _startDate); + event EditionSteppedSaleBuy(uint256 indexed _editionId, uint256 indexed _tokenId, address _buyer, uint256 _price, uint16 _currentStep); + event EditionSteppedAuctionUpdated(uint256 indexed _editionId, uint128 _basePrice, uint128 _stepPrice); + + function listSteppedEditionAuction(address _creator, uint256 _editionId, uint128 _basePrice, uint128 _stepPrice, uint128 _startDate) external; + + function buyNextStep(uint256 _editionId) external payable; + function buyNextStepFor(uint256 _editionId, address _buyer) external payable; + + function convertSteppedAuctionToListing(uint256 _editionId, uint128 _listingPrice, uint128 _startDate) external; + + function convertSteppedAuctionToOffers(uint256 _editionId, uint128 _startDate) external; + + function updateSteppedAuction(uint256 _editionId, uint128 _basePrice, uint128 _stepPrice) external; +} + +interface IReserveAuctionMarketplace { + event ListedForReserveAuction(uint256 indexed _id, uint256 _reservePrice, uint128 _startDate); + event BidPlacedOnReserveAuction(uint256 indexed _id, address _currentOwner, address _bidder, uint256 _amount, uint256 _originalBiddingEnd, uint256 _currentBiddingEnd); + event ReserveAuctionResulted(uint256 indexed _id, uint256 _finalPrice, address _currentOwner, address _winner, address _resulter); + event BidWithdrawnFromReserveAuction(uint256 _id, address _bidder, uint128 _bid); + event ReservePriceUpdated(uint256 indexed _id, uint256 _reservePrice); + event ReserveAuctionConvertedToBuyItNow(uint256 indexed _id, uint128 _listingPrice, uint128 _startDate); + event EmergencyBidWithdrawFromReserveAuction(uint256 indexed _id, address _bidder, uint128 _bid); + + function placeBidOnReserveAuction(uint256 _id) external payable; + function placeBidOnReserveAuctionFor(uint256 _id, address _bidder) external payable; + + function listForReserveAuction(address _creator, uint256 _id, uint128 _reservePrice, uint128 _startDate) external; + + function resultReserveAuction(uint256 _id) external; + + function withdrawBidFromReserveAuction(uint256 _id) external; + + function updateReservePriceForReserveAuction(uint256 _id, uint128 _reservePrice) external; + + function emergencyExitBidFromReserveAuction(uint256 _id) external; +} + +interface IKODAV3PrimarySaleMarketplace is IEditionSteppedMarketplace, IEditionOffersMarketplace, IBuyNowMarketplace, IReserveAuctionMarketplace { + function convertReserveAuctionToBuyItNow(uint256 _editionId, uint128 _listingPrice, uint128 _startDate) external; + + function convertReserveAuctionToOffers(uint256 _editionId, uint128 _startDate) external; +} + +interface ITokenBuyNowMarketplace { + event TokenDeListed(uint256 indexed _tokenId); + + function delistToken(uint256 _tokenId) external; +} + +interface ITokenOffersMarketplace { + event TokenBidPlaced(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + event TokenBidAccepted(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + event TokenBidRejected(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + event TokenBidWithdrawn(uint256 indexed _tokenId, address _bidder); + + function acceptTokenBid(uint256 _tokenId, uint256 _offerPrice) external; + + function rejectTokenBid(uint256 _tokenId) external; + + function withdrawTokenBid(uint256 _tokenId) external; + + function placeTokenBid(uint256 _tokenId) external payable; + function placeTokenBidFor(uint256 _tokenId, address _bidder) external payable; +} + +interface IBuyNowSecondaryMarketplace { + function listTokenForBuyNow(uint256 _tokenId, uint128 _listingPrice, uint128 _startDate) external; +} + +interface IEditionOffersSecondaryMarketplace { + event EditionBidPlaced(uint256 indexed _editionId, address indexed _bidder, uint256 _bid); + event EditionBidWithdrawn(uint256 indexed _editionId, address _bidder); + event EditionBidAccepted(uint256 indexed _tokenId, address _currentOwner, address _bidder, uint256 _amount); + + function placeEditionBid(uint256 _editionId) external payable; + function placeEditionBidFor(uint256 _editionId, address _bidder) external payable; + + function withdrawEditionBid(uint256 _editionId) external; + + function acceptEditionBid(uint256 _tokenId, uint256 _offerPrice) external; +} + +interface IKODAV3SecondarySaleMarketplace is ITokenBuyNowMarketplace, ITokenOffersMarketplace, IEditionOffersSecondaryMarketplace, IBuyNowSecondaryMarketplace { + function convertReserveAuctionToBuyItNow(uint256 _tokenId, uint128 _listingPrice, uint128 _startDate) external; + + function convertReserveAuctionToOffers(uint256 _tokenId) external; +} + +interface IKODAV3GatedMarketplace { + + function createSale(uint256 _editionId) external; + + function createPhase( + uint256 _editionId, + uint128 _startTime, + uint128 _endTime, + uint128 _priceInWei, + uint16 _mintCap, + uint16 _walletMintLimit, + bytes32 _merkleRoot, + string calldata _merkleIPFSHash + ) external; + + function createSaleWithPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function createPhases( + uint256 _editionId, + uint128[] memory _startTimes, + uint128[] memory _endTimes, + uint128[] memory _pricesInWei, + uint16[] memory _mintCaps, + uint16[] memory _walletMintLimits, + bytes32[] memory _merkleRoots, + string[] memory _merkleIPFSHashes + ) external; + + function removePhase(uint256 _editionId, uint256 _phaseId) external; +} + + +// File contracts/collab/ICollabRoyaltiesRegistry.sol + +// SPDX-License-Identifier: MIT +pragma solidity 0.8.4; + +/// @notice Common interface to the edition royalties registry +interface ICollabRoyaltiesRegistry { + + /// @notice Creates & deploys a new royalties recipient, cloning _handle and setting it up with the provided _recipients and _splits + function createRoyaltiesRecipient( + address _handler, + address[] calldata _recipients, + uint256[] calldata _splits + ) external returns (address deployedHandler); + + /// @notice Sets up the provided edition to use the provided _recipient + function useRoyaltiesRecipient(uint256 _editionId, address _deployedHandler) external; + + /// @notice Setup a royalties handler but does not deploy it, uses predicable clone and sets this against the edition + function usePredeterminedRoyaltiesRecipient( + uint256 _editionId, + address _handler, + address[] calldata _recipients, + uint256[] calldata _splits + ) external; + + /// @notice Deploy and setup a royalties recipient for the given edition + function createAndUseRoyaltiesRecipient( + uint256 _editionId, + address _handler, + address[] calldata _recipients, + uint256[] calldata _splits + ) + external returns (address deployedHandler); + + /// @notice Predict the deployed clone address with the given parameters + function predictedRoyaltiesHandler( + address _handler, + address[] calldata _recipients, + uint256[] calldata _splits + ) external view returns (address predictedHandler); + +} + + +// File contracts/access/IKOAccessControlsLookup.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + +interface IKOAccessControlsLookup { + function hasAdminRole(address _address) external view returns (bool); + + function isVerifiedArtist(uint256 _index, address _account, bytes32[] calldata _merkleProof) external view returns (bool); + + function isVerifiedArtistProxy(address _artist, address _proxy) external view returns (bool); + + function hasLegacyMinterRole(address _address) external view returns (bool); + + function hasContractRole(address _address) external view returns (bool); + + function hasContractOrAdminRole(address _address) external view returns (bool); +} + + +// File contracts/minter/MintingFactoryV2.sol + +// SPDX-License-Identifier: MIT + +pragma solidity 0.8.4; + + + + + +contract MintingFactoryV2 is Context, UUPSUpgradeable { + + event EditionMinted(uint256 indexed _editionId); + event EditionMintedAndListed(uint256 indexed _editionId, SaleType _saleType); + + event MintingFactoryCreated(); + event AdminMintingPeriodChanged(uint256 _mintingPeriod); + event AdminMaxMintsInPeriodChanged(uint256 _maxMintsInPeriod); + event AdminFrequencyOverrideChanged(address _account, bool _override); + event AdminRoyaltiesRegistryChanged(address _royaltiesRegistry); + + modifier onlyAdmin() { + require(accessControls.hasAdminRole(_msgSender()), "Caller must have admin role"); + _; + } + + modifier canMintAgain(address _sender) { + require(_canCreateNewEdition(_sender), "Caller unable to create yet"); + _; + } + + struct MintingPeriod { + uint128 mints; + uint128 firstMintInPeriod; + } + + enum SaleType { + BUY_NOW, OFFERS, STEPPED, RESERVE + } + + // Minting allowance period + uint256 public mintingPeriod; + + // Limit of mints with in the period + uint256 public maxMintsInPeriod; + + // Frequency override list for users - you can temporarily add in address which disables the freeze time check + mapping(address => bool) public frequencyOverride; + + // How many mints within the current minting period + mapping(address => MintingPeriod) mintingPeriodConfig; + + IKOAccessControlsLookup public accessControls; + IKODAV3Minter public koda; + IKODAV3PrimarySaleMarketplace public marketplace; + IKODAV3GatedMarketplace public gatedMarketplace; + ICollabRoyaltiesRegistry public royaltiesRegistry; + + /// @custom:oz-upgrades-unsafe-allow constructor + constructor() initializer {} + + function initialize( + IKOAccessControlsLookup _accessControls, + IKODAV3Minter _koda, + IKODAV3PrimarySaleMarketplace _marketplace, + IKODAV3GatedMarketplace _gatedMarketplace, + ICollabRoyaltiesRegistry _royaltiesRegistry + ) public initializer { + + accessControls = _accessControls; + koda = _koda; + marketplace = _marketplace; + gatedMarketplace = _gatedMarketplace; + royaltiesRegistry = _royaltiesRegistry; + + mintingPeriod = 30 days; + maxMintsInPeriod = 15; + + emit MintingFactoryCreated(); + } + + function _authorizeUpgrade(address newImplementation) internal view override { + require(accessControls.hasAdminRole(msg.sender), "Only admin can upgrade"); + } + + ////////////////////////////////////////// + /// Mint & setup on primary marketplace // + ////////////////////////////////////////// + + function mintBatchEdition( + SaleType _saleType, + uint16 _editionSize, + uint128 _startDate, + uint128 _basePrice, + uint128 _stepPrice, + string calldata _uri, + uint256 _merkleIndex, + bytes32[] calldata _merkleProof, + address _deployedRoyaltiesHandler + ) canMintAgain(_msgSender()) external { + require(accessControls.isVerifiedArtist(_merkleIndex, _msgSender(), _merkleProof), "Caller must have minter role"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _msgSender(), _uri); + + _setupSalesMechanic(editionId, _saleType, _startDate, _basePrice, _stepPrice); + _recordSuccessfulMint(_msgSender()); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + } + + function mintBatchEditionAsProxy( + address _creator, + SaleType _saleType, + uint16 _editionSize, + uint128 _startDate, + uint128 _basePrice, + uint128 _stepPrice, + string calldata _uri, + address _deployedRoyaltiesHandler + ) canMintAgain(_creator) external { + require(accessControls.isVerifiedArtistProxy(_creator, _msgSender()), "Caller is not artist proxy"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _creator, _uri); + + _setupSalesMechanic(editionId, _saleType, _startDate, _basePrice, _stepPrice); + _recordSuccessfulMint(_creator); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + } + + ////////////////////////////////////// + /// Mint & setup on gated only drop // + ////////////////////////////////////// + + function mintBatchEditionGatedOnly( + uint16 _editionSize, + uint256 _merkleIndex, + bytes32[] calldata _merkleProof, + address _deployedRoyaltiesHandler, + string calldata _uri + ) canMintAgain(_msgSender()) external { + require(accessControls.isVerifiedArtist(_merkleIndex, _msgSender(), _merkleProof), "Caller must have minter role"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _msgSender(), _uri); + + // Created gated sale + gatedMarketplace.createSale(editionId); + + _recordSuccessfulMint(_msgSender()); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + } + + function mintBatchEditionGatedOnlyAsProxy( + address _creator, + uint16 _editionSize, + address _deployedRoyaltiesHandler, + string calldata _uri + ) canMintAgain(_creator) external { + require(accessControls.isVerifiedArtistProxy(_creator, _msgSender()), "Caller is not artist proxy"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _creator, _uri); + + // Created gated sale + gatedMarketplace.createSale(editionId); + + _recordSuccessfulMint(_creator); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + } + + ////////////////////////////////////////// + /// Mint & setup on gated & public drop // + ////////////////////////////////////////// + + function mintBatchEditionGatedAndPublic( + uint16 _editionSize, + uint128 _publicStartDate, + uint128 _publicBuyNowPrice, + uint256 _merkleIndex, + bytes32[] calldata _merkleProof, + address _deployedRoyaltiesHandler, + string calldata _uri + ) canMintAgain(_msgSender()) external { + require(accessControls.isVerifiedArtist(_merkleIndex, _msgSender(), _merkleProof), "Caller must have minter role"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _msgSender(), _uri); + + // Setup public sale + _setupSalesMechanic(editionId, SaleType.BUY_NOW, _publicStartDate, _publicBuyNowPrice, 0); + + // Created gated sale + gatedMarketplace.createSale(editionId); + + _recordSuccessfulMint(_msgSender()); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + } + + function mintBatchEditionGatedAndPublicAsProxy( + address _creator, + uint16 _editionSize, + uint128 _publicStartDate, + uint128 _publicBuyNowPrice, + address _deployedRoyaltiesHandler, + string calldata _uri + ) canMintAgain(_creator) external { + require(accessControls.isVerifiedArtistProxy(_creator, _msgSender()), "Caller is not artist proxy"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _creator, _uri); + + // Setup public sale + _setupSalesMechanic(editionId, SaleType.BUY_NOW, _publicStartDate, _publicBuyNowPrice, 0); + + // Created gated sale + gatedMarketplace.createSale(editionId); + + _recordSuccessfulMint(_creator); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + } + + //////////////// + /// Mint only // + //////////////// + + function mintBatchEditionOnly( + uint16 _editionSize, + uint256 _merkleIndex, + bytes32[] calldata _merkleProof, + address _deployedRoyaltiesHandler, + string calldata _uri + ) canMintAgain(_msgSender()) external { + require(accessControls.isVerifiedArtist(_merkleIndex, _msgSender(), _merkleProof), "Caller must have minter role"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _msgSender(), _uri); + + _recordSuccessfulMint(_msgSender()); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + + emit EditionMinted(editionId); + } + + function mintBatchEditionOnlyAsProxy( + address _creator, + uint16 _editionSize, + address _deployedRoyaltiesHandler, + string calldata _uri + ) canMintAgain(_creator) external { + require(accessControls.isVerifiedArtistProxy(_creator, _msgSender()), "Caller is not artist proxy"); + + // Make tokens & edition + uint256 editionId = koda.mintBatchEdition(_editionSize, _creator, _uri); + + _recordSuccessfulMint(_creator); + _setupRoyalties(editionId, _deployedRoyaltiesHandler); + + emit EditionMinted(editionId); + } + + /////////////////////// + /// Internal helpers // + /////////////////////// + + function _setupSalesMechanic(uint256 _editionId, SaleType _saleType, uint128 _startDate, uint128 _basePrice, uint128 _stepPrice) internal { + if (SaleType.BUY_NOW == _saleType) { + marketplace.listForBuyNow(_msgSender(), _editionId, _basePrice, _startDate); + } + else if (SaleType.STEPPED == _saleType) { + marketplace.listSteppedEditionAuction(_msgSender(), _editionId, _basePrice, _stepPrice, _startDate); + } + else if (SaleType.OFFERS == _saleType) { + marketplace.enableEditionOffers(_editionId, _startDate); + } + else if (SaleType.RESERVE == _saleType) { + // use base price for reserve price + marketplace.listForReserveAuction(_msgSender(), _editionId, _basePrice, _startDate); + } + + emit EditionMintedAndListed(_editionId, _saleType); + } + + function _setupRoyalties(uint256 _editionId, address _deployedHandler) internal { + if (_deployedHandler != address(0) && address(royaltiesRegistry) != address(0)) { + royaltiesRegistry.useRoyaltiesRecipient(_editionId, _deployedHandler); + } + } + + function _canCreateNewEdition(address _account) internal view returns (bool) { + // if frequency is overridden then assume they can mint + if (frequencyOverride[_account]) { + return true; + } + + // if within the period range, check remaining allowance + if (_getNow() <= mintingPeriodConfig[_account].firstMintInPeriod + mintingPeriod) { + return mintingPeriodConfig[_account].mints < maxMintsInPeriod; + } + + // if period expired - can mint another one + return true; + } + + function _recordSuccessfulMint(address _account) internal { + MintingPeriod storage period = mintingPeriodConfig[_account]; + + uint256 endOfCurrentMintingPeriodLimit = period.firstMintInPeriod + mintingPeriod; + + // if first time use, set the first timestamp to be now abd start counting + if (period.firstMintInPeriod == 0) { + period.firstMintInPeriod = _getNow(); + period.mints = period.mints + 1; + } + // if still within the minting period, record the new mint + else if (_getNow() <= endOfCurrentMintingPeriodLimit) { + period.mints = period.mints + 1; + } + // if we are outside of the window reset the limit and record a new single mint + else if (endOfCurrentMintingPeriodLimit < _getNow()) { + period.mints = 1; + period.firstMintInPeriod = _getNow(); + } + } + + function _getNow() internal virtual view returns (uint128) { + return uint128(block.timestamp); + } + + /// Public helpers + + function canCreateNewEdition(address _account) public view returns (bool) { + return _canCreateNewEdition(_account); + } + + function currentMintConfig(address _account) public view returns (uint128 mints, uint128 firstMintInPeriod) { + MintingPeriod memory config = mintingPeriodConfig[_account]; + return ( + config.mints, + config.firstMintInPeriod + ); + } + + function setFrequencyOverride(address _account, bool _override) onlyAdmin public { + frequencyOverride[_account] = _override; + emit AdminFrequencyOverrideChanged(_account, _override); + } + + function setMintingPeriod(uint256 _mintingPeriod) onlyAdmin public { + mintingPeriod = _mintingPeriod; + emit AdminMintingPeriodChanged(_mintingPeriod); + } + + function setRoyaltiesRegistry(ICollabRoyaltiesRegistry _royaltiesRegistry) onlyAdmin public { + royaltiesRegistry = _royaltiesRegistry; + emit AdminRoyaltiesRegistryChanged(address(_royaltiesRegistry)); + } + + function setMaxMintsInPeriod(uint256 _maxMintsInPeriod) onlyAdmin public { + maxMintsInPeriod = _maxMintsInPeriod; + emit AdminMaxMintsInPeriodChanged(_maxMintsInPeriod); + } + +} diff --git a/flatten.sh b/flatten.sh index 7ff7571c..7449caa8 100755 --- a/flatten.sh +++ b/flatten.sh @@ -1,10 +1,12 @@ #!/usr/bin/env bash -truffle-flattener ./contracts/access/KOAccessControls.sol > ./contracts-flat/KOAccessControls.sol -truffle-flattener ./contracts/core/KnownOriginDigitalAssetV3.sol > ./contracts-flat/KnownOriginDigitalAssetV3.sol -truffle-flattener ./contracts/marketplace/KODAV3PrimaryMarketplace.sol > ./contracts-flat/KODAV3PrimaryMarketplace.sol -truffle-flattener ./contracts/marketplace/KODAV3SecondaryMarketplace.sol > ./contracts-flat/KODAV3SecondaryMarketplace.sol -truffle-flattener ./contracts/minter/MintingFactory.sol > ./contracts-flat/MintingFactory.sol -truffle-flattener ./contracts/collab/CollabRoyaltiesRegistry.sol > ./contracts-flat/CollabRoyaltiesRegistry.sol -truffle-flattener ./contracts/collab/handlers/ClaimableFundsReceiverV1.sol > ./contracts-flat/ClaimableFundsReceiverV1.sol -truffle-flattener ./contracts/collab/handlers/ClaimableFundsSplitterV1.sol > ./contracts-flat/ClaimableFundsSplitterV1.sol +npx hardhat flatten ./contracts/access/KOAccessControls.sol > ./contracts-flat/KOAccessControls.sol +npx hardhat flatten ./contracts/core/KnownOriginDigitalAssetV3.sol > ./contracts-flat/KnownOriginDigitalAssetV3.sol +npx hardhat flatten ./contracts/marketplace/KODAV3PrimaryMarketplace.sol > ./contracts-flat/KODAV3PrimaryMarketplace.sol +npx hardhat flatten ./contracts/marketplace/KODAV3SecondaryMarketplace.sol > ./contracts-flat/KODAV3SecondaryMarketplace.sol +npx hardhat flatten ./contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol > ./contracts-flat/KODAV3UpgradableGatedMarketplace.sol +npx hardhat flatten ./contracts/minter/MintingFactory.sol > ./contracts-flat/MintingFactory.sol +npx hardhat flatten ./contracts/minter/MintingFactoryV2.sol > ./contracts-flat/MintingFactoryV2.sol +npx hardhat flatten ./contracts/collab/CollabRoyaltiesRegistry.sol > ./contracts-flat/CollabRoyaltiesRegistry.sol +npx hardhat flatten ./contracts/collab/handlers/ClaimableFundsReceiverV1.sol > ./contracts-flat/ClaimableFundsReceiverV1.sol +npx hardhat flatten ./contracts/collab/handlers/ClaimableFundsSplitterV1.sol > ./contracts-flat/ClaimableFundsSplitterV1.sol diff --git a/scripts/data/merkle-and-ipfs/create_sample_merkle_tree_for_gated_sale.js b/scripts/data/merkle-and-ipfs/create_sample_merkle_tree_for_gated_sale.js index 8c154b98..267f78b0 100644 --- a/scripts/data/merkle-and-ipfs/create_sample_merkle_tree_for_gated_sale.js +++ b/scripts/data/merkle-and-ipfs/create_sample_merkle_tree_for_gated_sale.js @@ -11,9 +11,9 @@ const {parseBalanceMap} = require('../../../test/utils/parse-balance-map'); (async function () { const PHASE = 1; - const IN = `./scripts/refik/merkle-and-ipfs/in/prelist-phase-${PHASE}.json`; - const OUT = `./scripts/refik/merkle-and-ipfs/out/phase-${PHASE}.json`; - const IPFS = `./scripts/refik/merkle-and-ipfs/out/phase-${PHASE}-ipfs.json`; + const IN = `./scripts/data/merkle-and-ipfs/in/prelist-phase-${PHASE}.json`; + const OUT = `./scripts/data/merkle-and-ipfs/out/phase-${PHASE}.json`; + const IPFS = `./scripts/data/merkle-and-ipfs/out/phase-${PHASE}-ipfs.json`; const merkleConfig = JSON.parse(fs.readFileSync(IN)); const merkleTree = parseBalanceMap(merkleConfig); @@ -36,9 +36,7 @@ Total: ${totalAddresses} results }, null, 2)); - console.log(` -Results written to ./scripts/refik/merkle-and-ipfs/out/ - `); + console.log(`Results written to ./scripts/data/merkle-and-ipfs/out/`); })(); diff --git a/scripts/data/merkle-and-ipfs/in/ko-staff-list.json b/scripts/data/merkle-and-ipfs/in/ko-staff-list.json index 6b386b11..04399943 100644 --- a/scripts/data/merkle-and-ipfs/in/ko-staff-list.json +++ b/scripts/data/merkle-and-ipfs/in/ko-staff-list.json @@ -17,5 +17,6 @@ "0x5770fFaF8c51E6F7728B36BcC46794107c56641a": 1, "0x3507d8cB9bD241b6dC37Be87c8a30bF8d112fB4A": 1, "0xFc8e2EA4f20E08b6124FDEb6813561349BC1F599": 1, + "0x3f8c962eb167ad2f80c72b5f933511ccdf0719d4": 1, "0x5c9a5964c7C85c15C87854b0938a94f99485AA46": 1 } diff --git a/scripts/data/merkle-and-ipfs/in/prelist-phase-1.json b/scripts/data/merkle-and-ipfs/in/prelist-phase-1.json index fcd19e17..e8a044a2 100644 --- a/scripts/data/merkle-and-ipfs/in/prelist-phase-1.json +++ b/scripts/data/merkle-and-ipfs/in/prelist-phase-1.json @@ -14,5 +14,6 @@ "0x2ac0b77652cfb7ebde8190d7c3e1a41e18dcc66f": 1, "0xD84708b4d3c9a3B26c22C62511236190C5a30e8c": 1, "0xf7C088582dcd4B2CA1e629de63699034D2cE7880": 1, + "0x3f8c962eb167ad2f80c72b5f933511ccdf0719d4": 1, "0x5770fFaF8c51E6F7728B36BcC46794107c56641a": 1 -} \ No newline at end of file +} diff --git a/scripts/data/merkle-and-ipfs/out/phase-1-ipfs.json b/scripts/data/merkle-and-ipfs/out/phase-1-ipfs.json index 97cd1fab..3da028b6 100644 --- a/scripts/data/merkle-and-ipfs/out/phase-1-ipfs.json +++ b/scripts/data/merkle-and-ipfs/out/phase-1-ipfs.json @@ -1,8 +1,7 @@ { "results": { - "IpfsHash": "QmbiUuNAi6DfJrQcnzpJBvQNkRAbkdB8JyVgPLka1dkeMv", - "PinSize": 7499, - "Timestamp": "2022-02-18T13:44:18.576Z", - "isDuplicate": true + "IpfsHash": "QmYr59W2kynwCqo83SLpBXHXs4HfPkea9eAexECi2dNu6u", + "PinSize": 8997, + "Timestamp": "2022-03-23T14:51:43.820Z" } } \ No newline at end of file diff --git a/scripts/data/merkle-and-ipfs/out/phase-1.json b/scripts/data/merkle-and-ipfs/out/phase-1.json index 795a3f6b..9ca8b30a 100644 --- a/scripts/data/merkle-and-ipfs/out/phase-1.json +++ b/scripts/data/merkle-and-ipfs/out/phase-1.json @@ -1,166 +1,189 @@ { "generateMerkleProofs": { - "merkleRoot": "0x0f5201869424745eea087a0123e8eb29c2754e14655ebbc05fb48177852cedb5", - "tokenTotal": "0x10", + "merkleRoot": "0xd7691a9553d9154779fc29f04d949167702594dfda6fc59a703e6923aab0bbc6", + "tokenTotal": "0x11", "claims": { "0x0b6Fa76a74fb44a1F6e62AC952cd6B1905C1Feb8": { "index": 0, "amount": "0x01", "proof": [ - "0xacf14138c616716a2cec53b912d56b5cb2ca5d6cff2b6a26a91533f3c72d85d7", - "0xee105725a9b1f1403fb542c139d877d0638f7fd32e3c06a3a2fe37191e520b9a", - "0xe50e6e5a1fd158f307801e7fe3f185b881ad9c119b7fc2c538973aa277e0e7f9", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0xa0ebcba69c19131f26286dff90b7a58b52c45e18d85bcf856a0a43b7e73547b7", + "0xf84ee98a7cba323e477004c7f9b08cf1ac2ce2819868ad2bb7b094050c00d789", + "0x43681f14e42c751a85ada893ed2c08af0b79fd41cfde26ec3c1b4c764b227929", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, "0x0f48669B1681D41357EAc232F516B77D0c10F0F1": { "index": 1, "amount": "0x01", "proof": [ - "0x331f18329c175452adb0ecf512ddfb8a86066136512509daf641316afebf59bc", - "0xfc4f6a07d08126dcb51237f11078f098ddf7affb90f1d1e6977a7c016c767007", - "0xdd39bcd8d99e72a0bcf56743a8ecec21926ba4234f17f2bf0b9c00fad2535df6", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0x2eb3e406babc3d35b8d875d06c9d674c983515937a9e05a4d618c10bf08ee17c", + "0x29947b312535d7bfe978db6a932421b616833c5d4cd6a60483df4b3ddb6f847d", + "0x00a9d7e12f65181f2711f9cab1a602e770315909819099dadcdf56e15450b819", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, "0x2AC0B77652cfb7ebdE8190d7c3E1a41E18dCc66f": { "index": 2, "amount": "0x01", "proof": [ - "0x1d04b650d0899601c809e05eacdeb0a3c446aaa3a7e1f897f31a00e3c54506b4", - "0xee6b3f7476b00e16414b06b34d21efa69be3886a3bb08c5cd9b0f31e000fe245", - "0xdd39bcd8d99e72a0bcf56743a8ecec21926ba4234f17f2bf0b9c00fad2535df6", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0x11c720926087f5963d61d24d2c065c7a272957c944a99cbe498ea62ac188216c", + "0x40ab80616d48b89eea3777508055b0c3237fa48277af035dba74d5ac5f29ef21", + "0x00a9d7e12f65181f2711f9cab1a602e770315909819099dadcdf56e15450b819", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0x401cBf2194D35D078c0BcdAe4BeA42275483ab5F": { + "0x3f8C962eb167aD2f80C72b5F933511CcDF0719D4": { "index": 3, "amount": "0x01", "proof": [ - "0xcf80809930de677e5a24d1f6f270293d9fad14bcb2ebc8eedb309f06dbff4ea5", - "0x1bf4bc16154a71a308567c23a08647ba11baf944673160124b4522478de31df7", - "0xe50e6e5a1fd158f307801e7fe3f185b881ad9c119b7fc2c538973aa277e0e7f9", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0x4cb37f9fd65cb45b24b243fd7f0ee7af3a756c577878beb36e2e13445118f4d0", + "0x17da6fc5236c4807420ba40767c3d7ed1491873b10fb18dd4b6664298e69c559", + "0x01b20f1edb5a666045e24290febd24d635b9e239cb05b4c84d188eacb967e650", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0x5770fFaF8c51E6F7728B36BcC46794107c56641a": { + "0x401cBf2194D35D078c0BcdAe4BeA42275483ab5F": { "index": 4, "amount": "0x01", "proof": [ - "0x8dc5309690222a7d37966f6db421efc7358b76c4ac67f34e8a452f528f6f905b", - "0x110a7f7353eced45878934c708fb045ef95cdf0db27a4c4c9c3d69240e1d326d", - "0x929fe87673797a2e75cd13cc47169b73baa1f1e881715555d7156a5baedc930a", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0x56880b61895d30d4a01ffc64074fa3f49bf7ff27b577638f80a9f123536f4a02", + "0x650b7fe3e551d6448022e74b4ae1aa687db0dee0dd05382ced1c7a7a3fc6bff5", + "0x01b20f1edb5a666045e24290febd24d635b9e239cb05b4c84d188eacb967e650", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0x5F8429d70c0B9e18622DAafAd4e8938073a09322": { + "0x5770fFaF8c51E6F7728B36BcC46794107c56641a": { "index": 5, "amount": "0x01", "proof": [ - "0x4020b5f428a50a28dd6c70eb3dc4346026f65321e7092a0ed233189c486ddec1", - "0x13cc78d4833bc835fb2167f26107ac5419441111d2aa79e42320be253663f256", - "0xbfc7d154e4ddce13ce1e3677cd38d897152a7fbee6d475791516649b7ce94225", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0x20e0c760447da478ed21290562792dc56b48bb31c9495bd9babf9590b42f739b", + "0x40ab80616d48b89eea3777508055b0c3237fa48277af035dba74d5ac5f29ef21", + "0x00a9d7e12f65181f2711f9cab1a602e770315909819099dadcdf56e15450b819", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0x681A7040477Be268A4b9A02c5e8263fd9fEbf0a9": { + "0x5F8429d70c0B9e18622DAafAd4e8938073a09322": { "index": 6, "amount": "0x01", "proof": [ - "0xc3212357459a52c591070681f656ad0d764363bb27af7bd41f21340eadcde95a", - "0xee105725a9b1f1403fb542c139d877d0638f7fd32e3c06a3a2fe37191e520b9a", - "0xe50e6e5a1fd158f307801e7fe3f185b881ad9c119b7fc2c538973aa277e0e7f9", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0x674c70396d28cec0f2e9ab9a42bd541389db4d179414e8f4017506591db51fce", + "0xac1027e7912b910587cc96c548c08f1482339c141a2490e9d3e6841f21eff98c", + "0x9fc5d8c37ec2556f2bf84d251eb783568ab82d0f9fe9ccac9b3c3930e4edefd3", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0x70482d3BD44fbEF402a0CEE6D9BeA516d12bE128": { + "0x681A7040477Be268A4b9A02c5e8263fd9fEbf0a9": { "index": 7, "amount": "0x01", "proof": [ - "0x32da3f738526859f9b5c101f83373ff4a44b88ffb20b44dca81eed815acda9a2", - "0xfc4f6a07d08126dcb51237f11078f098ddf7affb90f1d1e6977a7c016c767007", - "0xdd39bcd8d99e72a0bcf56743a8ecec21926ba4234f17f2bf0b9c00fad2535df6", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0x71443eeed6af9492d1c21a70debb47fc3f58d10f9f2fce97eb096881f0eb7f52", + "0x52a52cb76e4681bc20333bc00e335359dde62c6a29008a43ec289e3b7ef2c5d6", + "0x9fc5d8c37ec2556f2bf84d251eb783568ab82d0f9fe9ccac9b3c3930e4edefd3", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0x7DEc37c03ea5ca2C47ad2509BE6abAf8C63CDB39": { + "0x70482d3BD44fbEF402a0CEE6D9BeA516d12bE128": { "index": 8, "amount": "0x01", "proof": [ - "0x76da0b56d692d195a45ef7a0770b438842560cd0e4d9138f426bc92930f724f8", - "0x110a7f7353eced45878934c708fb045ef95cdf0db27a4c4c9c3d69240e1d326d", - "0x929fe87673797a2e75cd13cc47169b73baa1f1e881715555d7156a5baedc930a", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0x13c7481ffb558add6f440015dd38e3af5d49416b86770cf97747b62d3f307918" ] }, - "0x88157aCff3FAfD9696D7CA005291fB0b6e4dc833": { + "0x7DEc37c03ea5ca2C47ad2509BE6abAf8C63CDB39": { "index": 9, "amount": "0x01", "proof": [ - "0x50c5111d1740361fd1cd7e2d061d9971ab2324b5c1704ad87415ff920209e935", - "0xc523f985fe6d9975e719e6529b5819cbad712dbe4820b6a89d10d383907bd8c0", - "0xbfc7d154e4ddce13ce1e3677cd38d897152a7fbee6d475791516649b7ce94225", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0x64127c57c54f8f135bf194be08ea08b0f97c8f7664f3d27571ba5c25bddc9f0a", + "0xac1027e7912b910587cc96c548c08f1482339c141a2490e9d3e6841f21eff98c", + "0x9fc5d8c37ec2556f2bf84d251eb783568ab82d0f9fe9ccac9b3c3930e4edefd3", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0x93B63028Dd964318Ce6C8c0437Be0097F35bc366": { + "0x88157aCff3FAfD9696D7CA005291fB0b6e4dc833": { "index": 10, "amount": "0x01", "proof": [ - "0x9f961547eec0edd1aa2858ac97adf3eb65bb84d82e844367f04dc7907efe06f3", - "0x05e6d63a784a2219c3f10b60fc0be352657891164b0154cd3db8b26d6645e17d", - "0x929fe87673797a2e75cd13cc47169b73baa1f1e881715555d7156a5baedc930a", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0xc3212357459a52c591070681f656ad0d764363bb27af7bd41f21340eadcde95a", + "0xf84ee98a7cba323e477004c7f9b08cf1ac2ce2819868ad2bb7b094050c00d789", + "0x43681f14e42c751a85ada893ed2c08af0b79fd41cfde26ec3c1b4c764b227929", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0xD84708b4d3c9a3B26c22C62511236190C5a30e8c": { + "0x93B63028Dd964318Ce6C8c0437Be0097F35bc366": { "index": 11, "amount": "0x01", "proof": [ - "0x3ddd72be987a06ded0efdba917a8dcf343c8b4234d00db12447a9a11b91c9076", - "0x13cc78d4833bc835fb2167f26107ac5419441111d2aa79e42320be253663f256", - "0xbfc7d154e4ddce13ce1e3677cd38d897152a7fbee6d475791516649b7ce94225", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0xd25375733a1e349847b23176a5894368ab5c916c21fae867dbf333e314e65752", + "0x5224011b00ca0c6113f2cfdc448d12fbcdff5a2658d1228c3f0f80eb0f0b2c22", + "0x43681f14e42c751a85ada893ed2c08af0b79fd41cfde26ec3c1b4c764b227929", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0xE27Dc3AA4352244Dd8bAAB17e8813339456f8a2C": { + "0xD84708b4d3c9a3B26c22C62511236190C5a30e8c": { "index": 12, "amount": "0x01", "proof": [ - "0x55320adf0172c884d66e3e8552b03d2ff18ccc193d35741a8efa6d44e84a3f05", - "0xc523f985fe6d9975e719e6529b5819cbad712dbe4820b6a89d10d383907bd8c0", - "0xbfc7d154e4ddce13ce1e3677cd38d897152a7fbee6d475791516649b7ce94225", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0x32da3f738526859f9b5c101f83373ff4a44b88ffb20b44dca81eed815acda9a2", + "0x29947b312535d7bfe978db6a932421b616833c5d4cd6a60483df4b3ddb6f847d", + "0x00a9d7e12f65181f2711f9cab1a602e770315909819099dadcdf56e15450b819", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0xd514f2065fde42a02c73c913735E8E5a2FcC085E": { + "0xE27Dc3AA4352244Dd8bAAB17e8813339456f8a2C": { "index": 13, "amount": "0x01", "proof": [ - "0xe0135c20fd8afd0fb3fa176b5898995dff79010db4f7a97fa9c6cc38f24f073c", - "0x1bf4bc16154a71a308567c23a08647ba11baf944673160124b4522478de31df7", - "0xe50e6e5a1fd158f307801e7fe3f185b881ad9c119b7fc2c538973aa277e0e7f9", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0xda8f0038a841e4590dc139df80d58307bfd6f7badbb3ea423dbf5d07c4cc6d50", + "0x5224011b00ca0c6113f2cfdc448d12fbcdff5a2658d1228c3f0f80eb0f0b2c22", + "0x43681f14e42c751a85ada893ed2c08af0b79fd41cfde26ec3c1b4c764b227929", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0xd9c575163C3fC0948490b02cCe19aCf8D9eC8427": { + "0xd514f2065fde42a02c73c913735E8E5a2FcC085E": { "index": 14, "amount": "0x01", "proof": [ - "0x973231ec9fa4f2e4323d53ac44ab08cac34fb5e12ec500fda08938ebd1e97e4b", - "0x05e6d63a784a2219c3f10b60fc0be352657891164b0154cd3db8b26d6645e17d", - "0x929fe87673797a2e75cd13cc47169b73baa1f1e881715555d7156a5baedc930a", - "0x11cb8c43ce852cec5299dbc5a2216bd472bb1cc34604ec374e943f1283c40a9f" + "0x4615812038579b3dd14fbafae49580691223f4b9287e3471e54d754eac1ba759", + "0x17da6fc5236c4807420ba40767c3d7ed1491873b10fb18dd4b6664298e69c559", + "0x01b20f1edb5a666045e24290febd24d635b9e239cb05b4c84d188eacb967e650", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] }, - "0xf7C088582dcd4B2CA1e629de63699034D2cE7880": { + "0xd9c575163C3fC0948490b02cCe19aCf8D9eC8427": { "index": 15, "amount": "0x01", "proof": [ - "0x20e0c760447da478ed21290562792dc56b48bb31c9495bd9babf9590b42f739b", - "0xee6b3f7476b00e16414b06b34d21efa69be3886a3bb08c5cd9b0f31e000fe245", - "0xdd39bcd8d99e72a0bcf56743a8ecec21926ba4234f17f2bf0b9c00fad2535df6", - "0x2ae7dd9a7782967d8aaa5e7bf568429c4d0a95a67d026efa6f62458824bfbe18" + "0x96326a43db99248b0fda222b655d16a68c1a11c139197bdb41ee52fe75faf510", + "0x52a52cb76e4681bc20333bc00e335359dde62c6a29008a43ec289e3b7ef2c5d6", + "0x9fc5d8c37ec2556f2bf84d251eb783568ab82d0f9fe9ccac9b3c3930e4edefd3", + "0x4fa936754d233cc60c98f3b753a6b6cc700668bf6ac300e8ad636565c65ec003", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" + ] + }, + "0xf7C088582dcd4B2CA1e629de63699034D2cE7880": { + "index": 16, + "amount": "0x01", + "proof": [ + "0x6077039788d8b7dc9caa605a10429708170e190d107d692583abec5defcaba14", + "0x650b7fe3e551d6448022e74b4ae1aa687db0dee0dd05382ced1c7a7a3fc6bff5", + "0x01b20f1edb5a666045e24290febd24d635b9e239cb05b4c84d188eacb967e650", + "0x2c271856f06fcc2bcf46cf9c246dfb8e7830945d2274d2483b9582f330125c8c", + "0xed53084c5b879979bf3688bc78e0a48213e31b6e287016ba7079c20298d0a8dd" ] } } diff --git a/scripts/scratch-pad/get_upgrdable_gated_marketplace_data.js b/scripts/scratch-pad/gated/get_upgrdable_gated_marketplace_data.js similarity index 93% rename from scripts/scratch-pad/get_upgrdable_gated_marketplace_data.js rename to scripts/scratch-pad/gated/get_upgrdable_gated_marketplace_data.js index 1a842247..5435c4e4 100644 --- a/scripts/scratch-pad/get_upgrdable_gated_marketplace_data.js +++ b/scripts/scratch-pad/gated/get_upgrdable_gated_marketplace_data.js @@ -2,7 +2,7 @@ const prompt = require('prompt-sync')(); const hre = require('hardhat'); const {ethers, upgrades} = hre; -const KODAV3UpgradableGatedMarketplace = require('../../artifacts/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol/KODAV3UpgradableGatedMarketplace.json'); +const KODAV3UpgradableGatedMarketplace = require('../../../artifacts/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol/KODAV3UpgradableGatedMarketplace.json'); async function main() { const [deployer] = await ethers.getSigners(); diff --git a/scripts/scratch-pad/get_upgrdable_minting_factory_data.js b/scripts/scratch-pad/gated/get_upgrdable_minting_factory_data.js similarity index 93% rename from scripts/scratch-pad/get_upgrdable_minting_factory_data.js rename to scripts/scratch-pad/gated/get_upgrdable_minting_factory_data.js index 53d1c8d0..3e5819c6 100644 --- a/scripts/scratch-pad/get_upgrdable_minting_factory_data.js +++ b/scripts/scratch-pad/gated/get_upgrdable_minting_factory_data.js @@ -2,7 +2,7 @@ const prompt = require('prompt-sync')(); const hre = require('hardhat'); const {ethers} = hre; -const MintingFactoryV2 = require('../../artifacts/contracts/minter/MintingFactoryV2.sol/MintingFactoryV2.json'); +const MintingFactoryV2 = require('../../../artifacts/contracts/minter/MintingFactoryV2.sol/MintingFactoryV2.json'); async function main() { const [deployer] = await ethers.getSigners(); diff --git a/scripts/scratch-pad/gated/mint_batch_and_setup_sale.js b/scripts/scratch-pad/gated/mint_batch_and_setup_sale.js new file mode 100644 index 00000000..c9da4da9 --- /dev/null +++ b/scripts/scratch-pad/gated/mint_batch_and_setup_sale.js @@ -0,0 +1,93 @@ +const prompt = require('prompt-sync')(); +const hre = require('hardhat'); +const {ethers, upgrades} = hre; + +const {BigNumber} = ethers; +const moment = require('moment'); + +const fs = require('fs'); +const _ = require('lodash'); +const path = require('path'); +const axios = require('axios'); + +const KODAV3UpgradableGatedMarketplace = require('../../../artifacts/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol/KODAV3UpgradableGatedMarketplace.json'); +const MintingFactoryV2 = require('../../../artifacts/contracts/minter/MintingFactoryV2.sol/MintingFactoryV2.json'); + +async function main() { + try { + const [deployer] = await ethers.getSigners(); + console.log('Signer account:', await deployer.getAddress()); + + const {name: network} = hre.network; + console.log(`Running on network [${network}]`); + + const ALL_STAFF_MERKEL = '0xd7691a9553d9154779fc29f04d949167702594dfda6fc59a703e6923aab0bbc6'; + const ALL_STAFF_IPFS = 'QmYr59W2kynwCqo83SLpBXHXs4HfPkea9eAexECi2dNu6u'; + const KO_ACCOUNT = '0x3f8c962eb167ad2f80c72b5f933511ccdf0719d4'; + + ////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////////// + + const mintingFactoryAddress = prompt('MintingFactoryV2 address? '); + const mintingFactory = new ethers.Contract( + mintingFactoryAddress, + MintingFactoryV2.abi, + deployer + ); + prompt(`Found Minting factory [${mintingFactory.address}] for network [${network}] - click enter to continue ... ?`); + + const kodaV3GatedMarketplaceAddress = prompt('KodaV3GatedMarketplaceAddress address? '); + const gatedMarketplace = new ethers.Contract( + kodaV3GatedMarketplaceAddress, + KODAV3UpgradableGatedMarketplace.abi, + deployer + ); + prompt(`Found Gated marketplace [${gatedMarketplace.address}] for network [${network}] - click enter to continue ... ?`); + + const {index, proof} = await getMerkleApiDetails(network, KO_ACCOUNT); + console.log({index, proof}); + + // // create a hard coded sale via proxy concept for KO account + // const tx = await mintingFactory.connect(deployer).mintBatchEditionGatedAndPublicAsProxy( + // KO_ACCOUNT, + // '10', + // moment().add(1, 'weeks').unix().toString(), + // ethers.utils.parseEther('0.01'), + // '0x0000000000000000000000000000000000000000', + // 'ipfs://ipfs/QmZY2cXiuF3v8MUbabByT4aHiFgxi2ki1KsgyTsUE1VGzj' + // ); + // console.log('tx', tx); + + const createPhasesTx = await gatedMarketplace.connect(deployer).createPhases( + '344000', + [moment().unix().toString()], + [moment().add(1, 'weeks').unix().toString()], + [ethers.utils.parseEther('0.01')], + ['10'], + ['1'], + [ALL_STAFF_MERKEL], + [ALL_STAFF_IPFS] + ); + console.log(`Create phases transaction`, createPhasesTx); + + } catch (err) { + console.error('ERROR ! : ', err); + } +} + +async function getMerkleApiDetails(network, address) { + const url = `https://us-central1-known-origin-io.cloudfunctions.net/main/api/network/${network === 'rinkeby' ? 4 : 1}/selfservice/user-minting-access/v3/${address}`; + const res = await axios({method: 'get', url}); + return { + index: res.data.merkleProofAndIndex.index, + proof: res.data.merkleProofAndIndex.proof + }; +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/scratch-pad/gated/setup_hardcoded_gated_sale_with_phases.js b/scripts/scratch-pad/gated/setup_hardcoded_gated_sale_with_phases.js new file mode 100644 index 00000000..009ac391 --- /dev/null +++ b/scripts/scratch-pad/gated/setup_hardcoded_gated_sale_with_phases.js @@ -0,0 +1,73 @@ +const prompt = require('prompt-sync')(); +const hre = require('hardhat'); +const {ethers, upgrades} = hre; + +const {BigNumber} = ethers; +const moment = require('moment'); + +const fs = require('fs'); +const _ = require('lodash'); +const path = require('path'); +const axios = require('axios'); + +const KODAV3UpgradableGatedMarketplace = require('../../../artifacts/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol/KODAV3UpgradableGatedMarketplace.json'); + +async function main() { + try { + const [deployer] = await ethers.getSigners(); + console.log('Signer account:', await deployer.getAddress()); + + const {name: network} = hre.network; + console.log(`Running on network [${network}]`); + + const kodaV3GatedMarketplaceAddress = prompt('KodaV3GatedMarketplaceAddress address? '); + const gatedMarketplace = new ethers.Contract( + kodaV3GatedMarketplaceAddress, + KODAV3UpgradableGatedMarketplace.abi, + deployer + ); + prompt(`Found Gated marketplace [${gatedMarketplace.address}] for network [${network}] - click enter to continue ... ?`); + + const ALL_STAFF_MERKEL = '0xd7691a9553d9154779fc29f04d949167702594dfda6fc59a703e6923aab0bbc6'; + const ALL_STAFF_IPFS = 'QmYr59W2kynwCqo83SLpBXHXs4HfPkea9eAexECi2dNu6u'; + const KO_ACCOUNT = '0x3f8c962eb167ad2f80c72b5f933511ccdf0719d4'; + + console.log('Artist Address : ', KO_ACCOUNT); + + // Edition - 329000 (1-of-1) + const createSaleTx1 = await gatedMarketplace.connect(deployer).createSaleWithPhases( + '329000', + [moment().unix().toString()], + [moment().add(1, 'weeks').unix().toString()], + [ethers.utils.parseEther('0.01')], + ['1'], + ['1'], + [ALL_STAFF_MERKEL], + [ALL_STAFF_IPFS] + ); + console.log(`Create 1st sale transaction`, createSaleTx1); + + // Edition - 328000 (1-of-500) + const createSaleTx2 = await gatedMarketplace.connect(deployer).createSaleWithPhases( + '328000', + [moment().unix().toString()], + [moment().add(1, 'weeks').unix().toString()], + [ethers.utils.parseEther('0.01')], + ['500'], + ['5'], + [ALL_STAFF_MERKEL], + [ALL_STAFF_IPFS] + ); + console.log(`Create 2nd sale transaction`, createSaleTx2); + + } catch (err) { + console.error('ERROR ! : ', err); + } +} + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/scratch-pad/x_setup_gated_sale_with_phases.js b/scripts/scratch-pad/x_setup_gated_sale_with_phases.js deleted file mode 100644 index cfa5083e..00000000 --- a/scripts/scratch-pad/x_setup_gated_sale_with_phases.js +++ /dev/null @@ -1,209 +0,0 @@ -const prompt = require('prompt-sync')(); -const hre = require('hardhat'); -const {ethers} = hre; -const {BigNumber} = ethers; -const moment = require('moment') - - -const fs = require('fs'); -const _ = require('lodash'); -const path = require('path') -const axios = require('axios') - -const pinataSDK = require('@pinata/sdk'); -const pinata = pinataSDK(process.env.KO_PINATA_API_KEY, process.env.KO_PINATA_API_SECRET); -const {parseBalanceMap} = require('../../test/utils/parse-balance-map'); - -const MintingFactoryV2 = require('../../artifacts/contracts/minter/MintingFactoryV2.sol/MintingFactoryV2.json'); -const KODAV3UpgradableGatedMarketplace = require('../../artifacts/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol/KODAV3UpgradableGatedMarketplace.json'); - -const _6_MONTHS = 15780000; -const TOKEN_URI = 'ipfs://ipfs/Qmd9xQFBfqMZLG7RA2rXor7SA7qyJ1Pk2F2mSYzRQ2siMv'; - -async function createMerkle(inFileName, outFileName, artistAddress) { - try { - - if(!inFileName || !outFileName || !artistAddress) { - throw new Error('missing input variables for createMerkle') - } - - const merkleConfig = JSON.parse(fs.readFileSync(path.resolve(__dirname, `../data/merkle-and-ipfs/in/${inFileName}`))); - const merkleTree = parseBalanceMap(merkleConfig); - - const totalAddresses = parseInt(ethers.utils.formatUnits(merkleTree.tokenTotal, 'wei')); - - console.log(` - Generated merkle root: ${merkleTree.merkleRoot} - - Total: ${totalAddresses} - `); - - fs.writeFileSync(path.resolve(__dirname, `../data/merkle-and-ipfs/out/${outFileName}`), JSON.stringify({ - generateMerkleProofs: merkleTree - }, null, 2)); - - console.log(` -Results written to ../data/merkle-and-ipfs/out/${outFileName} - `); - - const results = await pinata.pinFileToIPFS(fs.createReadStream(path.resolve(__dirname, `../data/merkle-and-ipfs/out/${outFileName}`))); - console.log(`Pinning IPFS hash with proofs ${results.IpfsHash}`); - - return { - merkleRoot: merkleTree.merkleRoot, - ipfsHash: results.IpfsHash, - artistIndex: merkleTree.claims[artistAddress].index, - artistProof: merkleTree.claims[artistAddress].proof - } - } catch (err) { - console.error(err) - throw err - } -} - -async function getEditionId(contract, web3, tx) { - try { - await tx.wait(1) - - const txReceipt = await web3.getTransactionReceipt(tx.hash); - - const results = await contract.queryFilter( - state.mintingFactory.interface.events['EditionMintedAndListed(uint256, SaleType);'], - txReceipt.blockNumber, - txReceipt.blockNumber - ); - - return results[0].args._editionId - - } catch (err) { - console.error(err) - throw err - } -} - -async function getMerkleApiDetails(network, address) { - network = network === 'rinkeby' ? 4 : 1 - let url = `https://us-central1-known-origin-io.cloudfunctions.net/main/api/network/${network}/merklevault/metadata/${address}` - - let res = await axios({ - method: 'get', - url - }) - - return { - index: res.data.merkleProofAndIndex.index, - proof: res.data.merkleProofAndIndex.proof - } - -} - -async function main() { - try { - const rootTime = moment() - - console.log(`Starting process at ${rootTime.unix()}`) - - const [deployer] = await ethers.getSigners(); - console.log('Signer account:', await deployer.getAddress()); - const {name: network} = hre.network; - console.log(`Running on network [${network}]`); - - const web3 = new ethers.getDefaultProvider(`${network}`); - - // STEP 1 - get the contracts - const mintingFactoryV2Address = prompt('MintingFactoryV2Address address? ', '0x32f43177CB70EB482cFD5DD1f3D48A760241A36F'); - const mintingFactoryDeployment = new ethers.Contract( - mintingFactoryV2Address, - MintingFactoryV2.abi, - deployer - ) - prompt(`Found Minting Factory V2 [${mintingFactoryDeployment.address}] for network [${network}] - click enter to continue ... ?`); - - const kodaV3GatedMarketplaceAddress = prompt('KodaV3GatedMarketplaceAddress address? ', '0xB3563C45E45714d9B1a61171c0774a6deb07123D'); - const kodaV3GatedMarketplaceDeployment = new ethers.Contract( - kodaV3GatedMarketplaceAddress, - KODAV3UpgradableGatedMarketplace.abi, - deployer - ); - prompt(`Found Gated marketplace [${kodaV3GatedMarketplaceDeployment.address}] for network [${network}] - click enter to continue ... ?`); - - // STEP 2 - generate a merkle tree - const merkleInFileName = prompt('File Name for merkle tree addresses - IN file? ', 'ko-staff-list.json') - const merkleOutFileName = prompt('File Name for generated merkle tree - OUT file? ', 'ko-merkle.json') - const merkleArtistAddress = prompt('Artist address for merkle tree? ', '0x681A7040477Be268A4b9A02c5e8263fd9fEbf0a9') - - console.log('Artist Address : ', merkleArtistAddress) - - let merkleTree = await createMerkle(merkleInFileName, merkleOutFileName, merkleArtistAddress) - let artistMerkleInfo = await getMerkleApiDetails(network, merkleArtistAddress) - - console.log( - `Merkle generated and merkle artist information extracted: - - MerkleRoot: ${merkleTree.merkleRoot}, - IPFSHash: ${merkleTree.ipfsHash}, - `) - - console.log('ARTIST MERKLE INFO : ', merkleArtistAddress, artistMerkleInfo.index, artistMerkleInfo.proof) - - const batchEditionSize = prompt('Edition size for batch edition? ', 100) - const publicStartDate = prompt('Start date for public sale? ', rootTime.add(1, 'd').unix()) - const publicPrice = prompt('Price for public sale in eth? ', '0.2') - - // const mintEstimateGas = await mintingFactoryDeployment.connect(merkleArtistAddress.toLowerCase()).estimateGas.mintBatchEditionGatedAndPublic( - // batchEditionSize, - // publicStartDate, - // ethers.utils.parseEther(publicPrice).toString(), - // artistMerkleInfo.index, - // artistMerkleInfo.proof, - // ethers.constants.AddressZero, - // TOKEN_URI, - // ) - - const mintTx = await mintingFactoryDeployment.connect(merkleArtistAddress).mintBatchEditionGatedAndPublic( - batchEditionSize, - publicStartDate, - ethers.utils.parseEther(publicPrice).toString(), - artistMerkleInfo.index, - artistMerkleInfo.proof, - ethers.constants.AddressZero, - TOKEN_URI, - // {gasLimit: mintEstimateGas.add(10000)} - ) - - console.log(`Mint transaction: ${mintTx}`) - // - // const editionID = await getEditionId(web3, mintTx) - // - // console.log(`Edition ID extracted: ${editionID}`) - // - // const phaseStartDate = prompt('Start date for phase? ', rootTime.add(time.duration.hours(1))) - // const phasePrice = prompt('Price for phase? ', ether('0.1').toString()) - // const phaseTotalMintCap = prompt('Total mint cap for phase? ', Math.floor(batchEditionSize / 2)) - // const phaseWalletMintCap = prompt('Wallet mint cap for phase? ', 1) - // - // const phaseTx = await kodaV3GatedMarketplaceDeployment.createPhase( - // editionID.toString(), - // phaseStartDate, - // publicStartDate, - // phasePrice, - // phaseTotalMintCap, - // phaseWalletMintCap, - // merkleInfo.merkleRoot, - // merkleInfo.ipfsHash - // ) - // - // console.log(`Phase transaction: ${phaseTx}`) - // - // console.log('Finished!'); - } catch (err) { - console.error('ERROR ! : ', err) - } -} - -main() - .then(() => process.exit(0)) - .catch(error => { - console.error(error); - process.exit(1); - }); From 5c50e6f1979178ff0c5b692f8e0f43fee1862e18 Mon Sep 17 00:00:00 2001 From: James Morgan Date: Wed, 23 Mar 2022 17:19:46 +0000 Subject: [PATCH 5/7] Contract verification --- .../KODAV3UpgradableGatedMarketplace.sol | 44 +++++++++---------- contracts-flat/MintingFactoryV2.sol | 24 +++++----- .../gas/GatedSaleGasCostings.test.js | 8 ++-- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/contracts-flat/KODAV3UpgradableGatedMarketplace.sol b/contracts-flat/KODAV3UpgradableGatedMarketplace.sol index 8c4e9a65..c802a9e8 100644 --- a/contracts-flat/KODAV3UpgradableGatedMarketplace.sol +++ b/contracts-flat/KODAV3UpgradableGatedMarketplace.sol @@ -49,7 +49,7 @@ library MerkleProof { // File @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; @@ -248,7 +248,7 @@ library AddressUpgradeable { // File @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; @@ -330,7 +330,7 @@ abstract contract Initializable { // File @openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; @@ -408,7 +408,7 @@ abstract contract ReentrancyGuardUpgradeable is Initializable { // File @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; @@ -448,7 +448,7 @@ abstract contract ContextUpgradeable is Initializable { // File @openzeppelin/contracts-upgradeable/security/PausableUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts v4.4.1 (security/Pausable.sol) pragma solidity ^0.8.0; @@ -553,7 +553,7 @@ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { // File @openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; @@ -577,7 +577,7 @@ interface IERC1822ProxiableUpgradeable { // File @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; @@ -597,7 +597,7 @@ interface IBeaconUpgradeable { // File @openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) pragma solidity ^0.8.0; @@ -685,7 +685,7 @@ library StorageSlotUpgradeable { // File @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; @@ -899,7 +899,7 @@ abstract contract ERC1967UpgradeUpgradeable is Initializable { // File @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; @@ -1009,7 +1009,7 @@ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable // File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 -// SPDX-License-Identifier: MIT +// pragma solidity ^0.8.0; @@ -1094,7 +1094,7 @@ interface IERC20 { // File contracts/access/IKOAccessControlsLookup.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -1115,7 +1115,7 @@ interface IKOAccessControlsLookup { // File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 -// SPDX-License-Identifier: MIT +// pragma solidity ^0.8.0; @@ -1143,7 +1143,7 @@ interface IERC165 { // File @openzeppelin/contracts/token/ERC721/IERC721.sol@v4.2.0 -// SPDX-License-Identifier: MIT +// pragma solidity ^0.8.0; @@ -1287,7 +1287,7 @@ interface IERC721 is IERC165 { // File contracts/core/IERC2309.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -1317,7 +1317,7 @@ interface IERC2309 { // File contracts/core/IERC2981.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -1362,7 +1362,7 @@ interface IERC2981 is IERC165, IERC2981EditionExtension { // File contracts/core/IHasSecondarySaleFees.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -1380,7 +1380,7 @@ interface IHasSecondarySaleFees is IERC165 { // File contracts/core/IKODAV3.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -1459,7 +1459,7 @@ IHasSecondarySaleFees // Rariable / Foundation royalties // File contracts/marketplace/BaseUpgradableMarketplace.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -1624,7 +1624,7 @@ abstract contract BaseUpgradableMarketplace is ReentrancyGuardUpgradeable, Pausa // File contracts/marketplace/IKODAV3Marketplace.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; interface IBuyNowMarketplace { @@ -1797,7 +1797,7 @@ interface IKODAV3GatedMarketplace { // File hardhat/console.sol@v2.9.1 -// SPDX-License-Identifier: MIT +// pragma solidity >= 0.4.22 <0.9.0; library console { @@ -3333,7 +3333,7 @@ library console { // File contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; diff --git a/contracts-flat/MintingFactoryV2.sol b/contracts-flat/MintingFactoryV2.sol index 33b10cff..c964be3e 100644 --- a/contracts-flat/MintingFactoryV2.sol +++ b/contracts-flat/MintingFactoryV2.sol @@ -29,7 +29,7 @@ abstract contract Context { // File @openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; @@ -53,7 +53,7 @@ interface IERC1822ProxiableUpgradeable { // File @openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; @@ -73,7 +73,7 @@ interface IBeaconUpgradeable { // File @openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; @@ -272,7 +272,7 @@ library AddressUpgradeable { // File @openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts v4.4.1 (utils/StorageSlot.sol) pragma solidity ^0.8.0; @@ -360,7 +360,7 @@ library StorageSlotUpgradeable { // File @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; @@ -442,7 +442,7 @@ abstract contract Initializable { // File @openzeppelin/contracts-upgradeable/proxy/ERC1967/ERC1967UpgradeUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.2; @@ -656,7 +656,7 @@ abstract contract ERC1967UpgradeUpgradeable is Initializable { // File @openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol@v4.5.2 -// SPDX-License-Identifier: MIT +// // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.0; @@ -766,7 +766,7 @@ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable // File contracts/core/IKODAV3Minter.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -782,7 +782,7 @@ interface IKODAV3Minter { // File contracts/marketplace/IKODAV3Marketplace.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; interface IBuyNowMarketplace { @@ -955,7 +955,7 @@ interface IKODAV3GatedMarketplace { // File contracts/collab/ICollabRoyaltiesRegistry.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; /// @notice Common interface to the edition royalties registry @@ -1000,7 +1000,7 @@ interface ICollabRoyaltiesRegistry { // File contracts/access/IKOAccessControlsLookup.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; @@ -1021,7 +1021,7 @@ interface IKOAccessControlsLookup { // File contracts/minter/MintingFactoryV2.sol -// SPDX-License-Identifier: MIT +// pragma solidity 0.8.4; diff --git a/test/marketplace/gas/GatedSaleGasCostings.test.js b/test/marketplace/gas/GatedSaleGasCostings.test.js index 53cbccf7..c00a929e 100644 --- a/test/marketplace/gas/GatedSaleGasCostings.test.js +++ b/test/marketplace/gas/GatedSaleGasCostings.test.js @@ -137,7 +137,7 @@ contract('Gas golfing test ... ', function () { console.log('Increased time to start sale'); }); - describe('Buying all 1000', async () => { + describe.skip('Buying all 1000', async () => { it('1 per account', async () => { for (let i = 0; i < 1000; i++) { console.log(`Minting ${i}`); @@ -173,7 +173,7 @@ contract('Gas golfing test ... ', function () { }).timeout(5 * 60 * 1000); }); - describe('Buying all 500 editions', async () => { + describe.skip('Buying all 500 editions', async () => { it('1 per account', async () => { for (let i = 0; i < 500; i++) { console.log(`Minting ${i}`); @@ -209,7 +209,7 @@ contract('Gas golfing test ... ', function () { }).timeout(5 * 60 * 1000); }); - describe('Buying all 500 and transferring some', async () => { + describe.skip('Buying all 500 and transferring some', async () => { it('10 transfers are made from start of series', async () => { for (let i = 0; i < 10; i++) { console.log(`transferred ${i}`); @@ -280,7 +280,7 @@ contract('Gas golfing test ... ', function () { }).timeout(5 * 60 * 1000); }) - describe('Buying all 1000 and transferring some', async () => { + describe.skip('Buying all 1000 and transferring some', async () => { it('10 transfers are made from start of series', async () => { for (let i = 0; i < 10; i++) { console.log(`transferred ${i}`); From 248e347b38e03e23728f0a41f986f43126a0cf1b Mon Sep 17 00:00:00 2001 From: James Morgan Date: Wed, 23 Mar 2022 21:30:18 +0000 Subject: [PATCH 6/7] Removing comments --- contracts-flat/ClaimableFundsReceiverV1.sol | 2 +- contracts-flat/ClaimableFundsSplitterV1.sol | 2 +- contracts-flat/CollabRoyaltiesRegistry.sol | 2 +- contracts-flat/KOAccessControls.sol | 2 +- contracts-flat/KODAV3PrimaryMarketplace.sol | 2 +- contracts-flat/KODAV3SecondaryMarketplace.sol | 2 +- contracts-flat/KODAV3UpgradableGatedMarketplace.sol | 2 +- contracts-flat/KnownOriginDigitalAssetV3.sol | 2 +- contracts-flat/MintingFactory.sol | 2 +- contracts-flat/MintingFactoryV2.sol | 2 +- contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol | 2 -- 11 files changed, 10 insertions(+), 12 deletions(-) diff --git a/contracts-flat/ClaimableFundsReceiverV1.sol b/contracts-flat/ClaimableFundsReceiverV1.sol index bb0d751d..7e764753 100644 --- a/contracts-flat/ClaimableFundsReceiverV1.sol +++ b/contracts-flat/ClaimableFundsReceiverV1.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 diff --git a/contracts-flat/ClaimableFundsSplitterV1.sol b/contracts-flat/ClaimableFundsSplitterV1.sol index ef0b58d7..d89749f3 100644 --- a/contracts-flat/ClaimableFundsSplitterV1.sol +++ b/contracts-flat/ClaimableFundsSplitterV1.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/token/ERC20/IERC20.sol@v4.2.0 diff --git a/contracts-flat/CollabRoyaltiesRegistry.sol b/contracts-flat/CollabRoyaltiesRegistry.sol index 2b3be6ce..e66262ee 100644 --- a/contracts-flat/CollabRoyaltiesRegistry.sol +++ b/contracts-flat/CollabRoyaltiesRegistry.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/utils/Context.sol@v4.2.0 diff --git a/contracts-flat/KOAccessControls.sol b/contracts-flat/KOAccessControls.sol index a21e929d..373b51b3 100644 --- a/contracts-flat/KOAccessControls.sol +++ b/contracts-flat/KOAccessControls.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/utils/Context.sol@v4.2.0 diff --git a/contracts-flat/KODAV3PrimaryMarketplace.sol b/contracts-flat/KODAV3PrimaryMarketplace.sol index f4339749..975e5d90 100644 --- a/contracts-flat/KODAV3PrimaryMarketplace.sol +++ b/contracts-flat/KODAV3PrimaryMarketplace.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File contracts/access/IKOAccessControlsLookup.sol diff --git a/contracts-flat/KODAV3SecondaryMarketplace.sol b/contracts-flat/KODAV3SecondaryMarketplace.sol index eea7cd0a..070c4675 100644 --- a/contracts-flat/KODAV3SecondaryMarketplace.sol +++ b/contracts-flat/KODAV3SecondaryMarketplace.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File contracts/marketplace/IKODAV3Marketplace.sol diff --git a/contracts-flat/KODAV3UpgradableGatedMarketplace.sol b/contracts-flat/KODAV3UpgradableGatedMarketplace.sol index c802a9e8..24670aba 100644 --- a/contracts-flat/KODAV3UpgradableGatedMarketplace.sol +++ b/contracts-flat/KODAV3UpgradableGatedMarketplace.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/utils/cryptography/MerkleProof.sol@v4.2.0 diff --git a/contracts-flat/KnownOriginDigitalAssetV3.sol b/contracts-flat/KnownOriginDigitalAssetV3.sol index a7eb1c7f..95623c16 100644 --- a/contracts-flat/KnownOriginDigitalAssetV3.sol +++ b/contracts-flat/KnownOriginDigitalAssetV3.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/utils/introspection/IERC165.sol@v4.2.0 diff --git a/contracts-flat/MintingFactory.sol b/contracts-flat/MintingFactory.sol index dc75fb9c..b834aeeb 100644 --- a/contracts-flat/MintingFactory.sol +++ b/contracts-flat/MintingFactory.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/utils/Context.sol@v4.2.0 diff --git a/contracts-flat/MintingFactoryV2.sol b/contracts-flat/MintingFactoryV2.sol index c964be3e..381a57ab 100644 --- a/contracts-flat/MintingFactoryV2.sol +++ b/contracts-flat/MintingFactoryV2.sol @@ -1,4 +1,4 @@ -// Sources flattened with hardhat v2.9.1 https://hardhat.org + // File @openzeppelin/contracts/utils/Context.sol@v4.2.0 diff --git a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol index 774ee52b..3f448a58 100644 --- a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol +++ b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol @@ -8,8 +8,6 @@ import {IKODAV3} from "../core/IKODAV3.sol"; import {IKOAccessControlsLookup} from "../access/IKOAccessControlsLookup.sol"; import {IKODAV3GatedMarketplace} from "./IKODAV3Marketplace.sol"; -import "hardhat/console.sol"; - contract KODAV3UpgradableGatedMarketplace is IKODAV3GatedMarketplace, BaseUpgradableMarketplace { /// @notice emitted when admin updates funds receiver From 8518ab0381074492b668c0236f9d130e2b9d4625 Mon Sep 17 00:00:00 2001 From: James Morgan Date: Thu, 24 Mar 2022 13:26:32 +0000 Subject: [PATCH 7/7] Adding comments --- contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol index 3f448a58..2589df1f 100644 --- a/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol +++ b/contracts/marketplace/KODAV3UpgradableGatedMarketplace.sol @@ -297,6 +297,7 @@ contract KODAV3UpgradableGatedMarketplace is IKODAV3GatedMarketplace, BaseUpgrad emit MintFromSale(_saleId, _phaseId, tokenId, _recipient); + // reduce start ID to allow to optimised token ID determination unchecked {startId = tokenId--;} } _handleSaleFunds(sales[_saleId].fundsReceiver, getPlatformSaleCommissionForSale(_saleId));