From 4cf49b1634927739649ce9d3839a658826104981 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 12 Nov 2020 12:48:50 +0000 Subject: [PATCH 01/22] Pin node version to 12.19.0 using .nvmrc. --- .nvmrc | 1 + 1 file changed, 1 insertion(+) create mode 100644 .nvmrc diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000..260a0e20 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +12.19.0 From 07ca31e03fb47a7a457d0f33658b1ebd834120c8 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 12 Nov 2020 16:33:12 +0000 Subject: [PATCH 02/22] Add .nvmrc with latest supported Node.JS across all platforms. --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index 260a0e20..ea711f11 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -12.19.0 +10.23.0 From bcf9a0927672d2324de7565a50614691a5371246 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 12 Nov 2020 18:06:39 +0000 Subject: [PATCH 03/22] Get unit tests running without needing globally installed dependencies. --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index f7ba900f..19ba623c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7632,7 +7632,7 @@ "requires": { "underscore": "1.9.1", "web3-core-helpers": "1.2.1", - "websocket": "github:web3-js/WebSocket-Node#ef5ea2f41daf4a2113b80c9223df884b4d56c400" + "websocket": "github:web3-js/WebSocket-Node#polyfill/globalThis" }, "dependencies": { "websocket": { From d98ebab86ee0f42182f7f2c391987cfab74c9122 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Tue, 19 Jan 2021 19:53:22 +0000 Subject: [PATCH 04/22] Update README.md with getting started information. Format to 80 docs to characters. --- README.md | 65 +++++++++++++++++++++++++++++++++++++----------- doc_contracts.md | 50 ++++++++++++++++++++++++++----------- 2 files changed, 85 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index c94cd427..c4a89835 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,76 @@ # Core prototype -Code repository for Boson Protocol smart contracts. The description of the contracts and process can be found in [doc_contracts.md](doc_contracts.md). -## Install -Install dependencies from project root folder: -``` - $ npm install @openzeppelin/contracts truffle-assertions ethers -``` +Code repository for Boson Protocol smart contracts. The description of the +contracts and process can be found in [doc_contracts.md](doc_contracts.md). -Migrations are using HDWalletProvider, install it if you need it: -``` - $ npm install @truffle/hdwallet-provider +## Getting started + +Note: all commands below are run from the project root. + +To install dependencies: + +```shell script +npm install +```` + +To compile all contracts: + +```shell script +npm run compile ``` -## Contracts initialization -[Migrations script](./migrations/2_deploy_contracts.js) for Truffle also does this initialization: +To run the unit tests: + +1. Ensure Ethereum is running locally on port 8545. This can be achieved using + Ganache, `ganache-cli` or `etherlime ganache`. +1. Copy your 12 word mnemonic to `.secret`. Create the file if it doesn't + already exist. +1. Execute the unit tests: + +```shell script +npm run test:unit +``` + +Note: currently, the unit test suite will fail the second time it is run against +the same Ethereum instance. As a reuls, you'll need to reset between test runs. + +To run the integration tests, follow the instructions in +[`testUserInteractions/README.md](testUserInteractions/README.md). + +## Contracts initialization + +[Migrations script](./migrations/2_deploy_contracts.js) for Truffle also does +this initialization: + - ERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true') - ERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address) - VoucherKernel.setCashierAddress(contractCashier.address) ## Deployed contracts -Contract are deployed on Kovan testnet at addresses: + +Contracts are deployed on Kovan testnet at addresses: + ERC1155ERC721: 0xF3aA8eB3812303F6c86c136557bC23E48d634B58 VoucherKernel: 0x1806312211bd1521430C953683038d6263580feE Cashier: 0xaaf749c8e6e37b51410F1810ADcAEED18d0C166F + The frontend is currently pointing to Kovan deployment. -Contract are also deployed on Ropsten testnet at addresses: +Contract are also deployed on Ropsten testnet at addresses: + ERC1155ERC721: 0xe7028d66222aD1AfEB0098956347A6284443bd16 VoucherKernel: 0xa93f95bf0039CE30957b77A6638e2e273598D576 Cashier: 0x014b8baF57bA77FaE23075aa93c2B768eeb440bD ## Progress -See the project board at [https://github.com/bosonprotocol/bsn-core-prototype/projects/2](https://github.com/bosonprotocol/bsn-core-prototype/projects/2). +See the +[project board](https://github.com/bosonprotocol/bsn-core-prototype/projects/2). ## Coverage + Test coverage is executed by running the following command: ``` -npm run coverage \ No newline at end of file +npm run coverage +``` diff --git a/doc_contracts.md b/doc_contracts.md index ac2b2c7f..b9a6a61a 100644 --- a/doc_contracts.md +++ b/doc_contracts.md @@ -1,5 +1,9 @@ # Smart contracts description -This is a brief description of the smart contracts used in Boson Protocol. They are based on two NFT standards, [ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) and [ERC-721](https://eips.ethereum.org/EIPS/eip-721). + +This is a brief description of the smart contracts used in Boson Protocol. They +are based on two NFT standards, +[ERC-1155](https://eips.ethereum.org/EIPS/eip-1155) and +[ERC-721](https://eips.ethereum.org/EIPS/eip-721). Main contracts: * BosonToken: ERC-20 contract for the native Boson Protocol token @@ -8,33 +12,49 @@ Main contracts: * VoucherKernel: main business logic * usingHelpers: common utils as structures -Supported currencies are currently ETH and BSN tokens therefore functions dealing with funds have appendices such as ETH_ETH or ETH_TKN to denote the currencies used in that particular function (e.g. `function requestCreateOrder_ETH_ETH(uint256[] calldata metadata)`). - +Supported currencies are currently ETH and BSN tokens therefore functions +dealing with funds have appendices such as ETH_ETH or ETH_TKN to denote the +currencies used in that particular function (e.g. +`function requestCreateOrder_ETH_ETH(uint256[] calldata metadata)`). ## Transactions flow -The journey through the NFT lifecycle is presented on a simplified diagram below. + +The journey through the NFT lifecycle is presented on a simplified diagram +below. ![Simplified exchange mechanism](assets/boson_exchange_diagram_simplified.png) +Voucher's status is defined in 7 bits that are set depending on the path in its +lifecycle (defined in +[usingHelpers.sol](https://github.com/bosonprotocol/bsn-core-prototype/blob/master/contracts/usingHelpers.sol#L29)): -Voucher's status is defined in 7 bits that are set depending on the path in its lifecycle (defined in [usingHelpers.sol](https://github.com/bosonprotocol/bsn-core-prototype/blob/master/contracts/usingHelpers.sol#L29)): 7:COMMITTED -6:REDEEMED
 +6:REDEEMED 5:REFUNDED -4:EXPIRED 
 -3:COMPLAINED
 -2:CANCELORFAULT
 +4:EXPIRED +3:COMPLAINED +2:CANCELORFAULT 1:FINAL - ### Happy path -The process starts with Seller making an offer - minting a VoucherSet, which is represented as ERC-1155 token: `Cashier.requestCreateOrder()`. The Seller sets the expiration period of the whole VoucherSet. -Then the Buyer purchases the Voucher, i.e. is committing to redeem it at some point later - this means an ERC-721 token is extracted from a VoucherSet: `Cashier.requestVoucher()`. +The process starts with Seller making an offer - minting a VoucherSet, which is +represented as ERC-1155 token: `Cashier.requestCreateOrder()`. The Seller sets +the expiration period of the whole VoucherSet. -The Buyer redeems the voucher, thus releasing the payment amount to the Seller: `VoucherKernel.redeem()`. +Then the Buyer purchases the Voucher, i.e. is committing to redeem it at some +point later - this means an ERC-721 token is extracted from a VoucherSet: +`Cashier.requestVoucher()`. -After the two wait periods pass (the period within which Buyer can complain and the period within which Seller can admit cancel/fault), the Seller's deposit can be returned to the Seller and Buyer's deposit can be returned to the Buyer. +The Buyer redeems the voucher, thus releasing the payment amount to the Seller: +`VoucherKernel.redeem()`. -A scheduled process is running in the backend that flags the vouchers when redemption was made and when wait periods expire. Anybody could be executing these functions, marked as external, the backend is currently running them for convenience: `VoucherKernel.triggerExpiration()`, `VoucherKernel.triggerFinalizeVoucher()`, `Cashier.withdraw()`. +After the two wait periods pass (the period within which Buyer can complain and +the period within which Seller can admit cancel/fault), the Seller's deposit +can be returned to the Seller and Buyer's deposit can be returned to the Buyer. +A scheduled process is running in the backend that flags the vouchers when +redemption was made and when wait periods expire. Anybody could be executing +these functions, marked as external, the backend is currently running them for +convenience: `VoucherKernel.triggerExpiration()`, +`VoucherKernel.triggerFinalizeVoucher()`, `Cashier.withdraw()`. From 4f51b6886e2a7ff5b2be1828facd37dcb80f62e3 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Tue, 19 Jan 2021 19:53:48 +0000 Subject: [PATCH 05/22] Add missing test dependencies. --- package-lock.json | 1414 ++++++++++++++++++++++++++++++++++++--------- package.json | 11 +- 2 files changed, 1159 insertions(+), 266 deletions(-) diff --git a/package-lock.json b/package-lock.json index 19ba623c..d4bfa9bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", "integrity": "sha512-SR713Ogqg6++uexFRORf/+nPXMmWIn80TALu0uaFb+iQIUoR7bOC7zBWyzBs5b3tBBJXuyD0cRu1F15GyzjOWA==", - "dev": true, "requires": { "@babel/types": "^7.12.5" } @@ -16,20 +15,17 @@ "@babel/helper-plugin-utils": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==", - "dev": true + "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" }, "@babel/helper-validator-identifier": { "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", - "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==", - "dev": true + "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" }, "@babel/plugin-transform-runtime": { "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz", "integrity": "sha512-xOrUfzPxw7+WDm9igMgQCbO3cJKymX7dFdsgRr1eu9n3KjjyU4pptIXbXPseQDquw+W+RuJEJMHKHNsPNNm3CA==", - "dev": true, "requires": { "@babel/helper-module-imports": "^7.12.5", "@babel/helper-plugin-utils": "^7.10.4", @@ -39,8 +35,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -48,7 +43,6 @@ "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.12.5.tgz", "integrity": "sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg==", - "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } @@ -57,7 +51,6 @@ "version": "7.12.11", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.12.11.tgz", "integrity": "sha512-ukA9SQtKThINm++CX1CwmliMrE54J6nIYB5XTwL5f/CLFW9owfls+YSU8tVW15RQ2w+a3fSbPjC6HdQNtWZkiA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.12.11", "lodash": "^4.17.19", @@ -466,11 +459,295 @@ "fastq": "^1.6.0" } }, + "@opencensus/core": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz", + "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==", + "requires": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "@opencensus/propagation-b3": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz", + "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==", + "requires": { + "@opencensus/core": "^0.0.8", + "uuid": "^3.2.1" + }, + "dependencies": { + "@opencensus/core": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz", + "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==", + "requires": { + "continuation-local-storage": "^3.2.1", + "log-driver": "^1.2.7", + "semver": "^5.5.0", + "shimmer": "^1.2.0", + "uuid": "^3.2.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "@openzeppelin/contracts": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.3.0.tgz", "integrity": "sha512-AemZEsQYtUp1WRkcmZm1div5ORfTpLquLaziCIrSagjxyKdmObxuaY1yjQ5SHFMctR8rLwp706NXTbiIRJg7pw==" }, + "@pm2/agent": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-1.0.4.tgz", + "integrity": "sha512-cZLwaoLa45FRuetKCcoI3kHnnQ7VMLpZnmVom04MoK0cpY/RxcSarkCHSCu9V+pdARwxx96QrWdrtAJdw97dng==", + "requires": { + "async": "~3.2.0", + "chalk": "~3.0.0", + "dayjs": "~1.8.24", + "debug": "~4.1.1", + "eventemitter2": "~5.0.1", + "fclone": "~1.0.11", + "nssocket": "0.6.0", + "pm2-axon": "^3.2.0", + "pm2-axon-rpc": "^0.5.0", + "proxy-agent": "~3.1.1", + "semver": "~7.2.0", + "ws": "~7.2.0" + }, + "dependencies": { + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "pm2-axon": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-3.3.0.tgz", + "integrity": "sha512-dAFlFYRuFbFjX7oAk41zT+dx86EuaFX/TgOp5QpUKRKwxb946IM6ydnoH5sSTkdI2pHSVZ+3Am8n/l0ocr7jdQ==", + "requires": { + "amp": "~0.3.1", + "amp-message": "~0.1.1", + "debug": "^3.0", + "escape-regexp": "0.0.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "pm2-axon-rpc": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.5.2.tgz", + "integrity": "sha512-o4u1jO1EYBgBUVlraE1aeGWB5DvClJFB2+v7ytqLypNfgYeT6eJ/B+WMh5NcvRnexAYL5kblcRgNgSbgGEobvA==", + "requires": { + "debug": "^3.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "semver": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz", + "integrity": "sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig==" + } + } + }, + "@pm2/agent-node": { + "version": "1.1.10", + "resolved": "https://registry.npmjs.org/@pm2/agent-node/-/agent-node-1.1.10.tgz", + "integrity": "sha512-xRcrk7OEwhS3d/227/kKGvxgmbIi6Yyp27FzGlFNermEKhgddmFaRnmd7GRLIsBM/KB28NrwflBZulzk/mma6g==", + "requires": { + "debug": "^3.1.0", + "eventemitter2": "^5.0.1", + "proxy-agent": "^3.0.3", + "ws": "^6.0.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "@pm2/io": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/@pm2/io/-/io-4.3.5.tgz", + "integrity": "sha512-CY/a6Nw72vrlp/FPx38l4jfEHp4gNEbo8i+WlSJ2cnWO6VE6CKmnC1zb4yQLvdP8f3EuzzoOBZVq6aGN20M82Q==", + "requires": { + "@opencensus/core": "0.0.9", + "@opencensus/propagation-b3": "0.0.8", + "@pm2/agent-node": "^1.1.10", + "async": "~2.6.1", + "debug": "4.1.1", + "eventemitter2": "^6.3.1", + "require-in-the-middle": "^5.0.0", + "semver": "6.3.0", + "shimmer": "^1.2.0", + "signal-exit": "^3.0.3", + "tslib": "1.9.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "requires": { + "ms": "^2.1.1" + } + }, + "eventemitter2": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.3.tgz", + "integrity": "sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==" + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" + } + } + }, + "@pm2/js-api": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz", + "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==", + "requires": { + "async": "^2.6.3", + "axios": "^0.21.0", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "ws": "^7.0.0" + }, + "dependencies": { + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "eventemitter2": { + "version": "6.4.3", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.3.tgz", + "integrity": "sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==" + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "@pm2/pm2-version-check": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.3.tgz", + "integrity": "sha512-SBuYsh+o35knItbRW97vl5/5nEc5c5DYP7PxjyPLOfmm9bMaDsVeATXjXMBy6+KLlyrYWHZxGbfXe003NnHClg==", + "requires": { + "debug": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -500,7 +777,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/@truffle/hdwallet-provider/-/hdwallet-provider-1.2.0.tgz", "integrity": "sha512-EPatDbyRuGbB/MLt9ZBokmtjyLjaNpuHfUIWuv4mQMrH1Nu82H5AAZYLh4Z1BZliDZpqB03a0yUMmK/4R0BN9g==", - "dev": true, "requires": { "@trufflesuite/web3-provider-engine": "15.0.13-1", "@types/web3": "^1.0.20", @@ -518,7 +794,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -1537,7 +1812,6 @@ "version": "4.1.2-1", "resolved": "https://registry.npmjs.org/@trufflesuite/eth-json-rpc-filters/-/eth-json-rpc-filters-4.1.2-1.tgz", "integrity": "sha512-/MChvC5dw2ck9NU1cZmdovCz2VKbOeIyR4tcxDvA5sT+NaL0rA2/R5U0yI7zsbo1zD+pgqav77rQHTzpUdDNJQ==", - "dev": true, "requires": { "@trufflesuite/eth-json-rpc-middleware": "^4.4.2-0", "await-semaphore": "^0.1.3", @@ -1551,7 +1825,6 @@ "version": "4.0.3-0", "resolved": "https://registry.npmjs.org/@trufflesuite/eth-json-rpc-infura/-/eth-json-rpc-infura-4.0.3-0.tgz", "integrity": "sha512-xaUanOmo0YLqRsL0SfXpFienhdw5bpQ1WEXxMTRi57az4lwpZBv4tFUDvcerdwJrxX9wQqNmgUgd1BrR01dumw==", - "dev": true, "requires": { "@trufflesuite/eth-json-rpc-middleware": "^4.4.2-1", "cross-fetch": "^2.1.1", @@ -1563,7 +1836,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/eth-json-rpc-errors/-/eth-json-rpc-errors-1.1.1.tgz", "integrity": "sha512-WT5shJ5KfNqHi9jOZD+ID8I1kuYWNrigtZat7GOQkvwo99f8SzAVaEcWhJUv656WiZOAg3P1RiJQANtUmDmbIg==", - "dev": true, "requires": { "fast-safe-stringify": "^2.0.6" } @@ -1574,7 +1846,6 @@ "version": "4.4.2-1", "resolved": "https://registry.npmjs.org/@trufflesuite/eth-json-rpc-middleware/-/eth-json-rpc-middleware-4.4.2-1.tgz", "integrity": "sha512-iEy9H8ja7/8aYES5HfrepGBKU9n/Y4OabBJEklVd/zIBlhCCBAWBqkIZgXt11nBXO/rYAeKwYuE3puH3ByYnLA==", - "dev": true, "requires": { "@trufflesuite/eth-sig-util": "^1.4.2", "btoa": "^1.2.1", @@ -1596,7 +1867,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/eth-json-rpc-errors/-/eth-json-rpc-errors-1.1.1.tgz", "integrity": "sha512-WT5shJ5KfNqHi9jOZD+ID8I1kuYWNrigtZat7GOQkvwo99f8SzAVaEcWhJUv656WiZOAg3P1RiJQANtUmDmbIg==", - "dev": true, "requires": { "fast-safe-stringify": "^2.0.6" } @@ -1605,7 +1875,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -1619,8 +1888,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" } } }, @@ -1628,7 +1896,6 @@ "version": "1.4.2", "resolved": "https://registry.npmjs.org/@trufflesuite/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha512-+GyfN6b0LNW77hbQlH3ufZ/1eCON7mMrGym6tdYf7xiNw9Vv3jBO72bmmos1EId2NgBvPMhmYYm6DSLQFTmzrA==", - "dev": true, "requires": { "ethereumjs-abi": "^0.6.8", "ethereumjs-util": "^5.1.1" @@ -1638,7 +1905,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -1655,7 +1921,6 @@ "version": "15.0.13-1", "resolved": "https://registry.npmjs.org/@trufflesuite/web3-provider-engine/-/web3-provider-engine-15.0.13-1.tgz", "integrity": "sha512-6u3x/iIN5fyj8pib5QTUDmIOUiwAGhaqdSTXdqCu6v9zo2BEwdCqgEJd1uXDh3DBmPRDfiZ/ge8oUPy7LerpHg==", - "dev": true, "requires": { "@trufflesuite/eth-json-rpc-filters": "^4.1.2-1", "@trufflesuite/eth-json-rpc-infura": "^4.0.3-0", @@ -1685,7 +1950,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -1700,7 +1964,6 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", - "dev": true, "requires": { "async-limiter": "~1.0.0" } @@ -1711,7 +1974,6 @@ "version": "4.11.6", "resolved": "https://registry.npmjs.org/@types/bn.js/-/bn.js-4.11.6.tgz", "integrity": "sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==", - "dev": true, "requires": { "@types/node": "*" } @@ -1741,7 +2003,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/@types/pbkdf2/-/pbkdf2-3.1.0.tgz", "integrity": "sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ==", - "dev": true, "requires": { "@types/node": "*" } @@ -1750,7 +2011,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/secp256k1/-/secp256k1-4.0.1.tgz", "integrity": "sha512-+ZjSA8ELlOp8SlKi0YLB2tz9d5iPNEmOBd+8Rz21wTMdaXQIa9b6TEnD6l5qKOCypE7FSyPyck12qZJxSDNoog==", - "dev": true, "requires": { "@types/node": "*" } @@ -1759,7 +2019,6 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/web3/-/web3-1.2.2.tgz", "integrity": "sha512-eFiYJKggNrOl0nsD+9cMh2MLk4zVBfXfGnVeRFbpiZzBE20eet4KLA3fXcjSuHaBn0RnQzwLAGdgzgzdet4C0A==", - "dev": true, "requires": { "web3": "*" } @@ -1780,7 +2039,6 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz", "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==", - "dev": true, "requires": { "xtend": "~4.0.0" } @@ -1805,6 +2063,14 @@ "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" }, + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1820,14 +2086,25 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, "optional": true }, + "amp": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", + "integrity": "sha1-at+NWKdPNh6CwfqNOJwHnhOfxH0=" + }, + "amp-message": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", + "integrity": "sha1-p48cmJlQh602GSpBKY5NtJ49/EU=", + "requires": { + "amp": "0.3.1" + } + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" }, "ansi-regex": { "version": "3.0.0", @@ -1839,7 +2116,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "requires": { "color-convert": "^2.0.1" } @@ -1853,7 +2129,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", - "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1869,7 +2144,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -1914,11 +2188,18 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" }, + "ast-types": { + "version": "0.14.2", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", + "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", + "requires": { + "tslib": "^2.0.1" + } + }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, "requires": { "lodash": "^4.17.14" } @@ -1927,7 +2208,6 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dev": true, "requires": { "async": "^2.4.0" } @@ -1937,6 +2217,22 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, + "async-listener": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", + "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "requires": { + "semver": "^5.3.0", + "shimmer": "^1.1.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -1945,8 +2241,7 @@ "await-semaphore": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/await-semaphore/-/await-semaphore-0.1.3.tgz", - "integrity": "sha512-d1W2aNSYcz/sxYO4pMGX9vq65qOTu0P800epMud+6cYYX0QcT7zyqcxec3VWzpgvdXo57UWmVbZpLMjX2m1I7Q==", - "dev": true + "integrity": "sha512-d1W2aNSYcz/sxYO4pMGX9vq65qOTu0P800epMud+6cYYX0QcT7zyqcxec3VWzpgvdXo57UWmVbZpLMjX2m1I7Q==" }, "aws-sign2": { "version": "0.7.0", @@ -1959,19 +2254,17 @@ "integrity": "sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==" }, "axios": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", - "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "dev": true, + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.20.0.tgz", + "integrity": "sha512-ANA4rr2BDcmmAQLOKft2fufrtuvlqR+cXNNinUmvfeSNCOF98PZL+7M/v1zIdGo7OLjEA9J2gXJL+j4zGsl0bA==", "requires": { - "follow-redirects": "1.5.10" + "follow-redirects": "^1.10.0" } }, "backoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/backoff/-/backoff-2.5.0.tgz", "integrity": "sha1-9hbtqdPktmuMp/ynn2lXIsX44m8=", - "dev": true, "requires": { "precond": "0.2" } @@ -1979,14 +2272,12 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base-x": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.8.tgz", "integrity": "sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -2018,8 +2309,7 @@ "binary-extensions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", - "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", - "dev": true + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==" }, "bindings": { "version": "1.5.0", @@ -2041,8 +2331,12 @@ "blakejs": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", - "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=", - "dev": true + "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" + }, + "blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha1-+WLWh+wsNpVwrnGvhDJW5tDKESk=" }, "bluebird": { "version": "3.7.2", @@ -2075,7 +2369,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -2085,7 +2378,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "requires": { "fill-range": "^7.0.1" } @@ -2188,7 +2480,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", - "dev": true, "requires": { "base-x": "^3.0.2" } @@ -2197,7 +2488,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", - "dev": true, "requires": { "bs58": "^4.0.0", "create-hash": "^1.1.0", @@ -2207,8 +2497,7 @@ "btoa": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz", - "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==", - "dev": true + "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" }, "buffer": { "version": "5.7.1", @@ -2246,8 +2535,7 @@ "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-to-arraybuffer": { "version": "0.0.5", @@ -2336,6 +2624,11 @@ "supports-color": "^7.1.0" } }, + "charm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", + "integrity": "sha1-BsIe7RobBq62dVPNxT4jJ0usIpY=" + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -2346,7 +2639,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/checkpoint-store/-/checkpoint-store-1.1.0.tgz", "integrity": "sha1-BOTLUWuRQziTWB5tRgGnjpVS6gY=", - "dev": true, "requires": { "functional-red-black-tree": "^1.0.1" } @@ -2355,7 +2647,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", - "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", @@ -2434,6 +2725,25 @@ "integrity": "sha1-a82TsJ+y7RAl0woRVdWZeVSlNRI=", "dev": true }, + "cli-tableau": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", + "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", + "requires": { + "chalk": "3.0.0" + }, + "dependencies": { + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + } + } + }, "cli-util": { "version": "1.1.27", "resolved": "https://registry.npmjs.org/cli-util/-/cli-util-1.1.27.tgz", @@ -2485,8 +2795,7 @@ "clone": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=" }, "clone-response": { "version": "1.0.2", @@ -2496,11 +2805,15 @@ "mimic-response": "^1.0.0" } }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -2508,8 +2821,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "combined-stream": { "version": "1.0.8", @@ -2527,8 +2839,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "content-disposition": { "version": "0.5.3", @@ -2561,6 +2872,15 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "continuation-local-storage": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", + "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "requires": { + "async-listener": "^0.6.0", + "emitter-listener": "^1.1.1" + } + }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -2624,11 +2944,18 @@ "sha.js": "^2.4.8" } }, + "cron": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", + "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", + "requires": { + "moment-timezone": "^0.5.x" + } + }, "cross-fetch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==", - "dev": true, "requires": { "node-fetch": "2.1.2", "whatwg-fetch": "2.0.4" @@ -2637,8 +2964,7 @@ "node-fetch": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", - "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", - "dev": true + "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=" } } }, @@ -2677,6 +3003,16 @@ "assert-plus": "^1.0.0" } }, + "data-uri-to-buffer": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", + "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" + }, + "dayjs": { + "version": "1.8.36", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", + "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" + }, "death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", @@ -2803,8 +3139,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "defer-to-connect": { "version": "1.1.3", @@ -2815,11 +3150,27 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz", "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==", - "dev": true, "requires": { "abstract-leveldown": "~2.6.0" } }, + "degenerator": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", + "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", + "requires": { + "ast-types": "0.x.x", + "escodegen": "1.x.x", + "esprima": "3.x.x" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + } + } + }, "delay": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz", @@ -2929,6 +3280,14 @@ "minimalistic-crypto-utils": "^1.0.0" } }, + "emitter-listener": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", + "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "requires": { + "shimmer": "^1.2.0" + } + }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -2944,7 +3303,6 @@ "version": "0.1.13", "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, "requires": { "iconv-lite": "^0.6.2" }, @@ -2953,7 +3311,6 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.2.tgz", "integrity": "sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3.0.0" } @@ -2968,11 +3325,18 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + } + }, "errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", - "dev": true, "requires": { "prr": "~1.0.1" } @@ -2997,6 +3361,19 @@ "es6-symbol": "^3.1.1" } }, + "es6-promise": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", + "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, "es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", @@ -3011,17 +3388,20 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, + "escape-regexp": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/escape-regexp/-/escape-regexp-0.0.1.tgz", + "integrity": "sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ=" + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" }, "escodegen": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, "requires": { "esprima": "^2.7.1", "estraverse": "^1.9.1", @@ -3033,14 +3413,12 @@ "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" }, "source-map": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, "optional": true, "requires": { "amdefine": ">=0.0.4" @@ -3057,14 +3435,12 @@ "estraverse": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=" }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "etag": { "version": "1.8.1", @@ -3075,7 +3451,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-4.4.3.tgz", "integrity": "sha512-A8tG4Z4iNg4mw5tP1Vung9N9IjgMNqpiMoJ/FouSFwNCGHv2X0mmOYwtQOJzki6XN7r7Tyo01S29p7b224I4jw==", - "dev": true, "requires": { "@babel/plugin-transform-runtime": "^7.5.5", "@babel/runtime": "^7.5.5", @@ -3088,8 +3463,7 @@ "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=" } } }, @@ -3106,7 +3480,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/eth-json-rpc-errors/-/eth-json-rpc-errors-2.0.2.tgz", "integrity": "sha512-uBCRM2w2ewusRHGxN8JhcuOb2RN3ueAOYH/0BhqdFmQkZx5lj5+fLKTz0mIVOzd4FG5/kUksCzCD7eTEim6gaA==", - "dev": true, "requires": { "fast-safe-stringify": "^2.0.6" } @@ -3145,7 +3518,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/eth-query/-/eth-query-2.1.2.tgz", "integrity": "sha1-1nQdkAAQa1FRDHLbktY2VFam2l4=", - "dev": true, "requires": { "json-rpc-random-id": "^1.0.0", "xtend": "^4.0.1" @@ -3155,7 +3527,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/eth-rpc-errors/-/eth-rpc-errors-3.0.0.tgz", "integrity": "sha512-iPPNHPrLwUlR9xCSYm7HHQjWBasor3+KZfRvwEWxMz3ca0yqnlBeJrnyphkGIXZ4J7AMAaOLmwy4AWhnxOiLxg==", - "dev": true, "requires": { "fast-safe-stringify": "^2.0.6" } @@ -3180,14 +3551,12 @@ "ethereum-common": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.2.0.tgz", - "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", - "dev": true + "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==" }, "ethereum-cryptography": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz", "integrity": "sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==", - "dev": true, "requires": { "@types/pbkdf2": "^3.0.0", "@types/secp256k1": "^4.0.1", @@ -3209,14 +3578,12 @@ "ethereum-protocol": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ethereum-protocol/-/ethereum-protocol-1.0.1.tgz", - "integrity": "sha512-3KLX1mHuEsBW0dKG+c6EOJS1NBNqdCICvZW9sInmZTt5aY0oxmHVggYRE0lJu1tcnMD1K+AKHdLi6U43Awm1Vg==", - "dev": true + "integrity": "sha512-3KLX1mHuEsBW0dKG+c6EOJS1NBNqdCICvZW9sInmZTt5aY0oxmHVggYRE0lJu1tcnMD1K+AKHdLi6U43Awm1Vg==" }, "ethereumjs-abi": { "version": "0.6.8", "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz", "integrity": "sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA==", - "dev": true, "requires": { "bn.js": "^4.11.8", "ethereumjs-util": "^6.0.0" @@ -3226,7 +3593,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -3243,7 +3609,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/ethereumjs-account/-/ethereumjs-account-2.0.5.tgz", "integrity": "sha512-bgDojnXGjhMwo6eXQC0bY6UK2liSFUSMwwylOmQvZbSl/D7NXQ3+vrGO46ZeOgjGfxXmgIeVNDIiHw7fNZM4VA==", - "dev": true, "requires": { "ethereumjs-util": "^5.0.0", "rlp": "^2.0.0", @@ -3254,7 +3619,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -3271,7 +3635,6 @@ "version": "1.7.1", "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", - "dev": true, "requires": { "async": "^2.0.1", "ethereum-common": "0.2.0", @@ -3284,7 +3647,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -3300,14 +3662,12 @@ "ethereumjs-common": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz", - "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==", - "dev": true + "integrity": "sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA==" }, "ethereumjs-tx": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", - "dev": true, "requires": { "ethereum-common": "^0.0.18", "ethereumjs-util": "^5.0.0" @@ -3316,14 +3676,12 @@ "ethereum-common": { "version": "0.0.18", "resolved": "https://registry.npmjs.org/ethereum-common/-/ethereum-common-0.0.18.tgz", - "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=", - "dev": true + "integrity": "sha1-L9w1dvIykDNYl26znaeDIT/5Uj8=" }, "ethereumjs-util": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -3362,7 +3720,6 @@ "version": "2.6.0", "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.6.0.tgz", "integrity": "sha512-r/XIUik/ynGbxS3y+mvGnbOKnuLo40V5Mj1J25+HEO63aWYREIqvWeRO/hnROlMBE5WoniQmPmhiaN0ctiHaXw==", - "dev": true, "requires": { "async": "^2.1.2", "async-eventemitter": "^0.2.2", @@ -3381,7 +3738,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-2.2.2.tgz", "integrity": "sha512-2p49ifhek3h2zeg/+da6XpdFR3GlqY3BIEiqxGF8j9aSRIgkb7M1Ky+yULBKJOu8PAZxfhsYA+HxUk2aCQp3vg==", - "dev": true, "requires": { "async": "^2.0.1", "ethereumjs-common": "^1.5.0", @@ -3394,7 +3750,6 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -3411,7 +3766,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", - "dev": true, "requires": { "ethereumjs-common": "^1.5.0", "ethereumjs-util": "^6.0.0" @@ -3421,7 +3775,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -3438,7 +3791,6 @@ "version": "0.6.5", "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.5.tgz", "integrity": "sha512-MDwjwB9VQVnpp/Dc1XzA6J1a3wgHQ4hSvA1uWNatdpOrtCbPVuQSKSyRnjLvS0a+KKMw2pvQ9Ybqpb3+eW8oNA==", - "dev": true, "requires": { "aes-js": "^3.1.1", "bs58check": "^2.1.2", @@ -3454,14 +3806,12 @@ "aes-js": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", - "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", - "dev": true + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==" }, "ethereumjs-util": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -3476,7 +3826,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", - "dev": true, "requires": { "pbkdf2": "^3.0.3" } @@ -3539,12 +3888,16 @@ "version": "0.1.6", "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", - "dev": true, "requires": { "is-hex-prefixed": "1.0.0", "strip-hex-prefix": "1.0.0" } }, + "eventemitter2": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", + "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=" + }, "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", @@ -3553,8 +3906,7 @@ "events": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", - "dev": true + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==" }, "evp_bytestokey": { "version": "1.0.3", @@ -3638,7 +3990,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/fake-merkle-patricia-tree/-/fake-merkle-patricia-tree-1.0.1.tgz", "integrity": "sha1-S4w6z7Ugr635hgsfFM2M40As3dM=", - "dev": true, "requires": { "checkpoint-store": "^1.1.0" } @@ -3670,14 +4021,12 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fast-safe-stringify": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz", - "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==", - "dev": true + "integrity": "sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==" }, "fastq": { "version": "1.9.0", @@ -3688,6 +4037,11 @@ "reusify": "^1.0.4" } }, + "fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=" + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -3700,7 +4054,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/fetch-ponyfill/-/fetch-ponyfill-4.1.0.tgz", "integrity": "sha1-rjzl9zLGReq4fkroeTQUcJsjmJM=", - "dev": true, "requires": { "node-fetch": "~1.7.1" } @@ -3719,7 +4072,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -3755,24 +4107,9 @@ "dev": true }, "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, - "requires": { - "debug": "=3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" }, "forever-agent": { "version": "0.6.1", @@ -3825,21 +4162,55 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", - "dev": true, "optional": true }, + "ftp": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", + "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "requires": { + "readable-stream": "1.1.x", + "xregexp": "2.0.0" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "ganache-cli": { "version": "6.12.1", @@ -4636,6 +5007,19 @@ "pump": "^3.0.0" } }, + "get-uri": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.4.tgz", + "integrity": "sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==", + "requires": { + "data-uri-to-buffer": "1", + "debug": "2", + "extend": "~3.0.2", + "file-uri-to-path": "1", + "ftp": "~0.3.10", + "readable-stream": "2" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -4716,7 +5100,6 @@ "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4730,7 +5113,6 @@ "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -4847,11 +5229,18 @@ "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "requires": { + "function-bind": "^1.1.1" + } + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-symbol-support-x": { "version": "1.4.2", @@ -4942,6 +5331,25 @@ "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" }, + "http-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "requires": { + "agent-base": "4", + "debug": "3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + } + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -4952,6 +5360,30 @@ "sshpk": "^1.7.0" } }, + "https-proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", + "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -4989,14 +5421,12 @@ "immediate": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "dev": true + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -5019,6 +5449,11 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -5028,22 +5463,27 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, "requires": { "binary-extensions": "^2.0.0" } }, + "is-core-module": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", + "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", + "requires": { + "has": "^1.0.3" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-fn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fn/-/is-fn-1.0.0.tgz", - "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=", - "dev": true + "integrity": "sha1-lUPV3nvPWwiiLsiiC65uKG1RDYw=" }, "is-fullwidth-code-point": { "version": "2.0.0", @@ -5060,7 +5500,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -5078,8 +5517,7 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, "is-object": { "version": "1.0.2", @@ -5160,7 +5598,6 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-5.4.0.tgz", "integrity": "sha512-rAffKbPoNDjuRnXkecTjnsE3xLLrb00rEkdgalINhaYVYIxDwWtvYBr9UFbhTvPB1B2qUOLoFd/cV6f4Q7mh7g==", - "dev": true, "requires": { "eth-rpc-errors": "^3.0.0", "safe-event-emitter": "^1.0.1" @@ -5169,8 +5606,7 @@ "json-rpc-random-id": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-rpc-random-id/-/json-rpc-random-id-1.0.1.tgz", - "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=", - "dev": true + "integrity": "sha1-uknZat7RRE27jaPSA3SKy7zeyMg=" }, "json-schema": { "version": "0.2.3", @@ -5186,7 +5622,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, "requires": { "jsonify": "~0.0.0" } @@ -5207,8 +5642,7 @@ "jsonify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" }, "jsonschema": { "version": "1.4.0", @@ -5231,7 +5665,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/keccak/-/keccak-3.0.1.tgz", "integrity": "sha512-epq90L9jlFWCW7+pQa6JOnKn2Xgl2mtI664seYR6MHskvI9agt7AnDqmAlp9TqU4/caMYbA08Hi5DMZAl5zdkA==", - "dev": true, "requires": { "node-addon-api": "^2.0.0", "node-gyp-build": "^4.2.0" @@ -5251,17 +5684,20 @@ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, + "lazy": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", + "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=" + }, "level-codec": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", - "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", - "dev": true + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==" }, "level-errors": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", - "dev": true, "requires": { "errno": "~0.1.1" } @@ -5270,7 +5706,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", - "dev": true, "requires": { "inherits": "^2.0.1", "level-errors": "^1.0.3", @@ -5281,14 +5716,12 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -5299,8 +5732,7 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" } } }, @@ -5308,7 +5740,6 @@ "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", - "dev": true, "requires": { "readable-stream": "~1.0.15", "xtend": "~2.1.1" @@ -5317,14 +5748,12 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -5335,14 +5764,12 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "xtend": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, "requires": { "object-keys": "~0.4.0" } @@ -5353,7 +5780,6 @@ "version": "1.3.9", "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", - "dev": true, "requires": { "deferred-leveldown": "~1.2.1", "level-codec": "~7.0.0", @@ -5367,8 +5793,7 @@ "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" } } }, @@ -5376,7 +5801,6 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -5394,14 +5818,12 @@ "lodash": { "version": "4.17.20", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", - "dev": true + "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" }, "lodash.flatmap": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.flatmap/-/lodash.flatmap-4.5.0.tgz", - "integrity": "sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=", - "dev": true + "integrity": "sha1-74y/QI9uSCaGYzRTBcaswLd4cC4=" }, "lodash.isequal": { "version": "4.5.0", @@ -5414,6 +5836,11 @@ "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", "dev": true }, + "log-driver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", + "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + }, "log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", @@ -5432,7 +5859,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "requires": { "yallist": "^4.0.0" }, @@ -5440,16 +5866,14 @@ "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } }, "ltgt": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", - "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=", - "dev": true + "integrity": "sha1-81ypHEk/e3PaDgdJUwTxezH4fuU=" }, "make-dir": { "version": "1.3.0", @@ -5485,7 +5909,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/memdown/-/memdown-1.4.1.tgz", "integrity": "sha1-tOThkhdGZP+65BNhqlAPMRnv4hU=", - "dev": true, "requires": { "abstract-leveldown": "~2.7.1", "functional-red-black-tree": "^1.0.1", @@ -5499,7 +5922,6 @@ "version": "2.7.2", "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.7.2.tgz", "integrity": "sha512-+OVvxH2rHVEhWLdbudP6p0+dNMXu8JA1CbhP19T8paTYAcX7oJ4OVjT+ZUVpv7mITxXHqDMej+GdqXBmXkw09w==", - "dev": true, "requires": { "xtend": "~4.0.0" } @@ -5507,8 +5929,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" } } }, @@ -5527,7 +5948,6 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.2.tgz", "integrity": "sha512-81PW5m8oz/pz3GvsAwbauj7Y00rqm81Tzad77tHBwU7pIAtN+TJnMSOJhxBKflSVYhptMMb9RskhqHqrSm1V+g==", - "dev": true, "requires": { "async": "^1.4.2", "ethereumjs-util": "^5.0.0", @@ -5542,14 +5962,12 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, "ethereumjs-util": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.1.tgz", "integrity": "sha512-v3kT+7zdyCm1HIqWlLNrHGqHGLpGYIhjeHxQjnDXjLT2FyGJDsd3LWMYUo7pAFRrk86CR3nUJfhC81CCoJNNGQ==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -5631,7 +6049,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -5726,6 +6143,24 @@ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz", "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==" }, + "module-details-from-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", + "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" + }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, + "moment-timezone": { + "version": "0.5.32", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.32.tgz", + "integrity": "sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==", + "requires": { + "moment": ">= 2.9.0" + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -5773,6 +6208,11 @@ } } }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" + }, "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", @@ -5789,6 +6229,31 @@ "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", "dev": true }, + "needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -5800,6 +6265,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "netmask": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", + "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=" + }, "next-tick": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", @@ -5808,8 +6278,7 @@ "node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==", - "dev": true + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" }, "node-emoji": { "version": "1.10.0", @@ -5824,7 +6293,6 @@ "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "dev": true, "requires": { "encoding": "^0.1.11", "is-stream": "^1.0.1" @@ -5847,14 +6315,29 @@ "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==" }, "normalize-url": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" }, + "nssocket": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", + "integrity": "sha1-Wflvb/MhVm8zxw99vu7N/cBxVPo=", + "requires": { + "eventemitter2": "~0.4.14", + "lazy": "~1.0.11" + }, + "dependencies": { + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=" + } + } + }, "number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", @@ -5884,8 +6367,7 @@ "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" }, "oboe": { "version": "2.1.4", @@ -5915,7 +6397,6 @@ "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", @@ -5973,6 +6454,48 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "pac-proxy-agent": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz", + "integrity": "sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ==", + "requires": { + "agent-base": "^4.2.0", + "debug": "^4.1.1", + "get-uri": "^2.0.0", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^3.0.0", + "pac-resolver": "^3.0.0", + "raw-body": "^2.2.0", + "socks-proxy-agent": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "pac-resolver": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", + "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", + "requires": { + "co": "^4.6.0", + "degenerator": "^1.0.4", + "ip": "^1.1.5", + "netmask": "^1.0.6", + "thunkify": "^2.1.2" + } + }, "parse-asn1": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", @@ -6004,8 +6527,12 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-to-regexp": { "version": "0.1.7", @@ -6049,8 +6576,15 @@ "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", - "dev": true + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" + }, + "pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "requires": { + "safe-buffer": "^5.2.1" + } }, "pify": { "version": "2.3.0", @@ -6070,17 +6604,166 @@ "pinkie": "^2.0.0" } }, + "pm2": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-4.5.1.tgz", + "integrity": "sha512-gEOYugy4vEGazszDtjbZcWnZhHpBLKl0JiYhEnIJqmMj576a0D5LNCmd9grJswB1ziZim+9YInqFrG3FQTxvEg==", + "requires": { + "@pm2/agent": "~1.0.2", + "@pm2/io": "~4.3.5", + "@pm2/js-api": "~0.6.0", + "@pm2/pm2-version-check": "^1.0.3", + "async": "~3.2.0", + "blessed": "0.1.81", + "chalk": "3.0.0", + "chokidar": "^3.3.0", + "cli-tableau": "^2.0.0", + "commander": "2.15.1", + "cron": "1.8.2", + "dayjs": "~1.8.25", + "debug": "^4.3.0", + "enquirer": "2.3.6", + "eventemitter2": "5.0.1", + "fclone": "1.0.11", + "mkdirp": "1.0.4", + "needle": "2.4.0", + "pidusage": "2.0.21", + "pm2-axon": "4.0.0", + "pm2-axon-rpc": "0.6.0", + "pm2-deploy": "~1.0.2", + "pm2-multimeter": "^0.1.2", + "promptly": "^2", + "ps-list": "6.3.0", + "semver": "^7.2", + "source-map-support": "0.5.19", + "sprintf-js": "1.1.2", + "systeminformation": "^4.32", + "vizion": "0.2.13", + "yamljs": "0.3.0" + }, + "dependencies": { + "async": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", + "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" + } + } + }, + "pm2-axon": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.0.tgz", + "integrity": "sha512-A8dy0C57cRIm+kX58HrMcnvUdg8EdwCuCmavDdmFE4eoUE+5zfwGbDfZKCBVLNpDwjXPuXQQYZi3wQt/5xC8DQ==", + "requires": { + "amp": "~0.3.1", + "amp-message": "~0.1.1", + "debug": "^4.2", + "escape-string-regexp": "^4.0.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "pm2-axon-rpc": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.6.0.tgz", + "integrity": "sha512-xjYR0y1HpOopJ09VL2Qd5H1LajVN+QLPVZ1G+GesbORJDAZiStMhwECtOzm/Gx5ANQxL0usW8WZsElMfQq2hbw==", + "requires": { + "debug": "^3.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + } + } + }, + "pm2-deploy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", + "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==", + "requires": { + "run-series": "^1.1.8", + "tv4": "^1.3.0" + } + }, + "pm2-multimeter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", + "integrity": "sha1-Gh5VFT1BoFU0zqI8/oYKuqDrSs4=", + "requires": { + "charm": "~0.1.1" + } + }, "precond": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", - "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=", - "dev": true + "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=" }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" }, "prepend-http": { "version": "2.0.0", @@ -6101,12 +6784,19 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", "integrity": "sha1-XSp0kBC/tn2WNZj805YHRqaP7vc=", - "dev": true, "requires": { "is-fn": "^1.0.0", "set-immediate-shim": "^1.0.1" } }, + "promptly": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", + "integrity": "sha1-KhP6BjaIoqWYOxYf/wEIoH0m/HQ=", + "requires": { + "read": "^1.0.4" + } + }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -6116,11 +6806,58 @@ "ipaddr.js": "1.9.1" } }, + "proxy-agent": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.1.1.tgz", + "integrity": "sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw==", + "requires": { + "agent-base": "^4.2.0", + "debug": "4", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^3.0.0", + "lru-cache": "^5.1.1", + "pac-proxy-agent": "^3.0.1", + "proxy-from-env": "^1.0.0", + "socks-proxy-agent": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "requires": { + "yallist": "^3.0.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" + }, + "ps-list": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/ps-list/-/ps-list-6.3.0.tgz", + "integrity": "sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA==" }, "psl": { "version": "1.8.0", @@ -6213,6 +6950,14 @@ "unpipe": "1.0.0" } }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "requires": { + "mute-stream": "~0.0.4" + } + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -6238,7 +6983,6 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", - "dev": true, "requires": { "picomatch": "^2.2.1" } @@ -6264,8 +7008,7 @@ "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, "request": { "version": "2.88.2", @@ -6307,6 +7050,40 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-in-the-middle": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", + "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", + "requires": { + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "requires": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + } + } + } + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -6346,7 +7123,6 @@ "version": "2.2.6", "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz", "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==", - "dev": true, "requires": { "bn.js": "^4.11.1" } @@ -6357,11 +7133,15 @@ "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", "dev": true }, + "run-series": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==" + }, "rustbn.js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", - "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", - "dev": true + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==" }, "safe-buffer": { "version": "5.2.1", @@ -6372,7 +7152,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz", "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==", - "dev": true, "requires": { "events": "^3.0.0" } @@ -6382,6 +7161,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "sc-istanbul": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.5.tgz", @@ -6478,7 +7262,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-4.0.2.tgz", "integrity": "sha512-UDar4sKvWAksIlfX3xIaQReADn+WFnHvbVujpcbr+9Sf/69odMwy2MUsz5CKLQgX9nsIyrjuxL2imVyoNHa3fg==", - "dev": true, "requires": { "elliptic": "^6.5.2", "node-addon-api": "^2.0.0", @@ -6496,8 +7279,7 @@ "semaphore": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/semaphore/-/semaphore-1.1.0.tgz", - "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==", - "dev": true + "integrity": "sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==" }, "semver": { "version": "6.2.0", @@ -6572,8 +7354,7 @@ "set-immediate-shim": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=" }, "setimmediate": { "version": "1.0.5", @@ -6605,6 +7386,16 @@ "rechoir": "^0.6.2" } }, + "shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, "simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -6626,6 +7417,39 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, + "smart-buffer": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", + "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==" + }, + "socks": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", + "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", + "requires": { + "ip": "1.1.5", + "smart-buffer": "^4.1.0" + } + }, + "socks-proxy-agent": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", + "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", + "requires": { + "agent-base": "~4.2.1", + "socks": "~2.3.2" + }, + "dependencies": { + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "requires": { + "es6-promisify": "^5.0.0" + } + } + } + }, "solidity-coverage": { "version": "0.7.13", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.13.tgz", @@ -6767,14 +7591,12 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" }, "source-map-support": { "version": "0.5.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -6783,8 +7605,7 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" }, "sshpk": { "version": "1.16.1", @@ -6872,7 +7693,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -6942,6 +7762,12 @@ } } }, + "systeminformation": { + "version": "4.34.7", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-4.34.7.tgz", + "integrity": "sha512-cS3FiSZasFgVNjO9CP3aZmTO2VHwXKG+JN6Z85nWRyOzxRMNbZe7Xzwrewp42hj+OPMC3hk7MrAFyu/qLM65Mw==", + "optional": true + }, "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", @@ -6985,6 +7811,11 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, + "thunkify": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", + "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=" + }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -6998,8 +7829,7 @@ "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "dev": true + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" }, "to-readable-stream": { "version": "1.0.0", @@ -7010,7 +7840,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "requires": { "is-number": "^7.0.0" } @@ -7168,8 +7997,42 @@ "cli-logger": "0.5.40", "delay": "4.3.0", "querystring": "0.2.0" + }, + "dependencies": { + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "dev": true, + "requires": { + "follow-redirects": "1.5.10" + } + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + } + } } }, + "tslib": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", + "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -7178,6 +8041,11 @@ "safe-buffer": "^5.0.1" } }, + "tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha1-0CDIRvrdUMhVq7JeuuzGj8EPeWM=" + }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -7192,7 +8060,6 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, "requires": { "prelude-ls": "~1.1.2" } @@ -7331,6 +8198,21 @@ "extsprintf": "^1.2.0" } }, + "vizion": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/vizion/-/vizion-0.2.13.tgz", + "integrity": "sha1-ExTN7is0EW+fWxJIU2+V2/zW718=", + "requires": { + "async": "1.5" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" + } + } + }, "web3": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.1.tgz", @@ -7706,8 +8588,7 @@ "whatwg-fetch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", - "dev": true + "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" }, "which": { "version": "2.0.2", @@ -7736,8 +8617,7 @@ "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, "wordwrap": { "version": "1.0.0", @@ -7870,6 +8750,11 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" }, + "xregexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", + "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" + }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -7891,6 +8776,15 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, + "yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "requires": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + } + }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", diff --git a/package.json b/package.json index f528b04c..eef90f60 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "test": "test" }, "scripts": { - "test": "truffle test", + "compile": "truffle compile", + "test:unit": "truffle test", "coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage", "migrate-dev": "truffle migrate --network=rinkeby", "verify-dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby" @@ -24,18 +25,16 @@ "homepage": "https://github.com/bosonprotocol/bsn-core-prototype#readme", "dependencies": { "@openzeppelin/contracts": "^3.2.0", - "ethers": "5.0.4", - "truffle-assertions": "^0.9.2", - "truffle-hdwallet-provider": "^1.0.17" - }, - "devDependencies": { "@truffle/hdwallet-provider": "^1.2.0", + "axios": "^0.20.0", "chai": "^4.2.0", "dotenv": "^8.2.0", "ethereumjs-util": "^7.0.7", + "ethers": "5.0.4", "mocha": "^8.2.1", "solidity-coverage": "^0.7.12", "truffle": "5.1.10", + "truffle-assertions": "^0.9.2", "truffle-plugin-verify": "^0.5.2" } } From 524f2af459d1a37d65cd6145526f6635102f800d Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Tue, 19 Jan 2021 20:22:00 +0000 Subject: [PATCH 06/22] Clean up comments in truffle-config.js. Only load .secret when needed. --- package-lock.json | 1737 ++++----------------------------------------- truffle-config.js | 249 ++++--- 2 files changed, 278 insertions(+), 1708 deletions(-) diff --git a/package-lock.json b/package-lock.json index d4bfa9bf..345f8853 100644 --- a/package-lock.json +++ b/package-lock.json @@ -437,7 +437,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", - "dev": true, "requires": { "@nodelib/fs.stat": "2.0.3", "run-parallel": "^1.1.9" @@ -446,308 +445,22 @@ "@nodelib/fs.stat": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", - "dev": true + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==" }, "@nodelib/fs.walk": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", - "dev": true, "requires": { "@nodelib/fs.scandir": "2.1.3", "fastq": "^1.6.0" } }, - "@opencensus/core": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.9.tgz", - "integrity": "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q==", - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^5.5.0", - "shimmer": "^1.2.0", - "uuid": "^3.2.1" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, - "@opencensus/propagation-b3": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@opencensus/propagation-b3/-/propagation-b3-0.0.8.tgz", - "integrity": "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A==", - "requires": { - "@opencensus/core": "^0.0.8", - "uuid": "^3.2.1" - }, - "dependencies": { - "@opencensus/core": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.8.tgz", - "integrity": "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ==", - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^5.5.0", - "shimmer": "^1.2.0", - "uuid": "^3.2.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, "@openzeppelin/contracts": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/@openzeppelin/contracts/-/contracts-3.3.0.tgz", "integrity": "sha512-AemZEsQYtUp1WRkcmZm1div5ORfTpLquLaziCIrSagjxyKdmObxuaY1yjQ5SHFMctR8rLwp706NXTbiIRJg7pw==" }, - "@pm2/agent": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-1.0.4.tgz", - "integrity": "sha512-cZLwaoLa45FRuetKCcoI3kHnnQ7VMLpZnmVom04MoK0cpY/RxcSarkCHSCu9V+pdARwxx96QrWdrtAJdw97dng==", - "requires": { - "async": "~3.2.0", - "chalk": "~3.0.0", - "dayjs": "~1.8.24", - "debug": "~4.1.1", - "eventemitter2": "~5.0.1", - "fclone": "~1.0.11", - "nssocket": "0.6.0", - "pm2-axon": "^3.2.0", - "pm2-axon-rpc": "^0.5.0", - "proxy-agent": "~3.1.1", - "semver": "~7.2.0", - "ws": "~7.2.0" - }, - "dependencies": { - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "pm2-axon": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-3.3.0.tgz", - "integrity": "sha512-dAFlFYRuFbFjX7oAk41zT+dx86EuaFX/TgOp5QpUKRKwxb946IM6ydnoH5sSTkdI2pHSVZ+3Am8n/l0ocr7jdQ==", - "requires": { - "amp": "~0.3.1", - "amp-message": "~0.1.1", - "debug": "^3.0", - "escape-regexp": "0.0.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "pm2-axon-rpc": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.5.2.tgz", - "integrity": "sha512-o4u1jO1EYBgBUVlraE1aeGWB5DvClJFB2+v7ytqLypNfgYeT6eJ/B+WMh5NcvRnexAYL5kblcRgNgSbgGEobvA==", - "requires": { - "debug": "^3.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "semver": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.2.3.tgz", - "integrity": "sha512-utbW9Z7ZxVvwiIWkdOMLOR9G/NFXh2aRucghkVrEMJWuC++r3lCkBC3LwqBinyHzGMAJxY5tn6VakZGHObq5ig==" - } - } - }, - "@pm2/agent-node": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@pm2/agent-node/-/agent-node-1.1.10.tgz", - "integrity": "sha512-xRcrk7OEwhS3d/227/kKGvxgmbIi6Yyp27FzGlFNermEKhgddmFaRnmd7GRLIsBM/KB28NrwflBZulzk/mma6g==", - "requires": { - "debug": "^3.1.0", - "eventemitter2": "^5.0.1", - "proxy-agent": "^3.0.3", - "ws": "^6.0.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", - "requires": { - "async-limiter": "~1.0.0" - } - } - } - }, - "@pm2/io": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/@pm2/io/-/io-4.3.5.tgz", - "integrity": "sha512-CY/a6Nw72vrlp/FPx38l4jfEHp4gNEbo8i+WlSJ2cnWO6VE6CKmnC1zb4yQLvdP8f3EuzzoOBZVq6aGN20M82Q==", - "requires": { - "@opencensus/core": "0.0.9", - "@opencensus/propagation-b3": "0.0.8", - "@pm2/agent-node": "^1.1.10", - "async": "~2.6.1", - "debug": "4.1.1", - "eventemitter2": "^6.3.1", - "require-in-the-middle": "^5.0.0", - "semver": "6.3.0", - "shimmer": "^1.2.0", - "signal-exit": "^3.0.3", - "tslib": "1.9.3" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "requires": { - "ms": "^2.1.1" - } - }, - "eventemitter2": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.3.tgz", - "integrity": "sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==" - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - }, - "tslib": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", - "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==" - } - } - }, - "@pm2/js-api": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.6.7.tgz", - "integrity": "sha512-jiJUhbdsK+5C4zhPZNnyA3wRI01dEc6a2GhcQ9qI38DyIk+S+C8iC3fGjcjUbt/viLYKPjlAaE+hcT2/JMQPXw==", - "requires": { - "async": "^2.6.3", - "axios": "^0.21.0", - "debug": "~4.3.1", - "eventemitter2": "^6.3.1", - "ws": "^7.0.0" - }, - "dependencies": { - "axios": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", - "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", - "requires": { - "follow-redirects": "^1.10.0" - } - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "eventemitter2": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.3.tgz", - "integrity": "sha512-t0A2msp6BzOf+QAcI6z9XMktLj52OjGQg+8SJH6v5+3uxNpWYRR3wQmfA+6xtMU9kOC59qk9licus5dYcrYkMQ==" - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "@pm2/pm2-version-check": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.3.tgz", - "integrity": "sha512-SBuYsh+o35knItbRW97vl5/5nEc5c5DYP7PxjyPLOfmm9bMaDsVeATXjXMBy6+KLlyrYWHZxGbfXe003NnHClg==", - "requires": { - "debug": "^4.1.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, "@sindresorhus/is": { "version": "0.14.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", @@ -756,8 +469,7 @@ "@solidity-parser/parser": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.8.2.tgz", - "integrity": "sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ==", - "dev": true + "integrity": "sha512-8LySx3qrNXPgB5JiULfG10O3V7QTxI/TLzSw5hFQhXWSkVxZBAv4rZQ0sYgLEbc8g3L2lmnujj1hKul38Eu5NQ==" }, "@szmarczak/http-timer": { "version": "1.1.2", @@ -770,8 +482,7 @@ "@truffle/error": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/@truffle/error/-/error-0.0.11.tgz", - "integrity": "sha512-ju6TucjlJkfYMmdraYY/IBJaFb+Sa+huhYtOoyOJ+G29KcgytUVnDzKGwC7Kgk6IsxQMm62Mc1E0GZzFbGGipw==", - "dev": true + "integrity": "sha512-ju6TucjlJkfYMmdraYY/IBJaFb+Sa+huhYtOoyOJ+G29KcgytUVnDzKGwC7Kgk6IsxQMm62Mc1E0GZzFbGGipw==" }, "@truffle/hdwallet-provider": { "version": "1.2.0", @@ -810,7 +521,6 @@ "version": "0.4.18", "resolved": "https://registry.npmjs.org/@truffle/interface-adapter/-/interface-adapter-0.4.18.tgz", "integrity": "sha512-P9JVSYD/CX3V+NgTWu+Bf71sLh8pMwrCpbiYRB93pRw/1H3ZTvt5iDC2MVvVxCs8FkSiy4OZzQK/DJ8+hXAmYw==", - "dev": true, "requires": { "bn.js": "^4.11.8", "ethers": "^4.0.32", @@ -822,7 +532,6 @@ "version": "5.0.0-beta.153", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz", "integrity": "sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==", - "dev": true, "requires": { "@ethersproject/address": ">=5.0.0-beta.128", "@ethersproject/bignumber": ">=5.0.0-beta.130", @@ -839,7 +548,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", - "dev": true, "requires": { "ethereumjs-common": "^1.5.0", "ethereumjs-util": "^6.0.0" @@ -849,7 +557,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -864,7 +571,6 @@ "version": "4.0.48", "resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.48.tgz", "integrity": "sha512-sZD5K8H28dOrcidzx9f8KYh8083n5BexIO3+SbE4jK83L85FxtpXZBCQdXb8gkg+7sBqomcLhhkU7UHL+F7I2g==", - "dev": true, "requires": { "aes-js": "3.0.0", "bn.js": "^4.4.0", @@ -880,14 +586,12 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, "hash.js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.0" @@ -896,32 +600,27 @@ "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "scrypt-js": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", - "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==", - "dev": true + "integrity": "sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==" }, "setimmediate": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.4.tgz", - "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=", - "dev": true + "integrity": "sha1-IOgd5iLUoCWIzgyNqJc8vPHTE48=" }, "swarm-js": { "version": "0.1.40", "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, "requires": { "bluebird": "^3.5.0", "buffer": "^5.0.5", @@ -940,7 +639,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, "requires": { "decompress-response": "^3.2.0", "duplexer3": "^0.1.4", @@ -961,8 +659,7 @@ "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=" } } }, @@ -970,7 +667,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, "requires": { "prepend-http": "^1.0.1" } @@ -978,14 +674,12 @@ "uuid": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", - "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "dev": true + "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=" }, "web3": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.9.tgz", "integrity": "sha512-Mo5aBRm0JrcNpN/g4VOrDzudymfOnHRC3s2VarhYxRA8aWgF5rnhQ0ziySaugpic1gksbXPe105pUWyRqw8HUA==", - "dev": true, "requires": { "web3-bzz": "1.2.9", "web3-core": "1.2.9", @@ -1000,7 +694,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.9.tgz", "integrity": "sha512-ogVQr9jHodu9HobARtvUSmWG22cv2EUQzlPeejGWZ7j5h20HX40EDuWyomGY5VclIj5DdLY76Tmq88RTf/6nxA==", - "dev": true, "requires": { "@types/node": "^10.12.18", "got": "9.6.0", @@ -1012,7 +705,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.9.tgz", "integrity": "sha512-fSYv21IP658Ty2wAuU9iqmW7V+75DOYMVZsDH/c14jcF/1VXnedOcxzxSj3vArsCvXZNe6XC5/wAuGZyQwR9RA==", - "dev": true, "requires": { "@types/bn.js": "^4.11.4", "@types/node": "^12.6.1", @@ -1026,8 +718,7 @@ "@types/node": { "version": "12.19.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.9.tgz", - "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==", - "dev": true + "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==" } } }, @@ -1035,7 +726,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.9.tgz", "integrity": "sha512-t0WAG3orLCE3lqi77ZoSRNFok3VQWZXTniZigDQjyOJYMAX7BU3F3js8HKbjVnAxlX3tiKoDxI0KBk9F3AxYuw==", - "dev": true, "requires": { "underscore": "1.9.1", "web3-eth-iban": "1.2.9", @@ -1046,7 +736,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.9.tgz", "integrity": "sha512-bjsIoqP3gs7A/gP8+QeLUCyOKJ8bopteCSNbCX36Pxk6TYfYWNuC6hP+2GzUuqdP3xaZNe+XEElQFUNpR3oyAg==", - "dev": true, "requires": { "@ethersproject/transactions": "^5.0.0-beta.135", "underscore": "1.9.1", @@ -1060,7 +749,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.9.tgz", "integrity": "sha512-0eAUA2zjgXTleSrnc1wdoKQPPIHU6KHf4fAscu4W9kKrR+mqP1KsjYrxY9wUyjNnXxfQ+5M29ipvbiaK8OqdOw==", - "dev": true, "requires": { "eventemitter3": "3.1.2" } @@ -1069,7 +757,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.9.tgz", "integrity": "sha512-1PwKV2m46ALUnIN5VPPgjOj8yMLJhhqZYvYJE34hTN5SErOkwhzx5zScvo5MN7v7KyQGFnpVCZKKGCiEnDmtFA==", - "dev": true, "requires": { "underscore": "1.9.1", "web3-core-helpers": "1.2.9", @@ -1082,7 +769,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.9.tgz", "integrity": "sha512-Y48TvXPSPxEM33OmXjGVDMzTd0j8X0t2+sDw66haeBS8eYnrEzasWuBZZXDq0zNUsqyxItgBGDn+cszkgEnFqg==", - "dev": true, "requires": { "eventemitter3": "3.1.2", "underscore": "1.9.1", @@ -1093,7 +779,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.9.tgz", "integrity": "sha512-sIKO4iE9FEBa/CYUd6GdPd7GXt/wISqxUd8PlIld6+hvMJj02lgO7Z7p5T9mZIJcIZJGvZX81ogx8oJ9yif+Ag==", - "dev": true, "requires": { "underscore": "1.9.1", "web3-core": "1.2.9", @@ -1114,7 +799,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.9.tgz", "integrity": "sha512-3YwUYbh/DMfDbhMWEebAdjSd5bj3ZQieOjLzWFHU23CaLEqT34sUix1lba+hgUH/EN6A7bKAuKOhR3p0OvTn7Q==", - "dev": true, "requires": { "@ethersproject/abi": "5.0.0-beta.153", "underscore": "1.9.1", @@ -1125,7 +809,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.9.tgz", "integrity": "sha512-jkbDCZoA1qv53mFcRHCinoCsgg8WH+M0YUO1awxmqWXRmCRws1wW0TsuSQ14UThih5Dxolgl+e+aGWxG58LMwg==", - "dev": true, "requires": { "crypto-browserify": "3.12.0", "eth-lib": "^0.2.8", @@ -1144,7 +827,6 @@ "version": "0.2.8", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -1154,14 +836,12 @@ "scrypt-js": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz", - "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==", - "dev": true + "integrity": "sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==" }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" } } }, @@ -1169,7 +849,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.9.tgz", "integrity": "sha512-PYMvJf7EG/HyssUZa+pXrc8IB06K/YFfWYyW4R7ed3sab+9wWUys1TlWxBCBuiBXOokSAyM6H6P6/cKEx8FT8Q==", - "dev": true, "requires": { "@types/bn.js": "^4.11.4", "underscore": "1.9.1", @@ -1186,7 +865,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.9.tgz", "integrity": "sha512-kG4+ZRgZ8I1WYyOBGI8QVRHfUSbbJjvJAGA1AF/NOW7JXQ+x7gBGeJw6taDWJhSshMoEKWcsgvsiuoG4870YxQ==", - "dev": true, "requires": { "content-hash": "^2.5.2", "eth-ens-namehash": "2.0.8", @@ -1203,7 +881,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.9.tgz", "integrity": "sha512-RtdVvJE0pyg9dHLy0GzDiqgnLnssSzfz/JYguhC1wsj9+Gnq1M6Diy3NixACWUAp6ty/zafyOaZnNQ+JuH9TjQ==", - "dev": true, "requires": { "bn.js": "4.11.8", "web3-utils": "1.2.9" @@ -1212,8 +889,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" } } }, @@ -1221,7 +897,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.9.tgz", "integrity": "sha512-cFiNrktxZ1C/rIdJFzQTvFn3/0zcsR3a+Jf8Y3KxeQDHszQtosjLWptP7bsUmDwEh4hzh0Cy3KpOxlYBWB8bJQ==", - "dev": true, "requires": { "@types/node": "^12.6.1", "web3-core": "1.2.9", @@ -1234,8 +909,7 @@ "@types/node": { "version": "12.19.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.9.tgz", - "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==", - "dev": true + "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==" } } }, @@ -1243,7 +917,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.9.tgz", "integrity": "sha512-d2mTn8jPlg+SI2hTj2b32Qan6DmtU9ap/IUlJTeQbZQSkTLf0u9suW8Vjwyr4poJYXTurdSshE7OZsPNn30/ZA==", - "dev": true, "requires": { "web3-core": "1.2.9", "web3-core-method": "1.2.9", @@ -1254,7 +927,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.9.tgz", "integrity": "sha512-F956tCIj60Ttr0UvEHWFIhx+be3He8msoPzyA44/kfzzYoMAsCFRn5cf0zQG6al0znE75g6HlWVSN6s3yAh51A==", - "dev": true, "requires": { "web3-core-helpers": "1.2.9", "xhr2-cookies": "1.1.0" @@ -1264,7 +936,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.9.tgz", "integrity": "sha512-NQ8QnBleoHA2qTJlqoWu7EJAD/FR5uimf7Ielzk4Z2z+m+6UAuJdJMSuQNj+Umhz9L/Ys6vpS1vHx9NizFl+aQ==", - "dev": true, "requires": { "oboe": "2.1.4", "underscore": "1.9.1", @@ -1275,7 +946,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.9.tgz", "integrity": "sha512-6+UpvINeI//dglZoAKStUXqxDOXJy6Iitv2z3dbgInG4zb8tkYl/VBDL80UjUg3ZvzWG0g7EKY2nRPEpON2TFA==", - "dev": true, "requires": { "eventemitter3": "^4.0.0", "underscore": "1.9.1", @@ -1286,8 +956,7 @@ "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" } } }, @@ -1295,7 +964,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.9.tgz", "integrity": "sha512-PWa8b/EaxaMinFaxy6cV0i0EOi2M7a/ST+9k9nhyhCjVa2vzXuNoBNo2IUOmeZ0WP2UQB8ByJ2+p4htlJaDOjA==", - "dev": true, "requires": { "web3-core": "1.2.9", "web3-core-method": "1.2.9", @@ -1307,7 +975,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.9.tgz", "integrity": "sha512-9hcpuis3n/LxFzEVjwnVgvJzTirS2S9/MiNAa7l4WOEoywY+BSNwnRX4MuHnjkh9NY25B6QOjuNG6FNnSjTw1w==", - "dev": true, "requires": { "bn.js": "4.11.8", "eth-lib": "0.2.7", @@ -1322,14 +989,12 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "eth-lib": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", - "dev": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -1344,7 +1009,6 @@ "version": "0.2.25", "resolved": "https://registry.npmjs.org/@truffle/provider/-/provider-0.2.25.tgz", "integrity": "sha512-BohKgT2357c2dYCH2IQwldQ4EJkfsWUClpb3j+kR8ng02vbsyAPe0HMH463I+h+tiDKvL757dBltXpe0DBJusg==", - "dev": true, "requires": { "@truffle/error": "^0.0.11", "@truffle/interface-adapter": "^0.4.18", @@ -1355,7 +1019,6 @@ "version": "5.0.0-beta.153", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.0-beta.153.tgz", "integrity": "sha512-aXweZ1Z7vMNzJdLpR1CZUAIgnwjrZeUSvN9syCwlBaEBUFJmFY+HHnfuTI5vIhVs/mRkfJVrbEyl51JZQqyjAg==", - "dev": true, "requires": { "@ethersproject/address": ">=5.0.0-beta.128", "@ethersproject/bignumber": ">=5.0.0-beta.130", @@ -1371,14 +1034,12 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "ethereumjs-tx": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz", "integrity": "sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw==", - "dev": true, "requires": { "ethereumjs-common": "^1.5.0", "ethereumjs-util": "^6.0.0" @@ -1388,7 +1049,6 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz", "integrity": "sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==", - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -1402,26 +1062,22 @@ "get-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, "p-cancelable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true + "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==" }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" }, "swarm-js": { "version": "0.1.40", "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.40.tgz", "integrity": "sha512-yqiOCEoA4/IShXkY3WKwP5PvZhmoOOD8clsKA7EEcRILMkTEYHCQ21HDCAcVpmIxZq4LyZvWeRJ6quIyHk1caA==", - "dev": true, "requires": { "bluebird": "^3.5.0", "buffer": "^5.0.5", @@ -1440,7 +1096,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, "requires": { "decompress-response": "^3.2.0", "duplexer3": "^0.1.4", @@ -1464,7 +1119,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, "requires": { "prepend-http": "^1.0.1" } @@ -1472,14 +1126,12 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" }, "web3": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.9.tgz", "integrity": "sha512-Mo5aBRm0JrcNpN/g4VOrDzudymfOnHRC3s2VarhYxRA8aWgF5rnhQ0ziySaugpic1gksbXPe105pUWyRqw8HUA==", - "dev": true, "requires": { "web3-bzz": "1.2.9", "web3-core": "1.2.9", @@ -1494,7 +1146,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.2.9.tgz", "integrity": "sha512-ogVQr9jHodu9HobARtvUSmWG22cv2EUQzlPeejGWZ7j5h20HX40EDuWyomGY5VclIj5DdLY76Tmq88RTf/6nxA==", - "dev": true, "requires": { "@types/node": "^10.12.18", "got": "9.6.0", @@ -1506,7 +1157,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.2.9.tgz", "integrity": "sha512-fSYv21IP658Ty2wAuU9iqmW7V+75DOYMVZsDH/c14jcF/1VXnedOcxzxSj3vArsCvXZNe6XC5/wAuGZyQwR9RA==", - "dev": true, "requires": { "@types/bn.js": "^4.11.4", "@types/node": "^12.6.1", @@ -1520,8 +1170,7 @@ "@types/node": { "version": "12.19.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.9.tgz", - "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==", - "dev": true + "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==" } } }, @@ -1529,7 +1178,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.2.9.tgz", "integrity": "sha512-t0WAG3orLCE3lqi77ZoSRNFok3VQWZXTniZigDQjyOJYMAX7BU3F3js8HKbjVnAxlX3tiKoDxI0KBk9F3AxYuw==", - "dev": true, "requires": { "underscore": "1.9.1", "web3-eth-iban": "1.2.9", @@ -1540,7 +1188,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.2.9.tgz", "integrity": "sha512-bjsIoqP3gs7A/gP8+QeLUCyOKJ8bopteCSNbCX36Pxk6TYfYWNuC6hP+2GzUuqdP3xaZNe+XEElQFUNpR3oyAg==", - "dev": true, "requires": { "@ethersproject/transactions": "^5.0.0-beta.135", "underscore": "1.9.1", @@ -1554,7 +1201,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.2.9.tgz", "integrity": "sha512-0eAUA2zjgXTleSrnc1wdoKQPPIHU6KHf4fAscu4W9kKrR+mqP1KsjYrxY9wUyjNnXxfQ+5M29ipvbiaK8OqdOw==", - "dev": true, "requires": { "eventemitter3": "3.1.2" } @@ -1563,7 +1209,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.2.9.tgz", "integrity": "sha512-1PwKV2m46ALUnIN5VPPgjOj8yMLJhhqZYvYJE34hTN5SErOkwhzx5zScvo5MN7v7KyQGFnpVCZKKGCiEnDmtFA==", - "dev": true, "requires": { "underscore": "1.9.1", "web3-core-helpers": "1.2.9", @@ -1576,7 +1221,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.2.9.tgz", "integrity": "sha512-Y48TvXPSPxEM33OmXjGVDMzTd0j8X0t2+sDw66haeBS8eYnrEzasWuBZZXDq0zNUsqyxItgBGDn+cszkgEnFqg==", - "dev": true, "requires": { "eventemitter3": "3.1.2", "underscore": "1.9.1", @@ -1587,7 +1231,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.2.9.tgz", "integrity": "sha512-sIKO4iE9FEBa/CYUd6GdPd7GXt/wISqxUd8PlIld6+hvMJj02lgO7Z7p5T9mZIJcIZJGvZX81ogx8oJ9yif+Ag==", - "dev": true, "requires": { "underscore": "1.9.1", "web3-core": "1.2.9", @@ -1608,7 +1251,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.2.9.tgz", "integrity": "sha512-3YwUYbh/DMfDbhMWEebAdjSd5bj3ZQieOjLzWFHU23CaLEqT34sUix1lba+hgUH/EN6A7bKAuKOhR3p0OvTn7Q==", - "dev": true, "requires": { "@ethersproject/abi": "5.0.0-beta.153", "underscore": "1.9.1", @@ -1619,7 +1261,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.2.9.tgz", "integrity": "sha512-jkbDCZoA1qv53mFcRHCinoCsgg8WH+M0YUO1awxmqWXRmCRws1wW0TsuSQ14UThih5Dxolgl+e+aGWxG58LMwg==", - "dev": true, "requires": { "crypto-browserify": "3.12.0", "eth-lib": "^0.2.8", @@ -1638,7 +1279,6 @@ "version": "0.2.8", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -1651,7 +1291,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.2.9.tgz", "integrity": "sha512-PYMvJf7EG/HyssUZa+pXrc8IB06K/YFfWYyW4R7ed3sab+9wWUys1TlWxBCBuiBXOokSAyM6H6P6/cKEx8FT8Q==", - "dev": true, "requires": { "@types/bn.js": "^4.11.4", "underscore": "1.9.1", @@ -1668,7 +1307,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-ens/-/web3-eth-ens-1.2.9.tgz", "integrity": "sha512-kG4+ZRgZ8I1WYyOBGI8QVRHfUSbbJjvJAGA1AF/NOW7JXQ+x7gBGeJw6taDWJhSshMoEKWcsgvsiuoG4870YxQ==", - "dev": true, "requires": { "content-hash": "^2.5.2", "eth-ens-namehash": "2.0.8", @@ -1685,7 +1323,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.2.9.tgz", "integrity": "sha512-RtdVvJE0pyg9dHLy0GzDiqgnLnssSzfz/JYguhC1wsj9+Gnq1M6Diy3NixACWUAp6ty/zafyOaZnNQ+JuH9TjQ==", - "dev": true, "requires": { "bn.js": "4.11.8", "web3-utils": "1.2.9" @@ -1695,7 +1332,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.2.9.tgz", "integrity": "sha512-cFiNrktxZ1C/rIdJFzQTvFn3/0zcsR3a+Jf8Y3KxeQDHszQtosjLWptP7bsUmDwEh4hzh0Cy3KpOxlYBWB8bJQ==", - "dev": true, "requires": { "@types/node": "^12.6.1", "web3-core": "1.2.9", @@ -1708,8 +1344,7 @@ "@types/node": { "version": "12.19.9", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.9.tgz", - "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==", - "dev": true + "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==" } } }, @@ -1717,7 +1352,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.2.9.tgz", "integrity": "sha512-d2mTn8jPlg+SI2hTj2b32Qan6DmtU9ap/IUlJTeQbZQSkTLf0u9suW8Vjwyr4poJYXTurdSshE7OZsPNn30/ZA==", - "dev": true, "requires": { "web3-core": "1.2.9", "web3-core-method": "1.2.9", @@ -1728,7 +1362,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.2.9.tgz", "integrity": "sha512-F956tCIj60Ttr0UvEHWFIhx+be3He8msoPzyA44/kfzzYoMAsCFRn5cf0zQG6al0znE75g6HlWVSN6s3yAh51A==", - "dev": true, "requires": { "web3-core-helpers": "1.2.9", "xhr2-cookies": "1.1.0" @@ -1738,7 +1371,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.2.9.tgz", "integrity": "sha512-NQ8QnBleoHA2qTJlqoWu7EJAD/FR5uimf7Ielzk4Z2z+m+6UAuJdJMSuQNj+Umhz9L/Ys6vpS1vHx9NizFl+aQ==", - "dev": true, "requires": { "oboe": "2.1.4", "underscore": "1.9.1", @@ -1749,7 +1381,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.2.9.tgz", "integrity": "sha512-6+UpvINeI//dglZoAKStUXqxDOXJy6Iitv2z3dbgInG4zb8tkYl/VBDL80UjUg3ZvzWG0g7EKY2nRPEpON2TFA==", - "dev": true, "requires": { "eventemitter3": "^4.0.0", "underscore": "1.9.1", @@ -1760,8 +1391,7 @@ "eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" } } }, @@ -1769,7 +1399,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.2.9.tgz", "integrity": "sha512-PWa8b/EaxaMinFaxy6cV0i0EOi2M7a/ST+9k9nhyhCjVa2vzXuNoBNo2IUOmeZ0WP2UQB8ByJ2+p4htlJaDOjA==", - "dev": true, "requires": { "web3-core": "1.2.9", "web3-core-method": "1.2.9", @@ -1781,7 +1410,6 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.2.9.tgz", "integrity": "sha512-9hcpuis3n/LxFzEVjwnVgvJzTirS2S9/MiNAa7l4WOEoywY+BSNwnRX4MuHnjkh9NY25B6QOjuNG6FNnSjTw1w==", - "dev": true, "requires": { "bn.js": "4.11.8", "eth-lib": "0.2.7", @@ -1797,7 +1425,6 @@ "version": "0.2.7", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", - "dev": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -1982,7 +1609,6 @@ "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.3.tgz", "integrity": "sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==", - "dev": true, "requires": { "@types/minimatch": "*", "@types/node": "*" @@ -1991,8 +1617,7 @@ "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", - "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", - "dev": true + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" }, "@types/node": { "version": "10.17.49", @@ -2026,14 +1651,12 @@ "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==" }, "abbrev": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.0.9.tgz", - "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=", - "dev": true + "integrity": "sha1-kbR5JYinc4wl813W9jdSovh3YTU=" }, "abstract-leveldown": { "version": "2.6.3", @@ -2055,22 +1678,13 @@ "address": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "dev": true + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==" }, "aes-js": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.0.0.tgz", "integrity": "sha1-4h3xCtbCBTKVvLuNq0Cwnb6ofk0=" }, - "agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "requires": { - "es6-promisify": "^5.0.0" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -2088,19 +1702,6 @@ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", "optional": true }, - "amp": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", - "integrity": "sha1-at+NWKdPNh6CwfqNOJwHnhOfxH0=" - }, - "amp-message": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", - "integrity": "sha1-p48cmJlQh602GSpBKY5NtJ49/EU=", - "requires": { - "amp": "0.3.1" - } - }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -2109,8 +1710,7 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" }, "ansi-styles": { "version": "4.3.0", @@ -2137,8 +1737,7 @@ "app-module-path": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/app-module-path/-/app-module-path-2.2.0.tgz", - "integrity": "sha1-ZBqlXft9am8KgUHEucCqULbCTdU=", - "dev": true + "integrity": "sha1-ZBqlXft9am8KgUHEucCqULbCTdU=" }, "argparse": { "version": "1.0.10", @@ -2156,8 +1755,7 @@ "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" }, "asn1": { "version": "0.2.4", @@ -2188,14 +1786,6 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" }, - "ast-types": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.14.2.tgz", - "integrity": "sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==", - "requires": { - "tslib": "^2.0.1" - } - }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", @@ -2217,22 +1807,6 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } - } - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -2303,8 +1877,7 @@ "bignumber.js": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.1.tgz", - "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==", - "dev": true + "integrity": "sha512-IdZR9mh6ahOBv/hYGiXyVuyCetmGJhtYkqLBpTStdhEGjegpPlUawydyaF3pbIOFynJTpllEs+NP+CS9jKFLjA==" }, "binary-extensions": { "version": "2.1.0", @@ -2333,11 +1906,6 @@ "resolved": "https://registry.npmjs.org/blakejs/-/blakejs-1.1.0.tgz", "integrity": "sha1-ad+S75U6qIylGjLfarHFShVfx6U=" }, - "blessed": { - "version": "0.1.81", - "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", - "integrity": "sha1-+WLWh+wsNpVwrnGvhDJW5tDKESk=" - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -2390,8 +1958,7 @@ "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" }, "browserify-aes": { "version": "1.2.0", @@ -2592,8 +2159,7 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" }, "caseless": { "version": "0.12.0", @@ -2604,7 +2170,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", - "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", @@ -2618,22 +2183,15 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, - "charm": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", - "integrity": "sha1-BsIe7RobBq62dVPNxT4jJ0usIpY=" - }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", - "dev": true + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=" }, "checkpoint-store": { "version": "1.1.0", @@ -2667,7 +2225,6 @@ "version": "0.7.5", "resolved": "https://registry.npmjs.org/cids/-/cids-0.7.5.tgz", "integrity": "sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==", - "dev": true, "requires": { "buffer": "^5.5.0", "class-is": "^1.1.0", @@ -2680,7 +2237,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-1.0.4.tgz", "integrity": "sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==", - "dev": true, "requires": { "buffer": "^5.6.0", "varint": "^5.0.0" @@ -2700,20 +2256,17 @@ "circular": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/circular/-/circular-1.0.5.tgz", - "integrity": "sha1-fad6+Yu96c5LWzWM1Va13e0tMUk=", - "dev": true + "integrity": "sha1-fad6+Yu96c5LWzWM1Va13e0tMUk=" }, "class-is": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", - "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==", - "dev": true + "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" }, "cli-logger": { "version": "0.5.40", "resolved": "https://registry.npmjs.org/cli-logger/-/cli-logger-0.5.40.tgz", "integrity": "sha1-CX8OEbByx8aYomxH9YiinCC0iws=", - "dev": true, "requires": { "circular": "^1.0.5", "cli-util": "~1.1.27" @@ -2722,33 +2275,12 @@ "cli-regexp": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/cli-regexp/-/cli-regexp-0.1.2.tgz", - "integrity": "sha1-a82TsJ+y7RAl0woRVdWZeVSlNRI=", - "dev": true - }, - "cli-tableau": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", - "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", - "requires": { - "chalk": "3.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - } - } + "integrity": "sha1-a82TsJ+y7RAl0woRVdWZeVSlNRI=" }, "cli-util": { "version": "1.1.27", "resolved": "https://registry.npmjs.org/cli-util/-/cli-util-1.1.27.tgz", "integrity": "sha1-QtaeNqBAoyH8nPhRwVE8rcUJMFQ=", - "dev": true, "requires": { "cli-regexp": "~0.1.0" } @@ -2757,7 +2289,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", @@ -2767,14 +2298,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -2785,7 +2314,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -2805,11 +2333,6 @@ "mimic-response": "^1.0.0" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" - }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -2860,7 +2383,6 @@ "version": "2.5.2", "resolved": "https://registry.npmjs.org/content-hash/-/content-hash-2.5.2.tgz", "integrity": "sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==", - "dev": true, "requires": { "cids": "^0.7.1", "multicodec": "^0.5.5", @@ -2872,15 +2394,6 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -2944,14 +2457,6 @@ "sha.js": "^2.4.8" } }, - "cron": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/cron/-/cron-1.8.2.tgz", - "integrity": "sha512-Gk2c4y6xKEO8FSAUTklqtfSr7oTq0CiPQeLBG5Fl0qoXpZyMcj1SG59YL+hqq04bu6/IuEA7lMkYDAplQNKkyg==", - "requires": { - "moment-timezone": "^0.5.x" - } - }, "cross-fetch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", @@ -3003,21 +2508,10 @@ "assert-plus": "^1.0.0" } }, - "data-uri-to-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==" - }, - "dayjs": { - "version": "1.8.36", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", - "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==" - }, "death": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", - "dev": true + "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=" }, "debug": { "version": "2.6.9", @@ -3030,8 +2524,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", @@ -3131,7 +2624,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", - "dev": true, "requires": { "type-detect": "^4.0.0" } @@ -3154,28 +2646,10 @@ "abstract-leveldown": "~2.6.0" } }, - "degenerator": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", - "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", - "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" - } - } - }, "delay": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/delay/-/delay-4.3.0.tgz", - "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==", - "dev": true + "integrity": "sha512-Lwaf3zVFDMBop1yDuFZ19F9WyGcZcGacsbdlZtWjQmM50tOcMntm1njF/Nb/Vjij3KaSvCF+sEYGKrrjObu2NA==" }, "delayed-stream": { "version": "1.0.0", @@ -3205,7 +2679,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, "requires": { "address": "^1.0.1", "debug": "^2.6.0" @@ -3214,8 +2687,7 @@ "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==" }, "diffie-hellman": { "version": "5.0.3", @@ -3231,7 +2703,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, "requires": { "path-type": "^4.0.0" } @@ -3244,8 +2715,7 @@ "dotenv": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", - "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==", - "dev": true + "integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==" }, "duplexer3": { "version": "0.1.4", @@ -3280,19 +2750,10 @@ "minimalistic-crypto-utils": "^1.0.0" } }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "requires": { - "shimmer": "^1.2.0" - } - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "encodeurl": { "version": "1.0.2", @@ -3325,14 +2786,6 @@ "once": "^1.4.0" } }, - "enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "requires": { - "ansi-colors": "^4.1.1" - } - }, "errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", @@ -3361,19 +2814,6 @@ "es6-symbol": "^3.1.1" } }, - "es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "requires": { - "es6-promise": "^4.0.3" - } - }, "es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", @@ -3388,11 +2828,6 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=" }, - "escape-regexp": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/escape-regexp/-/escape-regexp-0.0.1.tgz", - "integrity": "sha1-9EvaEtRbvfnLf4Yu5+SCez3TIlQ=" - }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3429,8 +2864,7 @@ "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "estraverse": { "version": "1.9.3", @@ -3535,7 +2969,6 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.7.tgz", "integrity": "sha512-cDcJJSJ9GMAcURiAWO3DxIEhTL/uWqlQnvgKpuYQzYPrt/izuGU+1ntQmHt0IRq6ADoSYHFnB+aCEFIldjhkMQ==", - "dev": true, "requires": { "js-sha3": "^0.8.0" }, @@ -3543,8 +2976,7 @@ "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", - "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==", - "dev": true + "integrity": "sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==" } } }, @@ -3698,7 +3130,6 @@ "version": "7.0.7", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-7.0.7.tgz", "integrity": "sha512-vU5rtZBlZsgkTw3o6PDKyB8li2EgLavnAbsKcfsH2YhHH1Le+PP8vEiMnAnvgc1B6uMoaM5GDCrVztBw0Q5K9g==", - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^5.1.2", @@ -3711,8 +3142,7 @@ "bn.js": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", - "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", - "dev": true + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==" } } }, @@ -3893,11 +3323,6 @@ "strip-hex-prefix": "1.0.0" } }, - "eventemitter2": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", - "integrity": "sha1-YZegldX7a1folC9v1+qtY6CclFI=" - }, "eventemitter3": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", @@ -4003,7 +3428,6 @@ "version": "3.2.4", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", - "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -4032,16 +3456,10 @@ "version": "1.9.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.9.0.tgz", "integrity": "sha512-i7FVWL8HhVY+CTkwFxkN2mk3h+787ixS5S63eb78diVRc1MCssarHq3W5cj0av7YDSwmaV928RNag+U1etRQ7w==", - "dev": true, "requires": { "reusify": "^1.0.4" } }, - "fclone": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", - "integrity": "sha1-EOhdo4v+p/xZk0HClu4ddyZu5kA=" - }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -4094,7 +3512,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "requires": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4103,8 +3520,7 @@ "flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" }, "follow-redirects": { "version": "1.13.1", @@ -4170,43 +3586,6 @@ "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "optional": true }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", @@ -4216,7 +3595,6 @@ "version": "6.12.1", "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.12.1.tgz", "integrity": "sha512-zoefZLQpQyEJH9jgtVYgM+ENFLAC9iwys07IDCsju2Ieq9KSTLH89RxSP4bhizXKV/h/+qaWpfyCBGWnBfqgIQ==", - "dev": true, "requires": { "ethereumjs-util": "6.2.1", "source-map-support": "0.5.12", @@ -4226,20 +3604,17 @@ "@types/bn.js": { "version": "4.11.6", "bundled": true, - "dev": true, "requires": { "@types/node": "*" } }, "@types/node": { "version": "14.11.2", - "bundled": true, - "dev": true + "bundled": true }, "@types/pbkdf2": { "version": "3.1.0", "bundled": true, - "dev": true, "requires": { "@types/node": "*" } @@ -4247,20 +3622,17 @@ "@types/secp256k1": { "version": "4.0.1", "bundled": true, - "dev": true, "requires": { "@types/node": "*" } }, "ansi-regex": { "version": "4.1.0", - "bundled": true, - "dev": true + "bundled": true }, "ansi-styles": { "version": "3.2.1", "bundled": true, - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -4268,30 +3640,25 @@ "base-x": { "version": "3.0.8", "bundled": true, - "dev": true, "requires": { "safe-buffer": "^5.0.1" } }, "blakejs": { "version": "1.1.0", - "bundled": true, - "dev": true + "bundled": true }, "bn.js": { "version": "4.11.9", - "bundled": true, - "dev": true + "bundled": true }, "brorand": { "version": "1.1.0", - "bundled": true, - "dev": true + "bundled": true }, "browserify-aes": { "version": "1.2.0", "bundled": true, - "dev": true, "requires": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", @@ -4304,7 +3671,6 @@ "bs58": { "version": "4.0.1", "bundled": true, - "dev": true, "requires": { "base-x": "^3.0.2" } @@ -4312,7 +3678,6 @@ "bs58check": { "version": "2.1.2", "bundled": true, - "dev": true, "requires": { "bs58": "^4.0.0", "create-hash": "^1.1.0", @@ -4321,23 +3686,19 @@ }, "buffer-from": { "version": "1.1.1", - "bundled": true, - "dev": true + "bundled": true }, "buffer-xor": { "version": "1.0.3", - "bundled": true, - "dev": true + "bundled": true }, "camelcase": { "version": "5.3.1", - "bundled": true, - "dev": true + "bundled": true }, "cipher-base": { "version": "1.0.4", "bundled": true, - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4346,7 +3707,6 @@ "cliui": { "version": "5.0.0", "bundled": true, - "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", @@ -4356,20 +3716,17 @@ "color-convert": { "version": "1.9.3", "bundled": true, - "dev": true, "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", - "bundled": true, - "dev": true + "bundled": true }, "create-hash": { "version": "1.2.0", "bundled": true, - "dev": true, "requires": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", @@ -4381,7 +3738,6 @@ "create-hmac": { "version": "1.1.7", "bundled": true, - "dev": true, "requires": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", @@ -4394,7 +3750,6 @@ "cross-spawn": { "version": "6.0.5", "bundled": true, - "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", @@ -4405,13 +3760,11 @@ }, "decamelize": { "version": "1.2.0", - "bundled": true, - "dev": true + "bundled": true }, "elliptic": { "version": "6.5.3", "bundled": true, - "dev": true, "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -4424,13 +3777,11 @@ }, "emoji-regex": { "version": "7.0.3", - "bundled": true, - "dev": true + "bundled": true }, "end-of-stream": { "version": "1.4.4", "bundled": true, - "dev": true, "requires": { "once": "^1.4.0" } @@ -4438,7 +3789,6 @@ "ethereum-cryptography": { "version": "0.1.3", "bundled": true, - "dev": true, "requires": { "@types/pbkdf2": "^3.0.0", "@types/secp256k1": "^4.0.1", @@ -4460,7 +3810,6 @@ "ethereumjs-util": { "version": "6.2.1", "bundled": true, - "dev": true, "requires": { "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", @@ -4474,7 +3823,6 @@ "ethjs-util": { "version": "0.1.6", "bundled": true, - "dev": true, "requires": { "is-hex-prefixed": "1.0.0", "strip-hex-prefix": "1.0.0" @@ -4483,7 +3831,6 @@ "evp_bytestokey": { "version": "1.0.3", "bundled": true, - "dev": true, "requires": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" @@ -4492,7 +3839,6 @@ "execa": { "version": "1.0.0", "bundled": true, - "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", @@ -4506,20 +3852,17 @@ "find-up": { "version": "3.0.0", "bundled": true, - "dev": true, "requires": { "locate-path": "^3.0.0" } }, "get-caller-file": { "version": "2.0.5", - "bundled": true, - "dev": true + "bundled": true }, "get-stream": { "version": "4.1.0", "bundled": true, - "dev": true, "requires": { "pump": "^3.0.0" } @@ -4527,7 +3870,6 @@ "hash-base": { "version": "3.1.0", "bundled": true, - "dev": true, "requires": { "inherits": "^2.0.4", "readable-stream": "^3.6.0", @@ -4537,7 +3879,6 @@ "hash.js": { "version": "1.1.7", "bundled": true, - "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" @@ -4546,7 +3887,6 @@ "hmac-drbg": { "version": "1.0.1", "bundled": true, - "dev": true, "requires": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", @@ -4555,38 +3895,31 @@ }, "inherits": { "version": "2.0.4", - "bundled": true, - "dev": true + "bundled": true }, "invert-kv": { "version": "2.0.0", - "bundled": true, - "dev": true + "bundled": true }, "is-fullwidth-code-point": { "version": "2.0.0", - "bundled": true, - "dev": true + "bundled": true }, "is-hex-prefixed": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "is-stream": { "version": "1.1.0", - "bundled": true, - "dev": true + "bundled": true }, "isexe": { "version": "2.0.0", - "bundled": true, - "dev": true + "bundled": true }, "keccak": { "version": "3.0.1", "bundled": true, - "dev": true, "requires": { "node-addon-api": "^2.0.0", "node-gyp-build": "^4.2.0" @@ -4595,7 +3928,6 @@ "lcid": { "version": "2.0.0", "bundled": true, - "dev": true, "requires": { "invert-kv": "^2.0.0" } @@ -4603,7 +3935,6 @@ "locate-path": { "version": "3.0.0", "bundled": true, - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -4612,7 +3943,6 @@ "map-age-cleaner": { "version": "0.1.3", "bundled": true, - "dev": true, "requires": { "p-defer": "^1.0.0" } @@ -4620,7 +3950,6 @@ "md5.js": { "version": "1.3.5", "bundled": true, - "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1", @@ -4630,7 +3959,6 @@ "mem": { "version": "4.3.0", "bundled": true, - "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^2.0.0", @@ -4639,38 +3967,31 @@ }, "mimic-fn": { "version": "2.1.0", - "bundled": true, - "dev": true + "bundled": true }, "minimalistic-assert": { "version": "1.0.1", - "bundled": true, - "dev": true + "bundled": true }, "minimalistic-crypto-utils": { "version": "1.0.1", - "bundled": true, - "dev": true + "bundled": true }, "nice-try": { "version": "1.0.5", - "bundled": true, - "dev": true + "bundled": true }, "node-addon-api": { "version": "2.0.2", - "bundled": true, - "dev": true + "bundled": true }, "node-gyp-build": { "version": "4.2.3", - "bundled": true, - "dev": true + "bundled": true }, "npm-run-path": { "version": "2.0.2", "bundled": true, - "dev": true, "requires": { "path-key": "^2.0.0" } @@ -4678,7 +3999,6 @@ "once": { "version": "1.4.0", "bundled": true, - "dev": true, "requires": { "wrappy": "1" } @@ -4686,7 +4006,6 @@ "os-locale": { "version": "3.1.0", "bundled": true, - "dev": true, "requires": { "execa": "^1.0.0", "lcid": "^2.0.0", @@ -4695,23 +4014,19 @@ }, "p-defer": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "p-finally": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "p-is-promise": { "version": "2.1.0", - "bundled": true, - "dev": true + "bundled": true }, "p-limit": { "version": "2.3.0", "bundled": true, - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -4719,30 +4034,25 @@ "p-locate": { "version": "3.0.0", "bundled": true, - "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", - "bundled": true, - "dev": true + "bundled": true }, "path-exists": { "version": "3.0.0", - "bundled": true, - "dev": true + "bundled": true }, "path-key": { "version": "2.0.1", - "bundled": true, - "dev": true + "bundled": true }, "pbkdf2": { "version": "3.1.1", "bundled": true, - "dev": true, "requires": { "create-hash": "^1.1.2", "create-hmac": "^1.1.4", @@ -4754,7 +4064,6 @@ "pump": { "version": "3.0.0", "bundled": true, - "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" @@ -4763,7 +4072,6 @@ "randombytes": { "version": "2.1.0", "bundled": true, - "dev": true, "requires": { "safe-buffer": "^5.1.0" } @@ -4771,7 +4079,6 @@ "readable-stream": { "version": "3.6.0", "bundled": true, - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -4780,18 +4087,15 @@ }, "require-directory": { "version": "2.1.1", - "bundled": true, - "dev": true + "bundled": true }, "require-main-filename": { "version": "2.0.0", - "bundled": true, - "dev": true + "bundled": true }, "ripemd160": { "version": "2.0.2", "bundled": true, - "dev": true, "requires": { "hash-base": "^3.0.0", "inherits": "^2.0.1" @@ -4800,25 +4104,21 @@ "rlp": { "version": "2.2.6", "bundled": true, - "dev": true, "requires": { "bn.js": "^4.11.1" } }, "safe-buffer": { "version": "5.2.1", - "bundled": true, - "dev": true + "bundled": true }, "scrypt-js": { "version": "3.0.1", - "bundled": true, - "dev": true + "bundled": true }, "secp256k1": { "version": "4.0.2", "bundled": true, - "dev": true, "requires": { "elliptic": "^6.5.2", "node-addon-api": "^2.0.0", @@ -4827,23 +4127,19 @@ }, "semver": { "version": "5.7.1", - "bundled": true, - "dev": true + "bundled": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, - "dev": true + "bundled": true }, "setimmediate": { "version": "1.0.5", - "bundled": true, - "dev": true + "bundled": true }, "sha.js": { "version": "2.4.11", "bundled": true, - "dev": true, "requires": { "inherits": "^2.0.1", "safe-buffer": "^5.0.1" @@ -4852,30 +4148,25 @@ "shebang-command": { "version": "1.2.0", "bundled": true, - "dev": true, "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "signal-exit": { "version": "3.0.3", - "bundled": true, - "dev": true + "bundled": true }, "source-map": { "version": "0.6.1", - "bundled": true, - "dev": true + "bundled": true }, "source-map-support": { "version": "0.5.12", "bundled": true, - "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -4884,7 +4175,6 @@ "string-width": { "version": "3.1.0", "bundled": true, - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -4894,7 +4184,6 @@ "string_decoder": { "version": "1.3.0", "bundled": true, - "dev": true, "requires": { "safe-buffer": "~5.2.0" } @@ -4902,46 +4191,39 @@ "strip-ansi": { "version": "5.2.0", "bundled": true, - "dev": true, "requires": { "ansi-regex": "^4.1.0" } }, "strip-eof": { "version": "1.0.0", - "bundled": true, - "dev": true + "bundled": true }, "strip-hex-prefix": { "version": "1.0.0", "bundled": true, - "dev": true, "requires": { "is-hex-prefixed": "1.0.0" } }, "util-deprecate": { "version": "1.0.2", - "bundled": true, - "dev": true + "bundled": true }, "which": { "version": "1.3.1", "bundled": true, - "dev": true, "requires": { "isexe": "^2.0.0" } }, "which-module": { "version": "2.0.0", - "bundled": true, - "dev": true + "bundled": true }, "wrap-ansi": { "version": "5.1.0", "bundled": true, - "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -4950,18 +4232,15 @@ }, "wrappy": { "version": "1.0.2", - "bundled": true, - "dev": true + "bundled": true }, "y18n": { "version": "4.0.0", - "bundled": true, - "dev": true + "bundled": true }, "yargs": { "version": "13.2.4", "bundled": true, - "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -4979,7 +4258,6 @@ "yargs-parser": { "version": "13.1.2", "bundled": true, - "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -4990,14 +4268,12 @@ "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" }, "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", - "dev": true + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=" }, "get-stream": { "version": "4.1.0", @@ -5007,19 +4283,6 @@ "pump": "^3.0.0" } }, - "get-uri": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.4.tgz", - "integrity": "sha512-v7LT/s8kVjs+Tx0ykk1I+H/rbpzkHvuIq87LmeXptcf5sNWm9uQiwjNAt94SJPA1zOlCntmnOlJvVWKmzsxG8Q==", - "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "~3.0.2", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" - } - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -5032,7 +4295,6 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz", "integrity": "sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==", - "dev": true, "requires": { "chalk": "^2.4.2", "node-emoji": "^1.10.0" @@ -5042,7 +4304,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -5051,7 +4312,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -5062,7 +4322,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -5070,26 +4329,22 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -5130,7 +4385,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, "requires": { "global-prefix": "^3.0.0" } @@ -5139,7 +4393,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, "requires": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -5150,7 +4403,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -5161,7 +4413,6 @@ "version": "10.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", "integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==", - "dev": true, "requires": { "@types/glob": "^7.1.1", "array-union": "^2.1.0", @@ -5199,14 +4450,12 @@ "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==" }, "handlebars": { "version": "4.7.6", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", - "dev": true, "requires": { "minimist": "^1.2.5", "neo-async": "^2.6.0", @@ -5229,14 +4478,6 @@ "har-schema": "^2.0.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -5289,8 +4530,7 @@ "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, "hmac-drbg": { "version": "1.0.1", @@ -5331,25 +4571,6 @@ "resolved": "https://registry.npmjs.org/http-https/-/http-https-1.0.0.tgz", "integrity": "sha1-L5CN1fHbQGjAWM1ubUzjkskTOJs=" }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "requires": { - "agent-base": "4", - "debug": "3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - } - } - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -5360,30 +4581,6 @@ "sshpk": "^1.7.0" } }, - "https-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-3.0.1.tgz", - "integrity": "sha512-+ML2Rbh6DAuee7d07tYGEKOEi2voWPUGan+ExdPbPW6Z3svq+JCqr0v8WmKPOkz1vOVykPCBSuobe7G8GJUtVg==", - "requires": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -5415,8 +4612,7 @@ "ignore": { "version": "5.1.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", - "dev": true + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==" }, "immediate": { "version": "3.3.0", @@ -5440,19 +4636,12 @@ "ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, "interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" }, "ipaddr.js": { "version": "1.9.1", @@ -5467,14 +4656,6 @@ "binary-extensions": "^2.0.0" } }, - "is-core-module": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz", - "integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==", - "requires": { - "has": "^1.0.3" - } - }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -5488,8 +4669,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "is-function": { "version": "1.0.2", @@ -5552,8 +4732,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isstream": { "version": "0.1.2", @@ -5578,7 +4757,6 @@ "version": "3.14.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -5647,8 +4825,7 @@ "jsonschema": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.0.tgz", - "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==", - "dev": true + "integrity": "sha512-/YgW6pRMr6M7C+4o8kS+B/2myEpHCrxO4PEWnqJNBFMjn7EWXqlQ4tGwL6xTHeRplwuZmcAncdvfOad1nT2yMw==" }, "jsprim": { "version": "1.4.1", @@ -5681,13 +4858,7 @@ "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "lazy": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", - "integrity": "sha1-2qBoIGKCVCwIgojpdcKXwa53tpA=" + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" }, "level-codec": { "version": "7.0.1", @@ -5810,7 +4981,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "requires": { "p-locate": "^5.0.0" } @@ -5833,19 +5003,12 @@ "lodash.toarray": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz", - "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=", - "dev": true - }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==" + "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=" }, "log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", - "dev": true, "requires": { "chalk": "^4.0.0" } @@ -5941,8 +5104,7 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" }, "merkle-patricia-tree": { "version": "2.3.2", @@ -5989,7 +5151,6 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", - "dev": true, "requires": { "braces": "^3.0.1", "picomatch": "^2.0.5" @@ -6092,7 +5253,6 @@ "version": "8.2.1", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", - "dev": true, "requires": { "@ungap/promise-all-settled": "1.1.2", "ansi-colors": "4.1.1", @@ -6125,7 +5285,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, "requires": { "ms": "2.1.2" } @@ -6133,8 +5292,7 @@ "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" } } }, @@ -6143,24 +5301,6 @@ "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.13.0.tgz", "integrity": "sha512-DD0vOdofJdoaRNtnWcrXe6RQbpHkPPmtqGq14uRX0F8ZKJ5nv89CVTYl/BZdppDxBDaV0hl75htg3abpEWlPZA==" }, - "module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" - }, - "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" - }, - "moment-timezone": { - "version": "0.5.32", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.32.tgz", - "integrity": "sha512-Z8QNyuQHQAmWucp8Knmgei8YNo28aLjJq6Ma+jy1ZSpSk5nyfRT8xgUbSQvD2+2UajISfenndwvFuH3NGS+nvA==", - "requires": { - "moment": ">= 2.9.0" - } - }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -6170,7 +5310,6 @@ "version": "0.6.1", "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.6.1.tgz", "integrity": "sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==", - "dev": true, "requires": { "base-x": "^3.0.8", "buffer": "^5.5.0" @@ -6180,7 +5319,6 @@ "version": "0.5.7", "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-0.5.7.tgz", "integrity": "sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==", - "dev": true, "requires": { "varint": "^5.0.0" } @@ -6189,7 +5327,6 @@ "version": "0.4.21", "resolved": "https://registry.npmjs.org/multihashes/-/multihashes-0.4.21.tgz", "integrity": "sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==", - "dev": true, "requires": { "buffer": "^5.5.0", "multibase": "^0.7.0", @@ -6200,7 +5337,6 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/multibase/-/multibase-0.7.0.tgz", "integrity": "sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==", - "dev": true, "requires": { "base-x": "^3.0.8", "buffer": "^5.5.0" @@ -6208,11 +5344,6 @@ } } }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" - }, "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", @@ -6226,33 +5357,7 @@ "nanoid": { "version": "3.1.12", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", - "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", - "dev": true - }, - "needle": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", - "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==" }, "negotiator": { "version": "0.6.2", @@ -6262,13 +5367,7 @@ "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "netmask": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=" + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==" }, "next-tick": { "version": "1.0.0", @@ -6284,7 +5383,6 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.10.0.tgz", "integrity": "sha512-Yt3384If5H6BYGVHiHwTL+99OzJKHhgp82S8/dktEK73T26BazdgZ4JZh92xSVtGNJvz9UbXdNAc5hcrXV42vw==", - "dev": true, "requires": { "lodash.toarray": "^4.4.0" } @@ -6307,7 +5405,6 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, "requires": { "abbrev": "1" } @@ -6322,22 +5419,6 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.0.tgz", "integrity": "sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==" }, - "nssocket": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", - "integrity": "sha1-Wflvb/MhVm8zxw99vu7N/cBxVPo=", - "requires": { - "eventemitter2": "~0.4.14", - "lazy": "~1.0.11" - }, - "dependencies": { - "eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=" - } - } - }, "number-to-bn": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz", @@ -6409,8 +5490,7 @@ "original-require": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", - "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=", - "dev": true + "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=" }, "p-cancelable": { "version": "1.1.0", @@ -6426,7 +5506,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "requires": { "yocto-queue": "^0.1.0" } @@ -6435,7 +5514,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "requires": { "p-limit": "^3.0.2" } @@ -6451,50 +5529,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pac-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-3.0.1.tgz", - "integrity": "sha512-44DUg21G/liUZ48dJpUSjZnFfZro/0K5JTyFYLBcmh9+T6Ooi4/i4efwUiEy0+4oQusCBqWdhv16XohIj1GqnQ==", - "requires": { - "agent-base": "^4.2.0", - "debug": "^4.1.1", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^3.0.0", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "pac-resolver": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", - "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" - } + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "parse-asn1": { "version": "5.1.6", @@ -6521,19 +5556,13 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, - "path-parse": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" - }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -6542,14 +5571,12 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, "pathval": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", - "dev": true + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=" }, "pbkdf2": { "version": "3.1.1", @@ -6578,14 +5605,6 @@ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==" }, - "pidusage": { - "version": "2.0.21", - "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", - "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", - "requires": { - "safe-buffer": "^5.2.1" - } - }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -6604,157 +5623,6 @@ "pinkie": "^2.0.0" } }, - "pm2": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/pm2/-/pm2-4.5.1.tgz", - "integrity": "sha512-gEOYugy4vEGazszDtjbZcWnZhHpBLKl0JiYhEnIJqmMj576a0D5LNCmd9grJswB1ziZim+9YInqFrG3FQTxvEg==", - "requires": { - "@pm2/agent": "~1.0.2", - "@pm2/io": "~4.3.5", - "@pm2/js-api": "~0.6.0", - "@pm2/pm2-version-check": "^1.0.3", - "async": "~3.2.0", - "blessed": "0.1.81", - "chalk": "3.0.0", - "chokidar": "^3.3.0", - "cli-tableau": "^2.0.0", - "commander": "2.15.1", - "cron": "1.8.2", - "dayjs": "~1.8.25", - "debug": "^4.3.0", - "enquirer": "2.3.6", - "eventemitter2": "5.0.1", - "fclone": "1.0.11", - "mkdirp": "1.0.4", - "needle": "2.4.0", - "pidusage": "2.0.21", - "pm2-axon": "4.0.0", - "pm2-axon-rpc": "0.6.0", - "pm2-deploy": "~1.0.2", - "pm2-multimeter": "^0.1.2", - "promptly": "^2", - "ps-list": "6.3.0", - "semver": "^7.2", - "source-map-support": "0.5.19", - "sprintf-js": "1.1.2", - "systeminformation": "^4.32", - "vizion": "0.2.13", - "yamljs": "0.3.0" - }, - "dependencies": { - "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==" - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" - }, - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "semver": { - "version": "7.3.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", - "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" - } - } - }, - "pm2-axon": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.0.tgz", - "integrity": "sha512-A8dy0C57cRIm+kX58HrMcnvUdg8EdwCuCmavDdmFE4eoUE+5zfwGbDfZKCBVLNpDwjXPuXQQYZi3wQt/5xC8DQ==", - "requires": { - "amp": "~0.3.1", - "amp-message": "~0.1.1", - "debug": "^4.2", - "escape-string-regexp": "^4.0.0" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "pm2-axon-rpc": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.6.0.tgz", - "integrity": "sha512-xjYR0y1HpOopJ09VL2Qd5H1LajVN+QLPVZ1G+GesbORJDAZiStMhwECtOzm/Gx5ANQxL0usW8WZsElMfQq2hbw==", - "requires": { - "debug": "^3.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "pm2-deploy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", - "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==", - "requires": { - "run-series": "^1.1.8", - "tv4": "^1.3.0" - } - }, - "pm2-multimeter": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", - "integrity": "sha1-Gh5VFT1BoFU0zqI8/oYKuqDrSs4=", - "requires": { - "charm": "~0.1.1" - } - }, "precond": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/precond/-/precond-0.2.3.tgz", @@ -6789,14 +5657,6 @@ "set-immediate-shim": "^1.0.1" } }, - "promptly": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", - "integrity": "sha1-KhP6BjaIoqWYOxYf/wEIoH0m/HQ=", - "requires": { - "read": "^1.0.4" - } - }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -6806,59 +5666,11 @@ "ipaddr.js": "1.9.1" } }, - "proxy-agent": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.1.1.tgz", - "integrity": "sha512-WudaR0eTsDx33O3EJE16PjBRZWcX8GqCEeERw1W3hZJgH/F2a46g7jty6UGty6NeJ4CKQy8ds2CJPMiyeqaTvw==", - "requires": { - "agent-base": "^4.2.0", - "debug": "4", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^3.0.0", - "lru-cache": "^5.1.1", - "pac-proxy-agent": "^3.0.1", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "requires": { - "yallist": "^3.0.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - } - } - }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, - "ps-list": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/ps-list/-/ps-list-6.3.0.tgz", - "integrity": "sha512-qau0czUSB0fzSlBOQt0bo+I2v6R+xiQdj78e1BR/Qjfl5OHWJ/urXi8+ilw1eHe+5hSeDI1wrwVTgDp2wst4oA==" - }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -6909,8 +5721,7 @@ "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, "randombytes": { "version": "2.1.0", @@ -6950,14 +5761,6 @@ "unpipe": "1.0.0" } }, - "read": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", - "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", - "requires": { - "mute-stream": "~0.0.4" - } - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -6991,7 +5794,6 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, "requires": { "resolve": "^1.1.6" } @@ -7000,7 +5802,6 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", "integrity": "sha512-nRCcW9Sj7NuZwa2XvH9co8NPeXUBhZP7CRKJtU+cS6PW9FpCIFoI5ib0NT1ZrbNuPoRy0ylyCaUL8Gih4LSyFg==", - "dev": true, "requires": { "minimatch": "3.0.4" } @@ -7047,54 +5848,17 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-in-the-middle": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.1.0.tgz", - "integrity": "sha512-M2rLKVupQfJ5lf9OvqFGIT+9iVLnTmjgbOmpil12hiSQNn5zJTKGPoIisETNjfK+09vP3rpm1zJajmErpr2sEQ==", - "requires": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "requires": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - } - } - } + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" }, "resolve": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" }, "responselike": { "version": "1.0.2", @@ -7107,8 +5871,7 @@ "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "ripemd160": { "version": "2.0.2", @@ -7130,13 +5893,7 @@ "run-parallel": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", - "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==", - "dev": true - }, - "run-series": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", - "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==" + "integrity": "sha512-zb/1OuZ6flOlH6tQyMPUrE3x3Ulxjlo9WIVXR4yVYi4H9UXQaeIsPbLn2R3O3vQCnDKkAl2qHiuocKKX4Tz/Sw==" }, "rustbn.js": { "version": "0.2.0", @@ -7161,16 +5918,10 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, "sc-istanbul": { "version": "0.4.5", "resolved": "https://registry.npmjs.org/sc-istanbul/-/sc-istanbul-0.4.5.tgz", "integrity": "sha512-7wR5EZFLsC4w0wSm9BUuCgW+OGKAU7PNlW5L0qwVPbh+Q1sfVn2fyzfMXYCm6rkNA5ipaCOt94nApcguQwF5Gg==", - "dev": true, "requires": { "abbrev": "1.0.x", "async": "1.x", @@ -7191,20 +5942,17 @@ "async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" }, "glob": { "version": "5.0.15", "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -7216,14 +5964,12 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", - "dev": true, "requires": { "minimist": "^1.2.5" } @@ -7232,7 +5978,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -7241,7 +5986,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -7317,7 +6061,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", - "dev": true, "requires": { "randombytes": "^2.1.0" } @@ -7348,8 +6091,7 @@ "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-immediate-shim": { "version": "1.0.1", @@ -7379,23 +6121,12 @@ "version": "0.8.4", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==", - "dev": true, "requires": { "glob": "^7.0.0", "interpret": "^1.0.0", "rechoir": "^0.6.2" } }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" - }, "simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -7414,47 +6145,12 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "smart-buffer": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.1.0.tgz", - "integrity": "sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw==" - }, - "socks": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.3.3.tgz", - "integrity": "sha512-o5t52PCNtVdiOvzMry7wU4aOqYWL0PeCXRWBEiJow4/i/wr+wpsJQ9awEu1EonLIqsfGd5qSgDdxEOvCdmBEpA==", - "requires": { - "ip": "1.1.5", - "smart-buffer": "^4.1.0" - } - }, - "socks-proxy-agent": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.2.tgz", - "integrity": "sha512-NT6syHhI9LmuEMSK6Kd2V7gNv5KFZoLE7V5udWmn0de+3Mkj3UMA/AJPLyeNUVmElCurSHtUdM3ETpR3z770Wg==", - "requires": { - "agent-base": "~4.2.1", - "socks": "~2.3.2" - }, - "dependencies": { - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "requires": { - "es6-promisify": "^5.0.0" - } - } - } + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "solidity-coverage": { "version": "0.7.13", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.13.tgz", "integrity": "sha512-06r0R+/j8lgl5/Z57VwxWNFZId0ZavcQU45W2gCfsBmEt/1Y6Xgm96oMSa6JBIvwrPR8H4T3icxTLiUVsMFNeg==", - "dev": true, "requires": { "@solidity-parser/parser": "^0.8.1", "@truffle/provider": "^0.2.24", @@ -7481,7 +6177,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -7490,7 +6185,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -7501,7 +6195,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -7509,20 +6202,17 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "eth-lib": { "version": "0.2.8", "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.8.tgz", "integrity": "sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==", - "dev": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -7533,7 +6223,6 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, "requires": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", @@ -7543,20 +6232,17 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" }, "semver": { "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", - "dev": true, "requires": { "lru-cache": "^6.0.0" } @@ -7565,7 +6251,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -7574,7 +6259,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.3.0.tgz", "integrity": "sha512-2mS5axFCbkhicmoDRuJeuo0TVGQDgC2sPi/5dblfVC+PMtX0efrb8Xlttv/eGkq7X4E83Pds34FH98TP2WOUZA==", - "dev": true, "requires": { "bn.js": "^4.11.9", "eth-lib": "0.2.8", @@ -7637,7 +6321,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" @@ -7662,7 +6345,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -7686,8 +6368,7 @@ "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" }, "supports-color": { "version": "7.2.0", @@ -7762,12 +6443,6 @@ } } }, - "systeminformation": { - "version": "4.34.7", - "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-4.34.7.tgz", - "integrity": "sha512-cS3FiSZasFgVNjO9CP3aZmTO2VHwXKG+JN6Z85nWRyOzxRMNbZe7Xzwrewp42hj+OPMC3hk7MrAFyu/qLM65Mw==", - "optional": true - }, "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", @@ -7811,11 +6486,6 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, - "thunkify": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", - "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=" - }, "timed-out": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", @@ -7862,7 +6532,6 @@ "version": "5.1.10", "resolved": "https://registry.npmjs.org/truffle/-/truffle-5.1.10.tgz", "integrity": "sha512-7dkBjNwabpNUp2LTSsXWUk5TMOfomX9F0mPLDEZgAgmfH3qWG5rBEUn/jw5t0LQfVx8NCG+GIN9FxqiUIEWrYQ==", - "dev": true, "requires": { "app-module-path": "^2.2.0", "mocha": "5.2.0", @@ -7872,14 +6541,12 @@ "commander": { "version": "2.15.1", "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==" }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -7887,20 +6554,17 @@ "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -7913,26 +6577,22 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "he": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, "requires": { "minimist": "0.0.8" } @@ -7941,7 +6601,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", - "dev": true, "requires": { "browser-stdout": "1.3.1", "commander": "2.15.1", @@ -7960,7 +6619,6 @@ "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -7976,22 +6634,10 @@ "lodash.isequal": "^4.5.0" } }, - "truffle-hdwallet-provider": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/truffle-hdwallet-provider/-/truffle-hdwallet-provider-1.0.17.tgz", - "integrity": "sha512-s6DvSP83jiIAc6TUcpr7Uqnja1+sLGJ8og3X7n41vfyC4OCaKmBtXL5HOHf+SsU3iblOvnbFDgmN6Y1VBL/fsg==", - "requires": { - "any-promise": "^1.3.0", - "bindings": "^1.3.1", - "web3": "1.2.1", - "websocket": "^1.0.28" - } - }, "truffle-plugin-verify": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/truffle-plugin-verify/-/truffle-plugin-verify-0.5.2.tgz", "integrity": "sha512-2D1GdfdfltvXRf/VYgFep+uouBtdFWi/O2xA1/khqEg9pREmtNXEYzDjozpOInJ1jzoyn30oFUyb1rouD0dlqw==", - "dev": true, "requires": { "axios": "0.19.2", "cli-logger": "0.5.40", @@ -8003,7 +6649,6 @@ "version": "0.19.2", "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", - "dev": true, "requires": { "follow-redirects": "1.5.10" } @@ -8012,7 +6657,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, "requires": { "ms": "2.0.0" } @@ -8021,18 +6665,12 @@ "version": "1.5.10", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "dev": true, "requires": { "debug": "=3.1.0" } } } }, - "tslib": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.1.0.tgz", - "integrity": "sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==" - }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -8041,11 +6679,6 @@ "safe-buffer": "^5.0.1" } }, - "tv4": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", - "integrity": "sha1-0CDIRvrdUMhVq7JeuuzGj8EPeWM=" - }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", @@ -8067,8 +6700,7 @@ "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, "type-is": { "version": "1.6.18", @@ -8091,7 +6723,6 @@ "version": "3.12.2", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.2.tgz", "integrity": "sha512-rWYleAvfJPjduYCt+ELvzybNah/zIkRteGXIBO8X0lteRZPGladF61hFi8tU7qKTsF7u6DUQCtT9k00VlFOgkg==", - "dev": true, "optional": true }, "ultron": { @@ -8180,8 +6811,7 @@ "varint": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", - "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==", - "dev": true + "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==" }, "vary": { "version": "1.1.2", @@ -8198,21 +6828,6 @@ "extsprintf": "^1.2.0" } }, - "vizion": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/vizion/-/vizion-0.2.13.tgz", - "integrity": "sha1-ExTN7is0EW+fWxJIU2+V2/zW718=", - "requires": { - "async": "1.5" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" - } - } - }, "web3": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/web3/-/web3-1.2.1.tgz", @@ -8594,7 +7209,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "requires": { "isexe": "^2.0.0" } @@ -8602,14 +7216,12 @@ "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, "requires": { "string-width": "^1.0.2 || 2" } @@ -8622,20 +7234,17 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "workerpool": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", - "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", - "dev": true + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==" }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", @@ -8645,14 +7254,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -8661,7 +7268,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -8669,14 +7275,12 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -8687,7 +7291,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -8750,11 +7353,6 @@ "resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz", "integrity": "sha1-Z/4HXFwk/vOfnWX197f+dRcZaPw=" }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -8763,8 +7361,7 @@ "y18n": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" }, "yaeti": { "version": "0.0.6", @@ -8776,20 +7373,10 @@ "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" }, - "yamljs": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", - "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", - "requires": { - "argparse": "^1.0.7", - "glob": "^7.0.5" - } - }, "yargs": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", - "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", @@ -8806,14 +7393,12 @@ "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, "requires": { "locate-path": "^3.0.0" } @@ -8822,7 +7407,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" @@ -8832,7 +7416,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -8841,7 +7424,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, "requires": { "p-limit": "^2.0.0" } @@ -8849,14 +7431,12 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=" }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", @@ -8867,7 +7447,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, "requires": { "ansi-regex": "^4.1.0" } @@ -8878,7 +7457,6 @@ "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", - "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" @@ -8888,7 +7466,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, "requires": { "camelcase": "^6.0.0", "decamelize": "^4.0.0", @@ -8899,20 +7476,17 @@ "camelcase": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", - "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", - "dev": true + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==" }, "decamelize": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==" }, "is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==" } } }, @@ -8928,8 +7502,7 @@ "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" } } } diff --git a/truffle-config.js b/truffle-config.js index 5911cb4c..ad5693bd 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -8,143 +8,140 @@ * * truffleframework.com/docs/advanced/configuration * - * To deploy via Infura you'll need a wallet provider (like truffle-hdwallet-provider) - * to sign your transactions before they're sent to a remote public node. Infura accounts - * are available for free at: infura.io/register. + * To deploy via Infura you'll need a wallet provider (like + * truffle-hdwallet-provider) to sign your transactions before they're sent to + * a remote public node. Infura accounts are available for free at: + * infura.io/register. * - * You'll also need a mnemonic - the twelve word phrase the wallet uses to generate - * public/private key pairs. If you're publishing your code to GitHub make sure you load this - * phrase from a file you've .gitignored so it doesn't accidentally become public. + * You'll also need a mnemonic - the twelve word phrase the wallet uses to + * generate public/private key pairs. If you're publishing your code to GitHub + * make sure you load this phrase from a file you've .gitignored so it doesn't + * accidentally become public. * */ -const HDWalletProvider = require('@truffle/hdwallet-provider'); -const fs = require('fs'); -const pk = fs.readFileSync(".secret").toString().trim(); +const HDWalletProvider = require('@truffle/hdwallet-provider') +const fs = require('fs') -require('dotenv').config(); - -// const config = require('./common/config'); -// const config_networks = config("networks"); - -// const options = { -// contracts_build_directory: './drizzle/app/src/contracts', +require('dotenv').config() module.exports = { - /** - * Networks define how you connect to your ethereum client and let you set the - * defaults web3 uses to send transactions. If you don't specify one truffle - * will spin up a development blockchain for you on port 9545 when you - * run `develop` or `test`. You can ask a truffle command to use a specific - * network from the command line, e.g - * - * $ truffle test --network - */ - - networks: { - // Useful for testing. The `development` name is special - truffle uses it by default - // if it's defined here and no other network is specified at the command line. - // You should run a client (like ganache-cli, geth or parity) in a separate terminal - // tab if you use this network and you must also set the `host`, `port` and `network_id` - // options below to some value. - // - development: { - host: '127.0.0.1', // Localhost (default: none) - port: 8545, // Standard Ethereum port (default: none) - network_id: '*', // Any network (default: none) - }, - - coverage: { - host: '127.0.0.1', // Localhost (default: none) - port: 8555, // Test Coverage Port - network_id: '*', // Any network (default: none) - }, - - ropsten: { - provider: () => new HDWalletProvider(pk, "http://localhost:8545"), - network_id: 3, - gas: 8000000, - }, - - rinkeby: { - provider: function() { - return new HDWalletProvider( - `${process.env.PK}`, - `https://rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}` - ) - }, - network_id: 4 - }, - - // extend options with JSON config settings - // this is a complete list of config files in /common/json/config-*.json - //...config_networks, - - // host: "100.115.92.198", // Local IP for costini - // port: 8545, // Standard Ethereum port (default: none) - // network_id: "*", // Any network (default: none) - // }, - - - // Another network with more advanced options... - // advanced: { - // port: 8777, // Custom port - // network_id: 1342, // Custom network - // gas: 8500000, // Gas sent with each transaction (default: ~6700000) - // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) - // from:
, // Account to send txs from (default: accounts[0]) - // websockets: true // Enable EventEmitter interface for web3 (default: false) - // }, - - // Useful for deploying to a public network. - // NB: It's important to wrap the provider as a function. - // ropsten: { - // provider: () => new HDWalletProvider(mnemonic, `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`), - // network_id: 3, // Ropsten's id - // gas: 5500000, // Ropsten has a lower block limit than mainnet - // confirmations: 2, // # of confs to wait between deployments. (default: 0) - // timeoutBlocks: 200, // # of blocks before a deployment times out (minimum/default: 50) - // skipDryRun: true // Skip dry run before migrations? (default: false for public nets ) - // }, - - // Useful for private networks - // private: { - // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), - // network_id: 2111, // This network is yours, in the cloud. - // production: true // Treats this network as if it was a public net. (default: false) - // } + /** + * Networks define how you connect to your ethereum client and let you set + * the defaults web3 uses to send transactions. If you don't specify one + * truffle will spin up a development blockchain for you on port 9545 when + * you run `develop` or `test`. You can ask a truffle command to use a + * specific network from the command line, e.g + * + * $ truffle test --network + */ + + networks: { + // Useful for testing. The `development` name is special - truffle uses + // it by default if it's defined here and no other network is specified + // at the command line. + // + // You should run a client (like ganache-cli, geth or parity) in a + // separate terminal tab if you use this network and you must also set + // the `host`, `port` and `network_id` + // options below to some value. + // + development: { + host: '127.0.0.1', // Localhost (default: none) + port: 8545, // Standard Ethereum port (default: none) + network_id: '*' // Any network (default: none) }, - plugins: [ - "solidity-coverage", - "truffle-plugin-verify" - ], - - api_keys: { - etherscan: process.env.ETHERSCAN_API_KEY + coverage: { + host: '127.0.0.1', // Localhost (default: none) + port: 8555, // Test Coverage Port + network_id: '*' // Any network (default: none) }, - // Set default mocha options here, use special reporters etc. - mocha: { - timeout: 120000 + ropsten: { + provider: () => { + return new HDWalletProvider( + fs.readFileSync(".secret").toString().trim(), + "http://localhost:8545") + }, + network_id: 3, + gas: 8000000 }, - // Configure your compilers - compilers: { - solc: { - version: '0.6.6', // Fetch exact version from solc-bin (default: truffle's version) - // docker: true, // Use "0.5.1" you've installed locally with docker (default: false) - settings: { // See the solidity docs for advice about optimization and evmVersion - optimizer: { - enabled: true, - runs: 200 - }, - // evmVersion: "byzantium" - // } - - }, - - }, + rinkeby: { + provider: () => { + return new HDWalletProvider( + process.env.PK, + `https://rinkeby.infura.io/v3/${process.env.INFURA_API_KEY}` + ) + }, + network_id: 4 } -} -//module.exports = options; // + // Another network with more advanced options... + // advanced: { + // port: 8777, // Custom port + // network_id: 1342, // Custom network + // gas: 8500000, // Gas sent with each transaction + // // (default: ~6700000) + // gasPrice: 20000000000, // 20 gwei (in wei) (default: 100 gwei) + // from:
, // Account to send txs from + // // (default: accounts[0]) + // websockets: true // Enable EventEmitter interface for web3 + // // (default: false) + // }, + + // Useful for deploying to a public network. + // NB: It's important to wrap the provider as a function. + // ropsten: { + // provider: () => { + // return new HDWalletProvider( + // mnemonic, + // `https://ropsten.infura.io/v3/YOUR-PROJECT-ID`) + // }, + // network_id: 3, // Ropsten's id + // gas: 5500000, // Ropsten has a lower block limit than mainnet + // confirmations: 2, // # of confs to wait between deployments. + // // (default: 0) + // timeoutBlocks: 200, // # of blocks before a deployment times out + // // (minimum/default: 50) + // skipDryRun: true // Skip dry run before migrations? + // // (default: false for public nets ) + // }, + + // Useful for private networks + // private: { + // provider: () => new HDWalletProvider(mnemonic, `https://network.io`), + // network_id: 2111, // This network is yours, in the cloud. + // production: true // Treats this network as if it was a public net. + // // (default: false) + // } + }, + + plugins: [ + "solidity-coverage", + "truffle-plugin-verify" + ], + + api_keys: { + etherscan: process.env.ETHERSCAN_API_KEY + }, + + mocha: { + timeout: 120000 + }, + + compilers: { + solc: { + // Fetch exact version from solc-bin (default: truffle's version) + version: '0.6.6', + + // See the solidity docs for advice about optimization and evmVersion + settings: { + optimizer: { + enabled: true, + runs: 200 + } + } + } + } +} From 3f15345b3e64516935af6fb6a2e46eeabbd2e762 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Tue, 19 Jan 2021 20:31:37 +0000 Subject: [PATCH 07/22] Add first pass at local build. --- .envrc | 6 +++++ .ruby-version | 1 + Gemfile | 3 +++ Gemfile.lock | 13 +++++++++++ Rakefile | 8 +++++++ go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 7 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 .envrc create mode 100644 .ruby-version create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Rakefile create mode 100755 go diff --git a/.envrc b/.envrc new file mode 100644 index 00000000..e2afc20d --- /dev/null +++ b/.envrc @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +PROJECT_DIR="$(pwd)" + +PATH_add ${PROJECT_DIR} +PATH_add ${PROJECT_DIR}/node_modules/.bin diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 00000000..fbafd6b6 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.7.2 \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 00000000..a356e4b0 --- /dev/null +++ b/Gemfile @@ -0,0 +1,3 @@ +source 'https://rubygems.org' + +gem 'rake', '~> 13.0' diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 00000000..3bd69323 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,13 @@ +GEM + remote: https://rubygems.org/ + specs: + rake (13.0.3) + +PLATFORMS + x86_64-darwin-19 + +DEPENDENCIES + rake (~> 13.0) + +BUNDLED WITH + 2.2.6 diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..f6c80b11 --- /dev/null +++ b/Rakefile @@ -0,0 +1,8 @@ +task :default => :"contracts:compile" + +namespace :contracts do + desc "Compile all contracts" + task :compile do + sh('npm run compile') + end +end diff --git a/go b/go new file mode 100755 index 00000000..a42c485a --- /dev/null +++ b/go @@ -0,0 +1,61 @@ +#!/usr/bin/env bash + +[ -n "$GO_DEBUG" ] && set -x +set -e + +project_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +verbose="no" +offline="no" +skip_checks="no" + +missing_dependency="no" + +[ -n "$GO_DEBUG" ] && verbose="yes" +[ -n "$GO_SKIP_CHECKS" ] && skip_checks="yes" +[ -n "$GO_OFFLINE" ] && offline="yes" + + +if [[ "$skip_checks" = "no" ]]; then + echo "Checking for system dependencies." + ruby_version="$(cat "$project_dir"/.ruby-version)" + if ! type ruby >/dev/null 2>&1 || ! ruby -v | grep -q "$ruby_version"; then + echo "This codebase requires Ruby $ruby_version." + missing_dependency="yes" + fi + + if ! type bundler >/dev/null 2>&1; then + echo "This codebase requires Bundler." + missing_dependency="yes" + fi + + if [[ "$missing_dependency" = "yes" ]]; then + echo "Please install missing dependencies to continue." + exit 1 + fi + + echo "All system dependencies present. Continuing." +fi + +if [[ "$offline" = "no" ]]; then + echo "Installing bundler." + if [[ "$verbose" = "yes" ]]; then + gem install --no-document bundler + else + gem install --no-document bundler > /dev/null + fi + + echo "Installing ruby dependencies." + if [[ "$verbose" = "yes" ]]; then + bundle install + else + bundle install > /dev/null + fi +fi + +echo "Starting rake." +if [[ "$verbose" = "yes" ]]; then + time bundle exec rake --verbose "$@" +else + time bundle exec rake "$@" +fi diff --git a/package.json b/package.json index eef90f60..2641d9b8 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "test": "test" }, "scripts": { - "compile": "truffle compile", + "compile": "truffle compile --all", "test:unit": "truffle test", "coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage", "migrate-dev": "truffle migrate --network=rinkeby", From dd86ccb2065916b07a2bddf06193f90546925734 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Wed, 20 Jan 2021 00:54:30 +0000 Subject: [PATCH 08/22] Add rake task to run integration tests. --- .gitignore | 5 +- Gemfile | 2 + Gemfile.lock | 4 + Rakefile | 53 ++ migrations/2_deploy_contracts.js | 4 - package.json | 2 +- test/1_test_fullpath.js | 984 ++++++++++++++++++------------- testHelpers/accounts.js | 19 + testHelpers/constants.js | 154 +++-- testHelpers/permitUtils.js | 174 +++--- testHelpers/timemachine.js | 91 ++- testHelpers/utils.js | 957 +++++++++++++++++------------- testHelpers/utilsBuilder.js | 136 +++-- truffle-config.js | 14 +- 14 files changed, 1495 insertions(+), 1104 deletions(-) create mode 100644 testHelpers/accounts.js diff --git a/.gitignore b/.gitignore index a56ca6cb..a595f181 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ node_modules /build .etherlime-store /localDeploy +/run # Secrets .secret @@ -21,8 +22,8 @@ node_modules *.ipr .idea/ -#Test Coverage +# Test Coverage coverage* -#Personal Preferences +# Personal Preferences .vscode \ No newline at end of file diff --git a/Gemfile b/Gemfile index a356e4b0..e5517651 100644 --- a/Gemfile +++ b/Gemfile @@ -1,3 +1,5 @@ source 'https://rubygems.org' gem 'rake', '~> 13.0' +gem 'random-port', '~> 0.5' +gem 'childprocess', '~> 4.0' diff --git a/Gemfile.lock b/Gemfile.lock index 3bd69323..923be140 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,13 +1,17 @@ GEM remote: https://rubygems.org/ specs: + childprocess (4.0.0) rake (13.0.3) + random-port (0.5.1) PLATFORMS x86_64-darwin-19 DEPENDENCIES + childprocess (~> 4.0) rake (~> 13.0) + random-port (~> 0.5) BUNDLED WITH 2.2.6 diff --git a/Rakefile b/Rakefile index f6c80b11..0304c906 100644 --- a/Rakefile +++ b/Rakefile @@ -1,8 +1,61 @@ +require 'random-port' +require 'childprocess' + task :default => :"contracts:compile" +namespace :ganache do + task :start, [:port] do |_, args| + port = args.port.to_s + + puts "Starting ganache on port #{port}..." + process = ChildProcess.build( + './node_modules/.bin/ganache-cli', + '--allowUnlimitedContractSize', + '-p', port) + # process.io.inherit! + process.leader = true + process.detach = true + process.start + + FileUtils.mkdir_p('run/pid') + File.open("run/pid/ganache-#{port}.pid", "w") do |pidfile| + pidfile.write(process.pid) + end + end + + task :stop, [:port] do |_, args| + port = args.port.to_s + + puts "Stopping ganache on port #{port}..." + pid = File.read("run/pid/ganache-#{port}.pid").to_i + + Process.kill('INT', pid) + File.unlink("run/pid/ganache-#{port}.pid") + end +end + namespace :contracts do desc "Compile all contracts" task :compile do sh('npm run compile') end end + +namespace :test do + desc "Run all contract integration tests" + task :integration do + RandomPort::Pool.new.acquire do |port| + begin + Rake::Task[:'ganache:start'].invoke(port) + + puts "Running integration tests against node listening on #{port}..." + sh({ + "HOST" => "127.0.0.1", + "PORT" => "#{port}" + }, 'npm run test:integration') + ensure + Rake::Task[:'ganache:stop'].invoke(port) + end + end + end +end diff --git a/migrations/2_deploy_contracts.js b/migrations/2_deploy_contracts.js index 85b0dd4c..164a21e0 100644 --- a/migrations/2_deploy_contracts.js +++ b/migrations/2_deploy_contracts.js @@ -40,12 +40,8 @@ module.exports = function(deployer, network, accounts) { console.log("Boson Token Deposit Contract Address: ", BosonTokenDeposit.address); }) }) - }); - }) }) }); - - }; diff --git a/package.json b/package.json index 2641d9b8..32ba2c36 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ }, "scripts": { "compile": "truffle compile --all", - "test:unit": "truffle test", + "test:integration": "truffle test --network test", "coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage", "migrate-dev": "truffle migrate --network=rinkeby", "verify-dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby" diff --git a/test/1_test_fullpath.js b/test/1_test_fullpath.js index db61a2b8..5eded716 100644 --- a/test/1_test_fullpath.js +++ b/test/1_test_fullpath.js @@ -1,442 +1,608 @@ -const helpers = require("../testHelpers/constants"); -const timemachine = require('../testHelpers/timemachine'); -const truffleAssert = require('truffle-assertions'); -//later consider using https://github.com/OpenZeppelin/openzeppelin-test-helpers - -const ERC1155ERC721 = artifacts.require("ERC1155ERC721"); -const VoucherKernel = artifacts.require("VoucherKernel"); -const Cashier = artifacts.require("Cashier"); -const FundLimitsOracle = artifacts.require('FundLimitsOracle'); - -const config = require('../testHelpers/config.json') +const truffleAssert = require('truffle-assertions') +// later consider using +// https://github.com/OpenZeppelin/openzeppelin-test-helpers +const constants = require("../testHelpers/constants") +const timemachine = require('../testHelpers/timemachine') const Utils = require('../testHelpers/utils') -let snapshot; - -contract("Voucher tests", async accounts => { - let Seller = config.accounts.seller.address - let Buyer = config.accounts.buyer.address - let Attacker = config.accounts.attacker.address - - let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractFundLimitsOracle; - let promiseKey1, promiseKey2; - let order1payment, order1depositSe, order1depositBu; - let ordersCount; - let tokenSupplyKey1, tokenSupplyKey2, tokenVoucherKey1, tokenVoucherKey2; - - before('setup contracts for tests', async () => { - snapshot = await timemachine.takeSnapshot(); - - const timestamp = await Utils.getCurrTimestamp() - helpers.PROMISE_VALID_FROM = timestamp - helpers.PROMISE_VALID_TO = timestamp + 2 * helpers.SECONDS_IN_DAY; - - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new(); - contractVoucherKernel = await VoucherKernel.new(contractERC1155ERC721.address); - contractCashier = await Cashier.new(contractVoucherKernel.address, contractERC1155ERC721.address, contractFundLimitsOracle.address); - - await contractERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true'); - await contractERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address); - await contractVoucherKernel.setCashierAddress(contractCashier.address); - - console.log("Seller: " + Seller); - console.log("Buyer: " + Buyer); - console.log("Attacker: " + Attacker + "\n"); +const Accounts = require('../testHelpers/accounts') + +const ERC1155ERC721 = artifacts.require("ERC1155ERC721") +const VoucherKernel = artifacts.require("VoucherKernel") +const Cashier = artifacts.require("Cashier") +const FundLimitsOracle = artifacts.require('FundLimitsOracle') + +let snapshot + +contract("Voucher tests", async accountSet => { + const accounts = new Accounts(accountSet) + + let contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractFundLimitsOracle + let tokenSupplyKey1, + tokenSupplyKey2, + tokenVoucherKey1, + tokenVoucherKey2 + + before('setup contracts for tests', async () => { + snapshot = await timemachine.takeSnapshot() + + const timestamp = await Utils.getCurrTimestamp() + constants.PROMISE_VALID_FROM = timestamp + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY + + contractFundLimitsOracle = await FundLimitsOracle.new() + contractERC1155ERC721 = await ERC1155ERC721.new() + contractVoucherKernel = await VoucherKernel.new( + contractERC1155ERC721.address) + contractCashier = await Cashier.new( + contractVoucherKernel.address, + contractERC1155ERC721.address, + contractFundLimitsOracle.address) + + await contractERC1155ERC721.setApprovalForAll( + contractVoucherKernel.address, 'true') + await contractERC1155ERC721.setVoucherKernelAddress( + contractVoucherKernel.address) + await contractVoucherKernel.setCashierAddress( + contractCashier.address) + + console.log("Seller: " + accounts.seller) + console.log("Buyer: " + accounts.buyer) + console.log("Attacker: " + accounts.attacker + "\n") + }) + + describe('Direct minting', function () { + it("must fail: unauthorized minting ERC-1155", async () => { + await truffleAssert.reverts( + contractERC1155ERC721.mint(accounts.attacker, 666, 1, []), + truffleAssert.ErrorType.REVERT + ) }) - - describe('Direct minting', function() { - - it("must fail: unauthorized minting ERC-1155", async () => { - await truffleAssert.reverts(contractERC1155ERC721.mint(Attacker, 666, 1, []), - truffleAssert.ErrorType.REVERT - ); - }); - - it("must fail: unauthorized minting ERC-721", async () => { - await truffleAssert.reverts(contractERC1155ERC721.mint(Attacker, 666), - truffleAssert.ErrorType.REVERT - ); - }); - }) - - -//in the prototype, the creation of a promise is merged into creating an order - // describe('Promises (aka offers)', function() { - - // it("adding one new promise", async () => { - // // console.log("helpers.PROMISE_VALID_FROM: ", helpers.PROMISE_VALID_FROM, ", helpers.PROMISE_VALID_TO: ", helpers.PROMISE_VALID_TO); - // await contractVoucherKernel.createTokenSupplyID(helpers.ASSET_TITLE, helpers.ASSET_PIN1, helpers.ASSET_QR1, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.PROMISE_PRICE1, helpers.PROMISE_DEPOSITSE1, helpers.PROMISE_DEPOSITBU1, helpers.PROMISE_CHALLENGE_PERIOD, helpers.PROMISE_CANCELORFAULT_PERIOD); - - // promiseKey1 = await contractVoucherKernel.promiseKeys.call(0); - - // assert.notEqual(promiseKey1, helpers.ZERO_ADDRESS, "promise not added"); - // }); - - // it("adding second new promise", async () => { - // await contractVoucherKernel.createTokenSupplyID(helpers.ASSET_TITLE2, helpers.ASSET_PIN2, helpers.ASSET_QR2, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.PROMISE_PRICE2, helpers.PROMISE_DEPOSITSE2, helpers.PROMISE_DEPOSITBU2, helpers.PROMISE_CHALLENGE_PERIOD, helpers.PROMISE_CANCELORFAULT_PERIOD); - - // promiseKey2 = await contractVoucherKernel.promiseKeys.call(1); - - // assert.notEqual(promiseKey2, helpers.ZERO_ADDRESS, "second promise not added"); - // }); - - // it("must fail: adding new promise with invalid validity", async () => { - // await truffleAssert.reverts(contractVoucherKernel.createTokenSupplyID(helpers.ASSET_TITLE, helpers.ASSET_PIN1, helpers.ASSET_QR1, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_FROM - 1, helpers.PROMISE_PRICE1, helpers.PROMISE_DEPOSITSE1, helpers.PROMISE_DEPOSITBU1, helpers.PROMISE_CHALLENGE_PERIOD, helpers.PROMISE_CANCELORFAULT_PERIOD), - // truffleAssert.ErrorType.REVERT - // ); - // }); - - // }) - - - describe('Orders (aka supply tokens - ERC1155)', function() { - - it("adding one new order / promise", async () => { - - let txOrder = await contractCashier.requestCreateOrder_ETH_ETH([helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.PROMISE_PRICE1, helpers.PROMISE_DEPOSITSE1, helpers.PROMISE_DEPOSITBU1, helpers.ORDER_QUANTITY1], {from: Seller, to: contractCashier.address, value: helpers.PROMISE_DEPOSITSE1}); - - //would need truffle-events as the event emitted is from a nested contract, so truffle-assert doesn't detect it - // truffleAssert.eventEmitted(txOrder, 'LogOrderCreated', (ev) => { - // tokenSupplyKey = ev._tokenIdSupply; - // return ev._seller === Seller; - // }, "order1 not created successfully"); - - // //instead, we check that the escrow increased for the seller - // let escrowAmount = await contractCashier.getEscrowAmount.call(Seller); - // assert.isAbove(escrowAmount.toNumber(), 0, "seller's escrowed deposit should be more than zero"); - - //move events from VoucherKernel to Cashier: - truffleAssert.eventEmitted(txOrder, 'LogOrderCreated', (ev) => { - tokenSupplyKey1 = ev._tokenIdSupply; - return ev._seller === Seller; - }, "order1 not created successfully"); - - }); - - it("adding second order", async () => { - - let txOrder = await contractCashier.requestCreateOrder_ETH_ETH([helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.PROMISE_PRICE2, helpers.PROMISE_DEPOSITSE2, helpers.PROMISE_DEPOSITBU2, helpers.ORDER_QUANTITY2], {from: Seller, to: contractCashier.address, value: helpers.PROMISE_DEPOSITSE2}); - - truffleAssert.eventEmitted(txOrder, 'LogOrderCreated', (ev) => { - tokenSupplyKey2 = ev._tokenIdSupply; - return ev._seller === Seller; - }, "order2 not created successfully"); - - }); - - - it("fill one order (aka buy a voucher)", async () => { - - let txFillOrder = await contractCashier.requestVoucher_ETH_ETH(tokenSupplyKey1, Seller, {from: Buyer, to: contractCashier.address, value: helpers.PROMISE_PRICE1 + helpers.PROMISE_DEPOSITBU1}); - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - return ev._issuer === Seller; - }, "order1 not created successfully"); - - let filtered = internalTx.logs.filter(e => e.event == 'LogVoucherDelivered')[0] - tokenVoucherKey1 = filtered.returnValues['_tokenIdVoucher'] - }); - - - it("fill second order (aka buy a voucher)", async () => { - - let txFillOrder = await contractCashier.requestVoucher_ETH_ETH(tokenSupplyKey2, Seller, {from: Buyer, to: contractCashier.address, value: helpers.PROMISE_PRICE2 + helpers.PROMISE_DEPOSITBU2}); - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey2 = ev._tokenIdVoucher; - return ev._tokenIdSupply.toString() === tokenSupplyKey2.toString(); - }, "order1 not filled successfully"); - }); - - //in prototype, everyone can create an order - // it("must fail: unauthorized adding of new order", async () => { - - // await truffleAssert.reverts(contractCashier.requestCreateOrder_ETH_ETH(promiseKey1, helpers.ORDER_QUANTITY1, {from: Attacker, to: contractCashier.address, value: helpers.PROMISE_DEPOSITSE1}), - // truffleAssert.ErrorType.REVERT - // ); - - // }); - - - it("must fail: adding new order with incorrect value sent", async () => { - - await truffleAssert.reverts(contractCashier.requestCreateOrder_ETH_ETH([helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.PROMISE_PRICE1, helpers.PROMISE_DEPOSITSE1, helpers.PROMISE_DEPOSITBU1, helpers.ORDER_QUANTITY1], {from: Seller, to: contractCashier.address, value: 0}), - truffleAssert.ErrorType.REVERT - ); - - }); - - it("must fail: fill an order with incorrect value", async () => { - - await truffleAssert.reverts(contractCashier.requestVoucher_ETH_ETH(tokenSupplyKey1, Seller, {from: Buyer, to: contractCashier.address, value: 0}), - truffleAssert.ErrorType.REVERT - ); - - }); - - }) - - describe('Voucher tokens', function() { - - it("redeeming one voucher", async () => { - let txRedeem = await contractVoucherKernel.redeem(tokenVoucherKey1, {from: Buyer}); - - truffleAssert.eventEmitted(txRedeem, 'LogVoucherRedeemed', (ev) => { - return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString(); - }, "voucher not redeemed successfully"); - }); - - - it("mark non-redeemed voucher as expired", async () => { - let statusBefore = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey2); //[1000.0000] = hex"80" = 128 = COMMITTED - assert.equal(web3.utils.toHex(statusBefore[0]), web3.utils.numberToHex(128), "initial voucher status not as expected (COMMITTED)"); - - await timemachine.advanceTimeSeconds(helpers.SECONDS_IN_DAY*365); //fast-forward for a year - await contractVoucherKernel.triggerExpiration(tokenVoucherKey2); - - let statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey2); //[1001.0000] = hex"90" = 144 = EXPIRED - assert.equal(web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(144), "end voucher status not as expected (EXPIRED)"); - }); - - - it("mark voucher as finalized", async () => { - let txFinalize = await contractVoucherKernel.triggerFinalizeVoucher(tokenVoucherKey1, {from: Buyer}); - - truffleAssert.eventEmitted(txFinalize, 'LogFinalizeVoucher', (ev) => { - return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString(); - }, "voucher not finalized successfully"); - }); - - - it("must fail: unauthorized redemption", async () => { - await truffleAssert.reverts(contractVoucherKernel.redeem(tokenVoucherKey1, {from: Attacker}), - truffleAssert.ErrorType.REVERT - ); - }); - - }) - - - describe('Withdrawals', function() { - - it("withdraw the escrowed payment from one redeemed voucher", async () => { - let escrowedBefore = await contractCashier.getEscrowAmount.call(Buyer); - - await contractCashier.withdraw(tokenVoucherKey1); - - let escrowedAfter = await contractCashier.getEscrowAmount.call(Buyer); - - assert.isBelow(escrowedAfter.toNumber(), escrowedBefore.toNumber(), "escrowed amount not decreased"); - }); - - - // it("must fail: unauthorized withdrawal of escrowed pool", async () => { - // await truffleAssert.reverts(contractCashier.withdrawPool({from: Attacker}), - // truffleAssert.ErrorType.REVERT - // ); - // }); - - }) - - - - after(async () => { - await timemachine.revertToSnapShot(snapshot.id) - }) - -}); - - - - - - -contract("Voucher tests - UNHAPPY PATH", async accounts => { - - let Seller = accounts[0]; - let Buyer = accounts[1]; - let Attacker = accounts[2]; - - let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractFundLimitsOracle; - let promiseKey1, promiseKey2; - let order1payment, order1depositSe, order1depositBu; - let ordersCount; - let tokenSupplyKey1, tokenSupplyKey2, tokenVoucherKey1, tokenVoucherKey2; - - before('setup promise dates based on the block timestamp', async () => { - snapshot = await timemachine.takeSnapshot(); - - const timestamp = await Utils.getCurrTimestamp() - - helpers.PROMISE_VALID_FROM = timestamp - helpers.PROMISE_VALID_TO = timestamp + 2 * helpers.SECONDS_IN_DAY; - }) - - beforeEach('setup contracts for tests', async () => { - - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new(); - contractVoucherKernel = await VoucherKernel.new(contractERC1155ERC721.address); - contractCashier = await Cashier.new(contractVoucherKernel.address, contractERC1155ERC721.address, contractFundLimitsOracle.address); - - await contractERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true'); - await contractERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address); - await contractVoucherKernel.setCashierAddress(contractCashier.address); - - - //INIT - // await contractVoucherKernel.createTokenSupplyID(helpers.ASSET_TITLE, helpers.ASSET_PIN1, helpers.ASSET_QR1, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.PROMISE_PRICE1, helpers.PROMISE_DEPOSITSE1, helpers.PROMISE_DEPOSITBU1, helpers.PROMISE_CHALLENGE_PERIOD * helpers.SECONDS_IN_DAY, helpers.PROMISE_CANCELORFAULT_PERIOD * helpers.SECONDS_IN_DAY); - - // promiseKey1 = await contractVoucherKernel.promiseKeys.call(0); - - // assert.notEqual(promiseKey1, helpers.ZERO_ADDRESS, "promise not added"); - - let txOrder = await contractCashier.requestCreateOrder_ETH_ETH( [helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.PROMISE_PRICE1, helpers.PROMISE_DEPOSITSE1, helpers.PROMISE_DEPOSITBU1, helpers.ORDER_QUANTITY1], {from: Seller, to: contractCashier.address, value: helpers.PROMISE_DEPOSITSE1}); - - truffleAssert.eventEmitted(txOrder, 'LogOrderCreated', (ev) => { - tokenSupplyKey1 = ev._tokenIdSupply; - return ev._seller === Seller; - }, "order1 not created successfully"); - - let txFillOrder = await contractCashier.requestVoucher_ETH_ETH(tokenSupplyKey1, Seller, {from: Buyer, to: contractCashier.address, value: helpers.PROMISE_PRICE1 + helpers.PROMISE_DEPOSITBU1}); - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey1 = ev._tokenIdVoucher - return ev._issuer === Seller; - }, "order1 not created successfully"); - - //\INIT + it("must fail: unauthorized minting ERC-721", async () => { + await truffleAssert.reverts( + contractERC1155ERC721.mint(accounts.attacker, 666), + truffleAssert.ErrorType.REVERT + ) }) + }) + + describe('Orders (aka supply tokens - ERC1155)', () => { + it("adding one new order / promise", async () => { + const txOrder = await contractCashier + .requestCreateOrder_ETH_ETH([ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.PROMISE_DEPOSITSE1, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: accounts.buyer, + to: contractCashier.address, + value: constants.PROMISE_DEPOSITSE1 + }) + + // // would need truffle-events as the event emitted is from a nested + // // contract, so truffle-assert doesn't detect it + // truffleAssert.eventEmitted(txOrder, 'LogOrderCreated', (ev) => { + // tokenSupplyKey = ev._tokenIdSupply; + // return ev._seller === Seller; + // }, "order1 not created successfully"); + + // // instead, we check that the escrow increased for the seller + // let escrowAmount = await contractCashier.getEscrowAmount.call(Seller); + // assert.isAbove(escrowAmount.toNumber(), 0, + // "seller's escrowed deposit should be more than zero"); + + // move events from VoucherKernel to Cashier: + truffleAssert.eventEmitted( + txOrder, + 'LogOrderCreated', + (ev) => { + tokenSupplyKey1 = ev._tokenIdSupply + return ev._seller === accounts.buyer + }, "order1 not created successfully") + }) - describe('Wait periods', function() { - it("change complain period", async () => { - let txChangePeriod = await contractVoucherKernel.setComplainPeriod(helpers.PROMISE_CHALLENGE_PERIOD * helpers.SECONDS_IN_DAY); - - truffleAssert.eventEmitted(txChangePeriod, 'LogComplainPeriodChanged', (ev) => { - return ev._newComplainPeriod.toString() === (helpers.PROMISE_CHALLENGE_PERIOD * helpers.SECONDS_IN_DAY).toString(); - }, "complain period not changed successfully"); - }); - - - it("must fail: unauthorized change of complain period", async () => { - await truffleAssert.reverts(contractVoucherKernel.setComplainPeriod(helpers.PROMISE_CHALLENGE_PERIOD * helpers.SECONDS_IN_DAY, {from: Attacker}), - truffleAssert.ErrorType.REVERT - ); - }); - - - it("change cancelOrFault period", async () => { - let txChangePeriod = await contractVoucherKernel.setCancelFaultPeriod(helpers.PROMISE_CANCELORFAULT_PERIOD * helpers.SECONDS_IN_DAY); - - await truffleAssert.eventEmitted(txChangePeriod, 'LogCancelFaultPeriodChanged', (ev) => { - return ev._newCancelFaultPeriod.toString() === (helpers.PROMISE_CANCELORFAULT_PERIOD * helpers.SECONDS_IN_DAY).toString(); - }, "complain period not changed successfully"); - }); - - - it("must fail: unauthorized change of cancelOrFault period", async () => { - await truffleAssert.reverts(contractVoucherKernel.setCancelFaultPeriod(helpers.PROMISE_CANCELORFAULT_PERIOD * helpers.SECONDS_IN_DAY, {from: Attacker}), - truffleAssert.ErrorType.REVERT - ); - }); - - }) - - - describe('Refunds ...', function() { - - it("refunding one voucher", async () => { - let txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, {from: Buyer}); - - let statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey1); //[1010.0000] = hex"A0" = 160 = REFUND - assert.equal(web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(160), "end voucher status not as expected (REFUNDED)"); - }); + it("adding second order", async () => { + const txOrder = await contractCashier + .requestCreateOrder_ETH_ETH([ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE2, + constants.PROMISE_DEPOSITSE2, + constants.PROMISE_DEPOSITBU2, + constants.ORDER_QUANTITY2 + ], { + from: accounts.buyer, + to: contractCashier.address, + value: constants.PROMISE_DEPOSITSE2 + }) + + truffleAssert.eventEmitted( + txOrder, + 'LogOrderCreated', + (ev) => { + tokenSupplyKey2 = ev._tokenIdSupply + return ev._seller === accounts.buyer + }, "order2 not created successfully") + }) + it("fill one order (aka buy a voucher)", async () => { + const txFillOrder = await contractCashier + .requestVoucher_ETH_ETH( + tokenSupplyKey1, + accounts.buyer, { + from: accounts.buyer, + to: contractCashier.address, + value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1 + }) + const internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + return ev._issuer === accounts.buyer + }, "order1 not created successfully") + + const filtered = internalTx.logs + .filter(e => e.event === 'LogVoucherDelivered')[0] + + tokenVoucherKey1 = filtered.returnValues['_tokenIdVoucher'] + }) - it("refunding one voucher, then complain", async () => { - let txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, {from: Buyer}); - let txComplain = await contractVoucherKernel.complain(tokenVoucherKey1, {from: Buyer}); + it("fill second order (aka buy a voucher)", async () => { + const txFillOrder = await contractCashier + .requestVoucher_ETH_ETH( + tokenSupplyKey2, + accounts.buyer, { + from: accounts.buyer, + to: contractCashier.address, + value: constants.PROMISE_PRICE2 + constants.PROMISE_DEPOSITBU2 + }) + const internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey2 = ev._tokenIdVoucher + return ev._tokenIdSupply.toString() === tokenSupplyKey2.toString() + }, "order1 not filled successfully") + }) - let statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey1); //[1010.1000] = hex"A8" = 168 = REFUND_COMPLAIN - assert.equal(web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(168), "end voucher status not as expected (REFUNDED_COMPLAINED)"); - }); + it("must fail: adding new order with incorrect value sent", + async () => { + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_ETH([ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.PROMISE_DEPOSITSE1, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: accounts.buyer, + to: contractCashier.address, + value: 0 + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("must fail: fill an order with incorrect value", async () => { + await truffleAssert.reverts( + contractCashier.requestVoucher_ETH_ETH( + tokenSupplyKey1, + accounts.buyer, { + from: accounts.buyer, + to: contractCashier.address, + value: 0 + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe('Voucher tokens', function () { + it("redeeming one voucher", async () => { + const txRedeem = await contractVoucherKernel + .redeem(tokenVoucherKey1, { from: accounts.buyer }) + + truffleAssert.eventEmitted( + txRedeem, + 'LogVoucherRedeemed', + (ev) => { + return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString() + }, "voucher not redeemed successfully") + }) + it("mark non-redeemed voucher as expired", async () => { + const statusBefore = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey2) + + // [1000.0000] = hex"80" = 128 = COMMITTED + assert.equal( + web3.utils.toHex(statusBefore[0]), + web3.utils.numberToHex(128), + "initial voucher status not as expected (COMMITTED)") + + // fast-forward for a year + await timemachine.advanceTimeSeconds( + constants.SECONDS_IN_DAY * 365) + await contractVoucherKernel.triggerExpiration(tokenVoucherKey2) + + const statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey2) + + //[1001.0000] = hex"90" = 144 = EXPIRED + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(144), + "end voucher status not as expected (EXPIRED)") + }) - it("refunding one voucher, then complain, then cancel/fault", async () => { - let txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, {from: Buyer}); - let txComplain = await contractVoucherKernel.complain(tokenVoucherKey1, {from: Buyer}); - let txCoF = await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, {from: Seller}); + it("mark voucher as finalized", async () => { + const txFinalize = await contractVoucherKernel + .triggerFinalizeVoucher(tokenVoucherKey1, { from: accounts.buyer }) - let statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey1); //[1010.1100] = hex"AC" = 172 = REFUND_COMPLAIN_COF - assert.equal(web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(172), "end voucher status not as expected (REFUNDED_COMPLAINED_CANCELORFAULT)"); - }); + truffleAssert.eventEmitted( + txFinalize, + 'LogFinalizeVoucher', + (ev) => { + return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString() + }, "voucher not finalized successfully") + }) + it("must fail: unauthorized redemption", async () => { + await truffleAssert.reverts( + contractVoucherKernel.redeem( + tokenVoucherKey1, { from: accounts.attacker }), + truffleAssert.ErrorType.REVERT + ) + }) + }) - it("must fail: refund then try to redeem", async () => { - let txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, {from: Buyer}); + describe('Withdrawals', function () { + it("withdraw the escrowed payment from one redeemed voucher", + async () => { + const escrowedBefore = await contractCashier + .getEscrowAmount.call(accounts.buyer) - await truffleAssert.reverts(contractVoucherKernel.redeem(tokenVoucherKey1, {from: Buyer}), - truffleAssert.ErrorType.REVERT - ); - }); + await contractCashier.withdraw(tokenVoucherKey1) - }) + const escrowedAfter = await contractCashier + .getEscrowAmount.call(accounts.buyer) + assert.isBelow( + escrowedAfter.toNumber(), + escrowedBefore.toNumber(), + "escrowed amount not decreased") + }) - describe('Cancel/Fault by the seller ...', function() { + // it("must fail: unauthorized withdrawal of escrowed pool", async () => { + // await truffleAssert.reverts( + // contractCashier.withdrawPool({from: Attacker}), + // truffleAssert.ErrorType.REVERT + // ); + // }); - it("canceling one voucher", async () => { - let txCoF = await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, {from: Seller}); + }) - let statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey1); //[1000.0100] = hex"84" = 132 = CANCELORFAULT - assert.equal(web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(132), "end voucher status not as expected (CANCELORFAULT)"); - }); + after(async () => { + await timemachine.revertToSnapShot(snapshot.id) + }) +}) +contract("Voucher tests - UNHAPPY PATH", async accountSet => { + const accounts = new Accounts(accountSet) - it("must fail: cancel/fault then try to redeem", async () => { - let txCoF = await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, {from: Seller}); + let contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractFundLimitsOracle + let tokenSupplyKey1, + tokenVoucherKey1 - await truffleAssert.reverts(contractVoucherKernel.redeem(tokenVoucherKey1, {from: Buyer}), - truffleAssert.ErrorType.REVERT - ); - }); + before('setup promise dates based on the block timestamp', + async () => { + snapshot = await timemachine.takeSnapshot() - }) + const timestamp = await Utils.getCurrTimestamp() + constants.PROMISE_VALID_FROM = timestamp + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY + }) - describe('Expirations (one universal test) ...', function() { + beforeEach('setup contracts for tests', async () => { + contractFundLimitsOracle = await FundLimitsOracle.new() + contractERC1155ERC721 = await ERC1155ERC721.new() + contractVoucherKernel = await VoucherKernel.new( + contractERC1155ERC721.address) + contractCashier = await Cashier.new( + contractVoucherKernel.address, + contractERC1155ERC721.address, + contractFundLimitsOracle.address) + + await contractERC1155ERC721.setApprovalForAll( + contractVoucherKernel.address, 'true') + await contractERC1155ERC721.setVoucherKernelAddress( + contractVoucherKernel.address) + await contractVoucherKernel.setCashierAddress( + contractCashier.address) + + const txOrder = await contractCashier + .requestCreateOrder_ETH_ETH([ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.PROMISE_DEPOSITSE1, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: accounts.seller, + to: contractCashier.address, + value: constants.PROMISE_DEPOSITSE1 + }) + + truffleAssert.eventEmitted( + txOrder, + 'LogOrderCreated', + (ev) => { + tokenSupplyKey1 = ev._tokenIdSupply + return ev._seller === accounts.seller + }, "order1 not created successfully") + + const txFillOrder = await contractCashier + .requestVoucher_ETH_ETH( + tokenSupplyKey1, + accounts.seller, + { + from: accounts.buyer, + to: contractCashier.address, + value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1 + }) + const internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey1 = ev._tokenIdVoucher + return ev._issuer === accounts.seller + }, "order1 not created successfully") + }) + + describe('Wait periods', () => { + it("change complain period", async () => { + const complainPeriodSeconds = + constants.PROMISE_CHALLENGE_PERIOD * constants.SECONDS_IN_DAY + + const txChangePeriod = await contractVoucherKernel + .setComplainPeriod(complainPeriodSeconds) + + truffleAssert.eventEmitted( + txChangePeriod, + 'LogComplainPeriodChanged', + (ev) => { + return ev._newComplainPeriod.toString() === + complainPeriodSeconds.toString() + }, "complain period not changed successfully") + }) - it("Expired, then complain, then Cancel/Fault, then try to redeem", async () => { - await timemachine.advanceTimeSeconds(helpers.SECONDS_IN_DAY*3); //fast-forward for three days - await contractVoucherKernel.triggerExpiration(tokenVoucherKey1); + it("must fail: unauthorized change of complain period", + async () => { + const complainPeriodSeconds = + constants.PROMISE_CHALLENGE_PERIOD * constants.SECONDS_IN_DAY + + await truffleAssert.reverts( + contractVoucherKernel.setComplainPeriod( + complainPeriodSeconds, { from: accounts.attacker }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("change cancelOrFault period", async () => { + const cancelFaultPeriodSeconds = + constants.PROMISE_CANCELORFAULT_PERIOD * constants.SECONDS_IN_DAY + const txChangePeriod = await contractVoucherKernel + .setCancelFaultPeriod(cancelFaultPeriodSeconds) + + await truffleAssert.eventEmitted( + txChangePeriod, + 'LogCancelFaultPeriodChanged', + (ev) => { + return ev._newCancelFaultPeriod.toString() === + cancelFaultPeriodSeconds.toString() + }, "complain period not changed successfully") + }) - let statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey1); //[1001.0000] = hex"90" = 144 = EXPIRED - let txComplain = await contractVoucherKernel.complain(tokenVoucherKey1, {from: Buyer}); + it("must fail: unauthorized change of cancelOrFault period", + async () => { + const cancelFaultPeriodSeconds = + constants.PROMISE_CANCELORFAULT_PERIOD * constants.SECONDS_IN_DAY + await truffleAssert.reverts( + contractVoucherKernel.setCancelFaultPeriod( + cancelFaultPeriodSeconds, { from: accounts.attacker }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe('Refunds ...', function () { + it("refunding one voucher", async () => { + const txRefund = await contractVoucherKernel.refund( + tokenVoucherKey1, { + from: accounts.buyer + }) + + const statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey1) + + // [1010.0000] = hex"A0" = 160 = REFUND + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(160), + "end voucher status not as expected (REFUNDED)") + }) - statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey1); //[1001.1000] = hex"98" = 152 = EXPIRED_COMPLAIN - assert.equal(web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(152), "end voucher status not as expected (EXPIRED_COMPLAINED)"); + it("refunding one voucher, then complain", async () => { + const txRefund = await contractVoucherKernel.refund( + tokenVoucherKey1, { + from: accounts.buyer + }) + const txComplain = await contractVoucherKernel.complain( + tokenVoucherKey1, { + from: accounts.buyer + }) + + const statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey1) + + // [1010.1000] = hex"A8" = 168 = REFUND_COMPLAIN + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(168), + "end voucher status not as expected (REFUNDED_COMPLAINED)") + }) - //in the same test, because the EVM time machine is funky ... - let txCoF = await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, {from: Seller}); - statusAfter = await contractVoucherKernel.getVoucherStatus.call(tokenVoucherKey1); //[1001.1000] = hex"9C" = 156 = EXPIRED_COMPLAINED_CANCELORFAULT - assert.equal(web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(156), "end voucher status not as expected (EXPIRED_COMPLAINED_CANCELORFAULT)"); + it("refunding one voucher, then complain, then cancel/fault", + async () => { + const txRefund = await contractVoucherKernel.refund( + tokenVoucherKey1, { + from: accounts.buyer + }) + const txComplain = await contractVoucherKernel.complain( + tokenVoucherKey1, { + from: accounts.buyer + }) + const txCoF = await contractVoucherKernel.cancelOrFault( + tokenVoucherKey1, { + from: accounts.seller + }) + + const statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey1) + + // [1010.1100] = hex"AC" = 172 = REFUND_COMPLAIN_COF + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(172), + "end voucher status not as expected " + + "(REFUNDED_COMPLAINED_CANCELORFAULT)") + }) + + it("must fail: refund then try to redeem", async () => { + const txRefund = await contractVoucherKernel.refund( + tokenVoucherKey1, { + from: accounts.buyer + }) + + await truffleAssert.reverts( + contractVoucherKernel.redeem( + tokenVoucherKey1, { from: accounts.buyer }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe('Cancel/Fault by the seller ...', () => { + it("canceling one voucher", async () => { + const txCoF = await contractVoucherKernel + .cancelOrFault( + tokenVoucherKey1, { + from: accounts.seller + }) + + const statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey1) + + // [1000.0100] = hex"84" = 132 = CANCELORFAULT + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(132), + "end voucher status not as expected (CANCELORFAULT)") + }) - //in the same test, because the EVM time machine is funky ... - await truffleAssert.reverts(contractVoucherKernel.redeem(tokenVoucherKey1, {from: Buyer}), - truffleAssert.ErrorType.REVERT - ); - }); - - after(async () => { - await timemachine.revertToSnapShot(snapshot.id) - }) + it("must fail: cancel/fault then try to redeem", async () => { + const txCoF = await contractVoucherKernel + .cancelOrFault( + tokenVoucherKey1, { + from: accounts.seller + }) + + await truffleAssert.reverts( + contractVoucherKernel.redeem( + tokenVoucherKey1, { from: accounts.buyer }), + truffleAssert.ErrorType.REVERT + ) + }) - }) - -}); \ No newline at end of file + }) + + describe('Expirations (one universal test) ...', () => { + it("Expired, then complain, then Cancel/Fault, then try to redeem", + async () => { + // fast-forward for three days + const secondsInThreeDays = constants.SECONDS_IN_DAY * 3 + await timemachine.advanceTimeSeconds(secondsInThreeDays) + + await contractVoucherKernel.triggerExpiration(tokenVoucherKey1) + + let statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey1) + + // [1001.0000] = hex"90" = 144 = EXPIRED + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(144), + "end voucher status not as expected (EXPIRED)") + + const txComplain = await contractVoucherKernel + .complain(tokenVoucherKey1, { from: accounts.buyer }) + + statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey1) + + // [1001.1000] = hex"98" = 152 = EXPIRED_COMPLAIN + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(152), + "end voucher status not as expected (EXPIRED_COMPLAINED)") + + // in the same test, because the EVM time machine is funky ... + const txCoF = await contractVoucherKernel + .cancelOrFault(tokenVoucherKey1, { from: accounts.seller }) + + statusAfter = await contractVoucherKernel + .getVoucherStatus.call(tokenVoucherKey1) + + // [1001.1000] = hex"9C" = 156 = EXPIRED_COMPLAINED_CANCELORFAULT + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(156), + "end voucher status not as expected " + + "(EXPIRED_COMPLAINED_CANCELORFAULT)") + + // in the same test, because the EVM time machine is funky ... + await truffleAssert.reverts( + contractVoucherKernel.redeem( + tokenVoucherKey1, { from: accounts.buyer }), + truffleAssert.ErrorType.REVERT + ) + }) + + after(async () => { + await timemachine.revertToSnapShot(snapshot.id) + }) + }) +}) diff --git a/testHelpers/accounts.js b/testHelpers/accounts.js new file mode 100644 index 00000000..d7801d23 --- /dev/null +++ b/testHelpers/accounts.js @@ -0,0 +1,19 @@ +class Accounts { + constructor(accountSet) { + this.accountSet = accountSet + } + + get seller() { + return this.accountSet[1] + } + + get buyer() { + return this.accountSet[2] + } + + get attacker() { + return this.accountSet[3] + } +} + +module.exports = Accounts diff --git a/testHelpers/constants.js b/testHelpers/constants.js index c51c8cf2..9a94a92c 100644 --- a/testHelpers/constants.js +++ b/testHelpers/constants.js @@ -1,90 +1,88 @@ -//common -const SECONDS_IN_DAY = 86400; -const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000"; +// common +const SECONDS_IN_DAY = 86400 +const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" -//asset -const ASSET_VERSION = "0x3132"; -const ASSET_TITLE = "Dragon wizard hat"; -const ASSET_TITLE2 = "T-shirt dragons"; -const ASSET_TITLE3 = "T-shirt goblins"; -const ASSET_PIN1 = "I3DESK"; -const ASSET_PIN2 = "QBSOS"; -const ASSET_QR1 = "XYZ12"; -const ASSET_QR2 = "QWY43"; -const ASSET_DESCRIPTION = "mighty wizard hat, universal size"; -const CATEGORY1 = "entertainment.games.swag"; -const CATEGORY2 = "entertainment.games.shield"; +// asset +const ASSET_VERSION = "0x3132" +const ASSET_TITLE = "Dragon wizard hat" +const ASSET_TITLE2 = "T-shirt dragons" +const ASSET_TITLE3 = "T-shirt goblins" +const ASSET_PIN1 = "I3DESK" +const ASSET_PIN2 = "QBSOS" +const ASSET_QR1 = "XYZ12" +const ASSET_QR2 = "QWY43" +const ASSET_DESCRIPTION = "mighty wizard hat, universal size" +const CATEGORY1 = "entertainment.games.swag" +const CATEGORY2 = "entertainment.games.shield" -//promise -const PROMISE_VALID_FROM = ''; // evaluated based on the current block timestamp -const PROMISE_VALID_TO = ''; // evaluated based on the PROMISE_VALID_FROM + 2 * SECONDS_IN_DAY -const PROMISE_PRICE1 = 10; -const PROMISE_PRICE2 = 21; -const PROMISE_DEPOSITSE1 = 1; -const PROMISE_DEPOSITSE2 = 5; -const PROMISE_DEPOSITBU1 = 1; -const PROMISE_DEPOSITBU2 = 2; -const PROMISE_CHALLENGE_PERIOD = 8; -const PROMISE_CANCELORFAULT_PERIOD = 8; +// promise +const PROMISE_VALID_FROM = '' // evaluated based on the current block timestamp +const PROMISE_VALID_TO = '' // evaluated based on the PROMISE_VALID_FROM + 2 * SECONDS_IN_DAY +const PROMISE_PRICE1 = 10 +const PROMISE_PRICE2 = 21 +const PROMISE_DEPOSITSE1 = 1 +const PROMISE_DEPOSITSE2 = 5 +const PROMISE_DEPOSITBU1 = 1 +const PROMISE_DEPOSITBU2 = 2 +const PROMISE_CHALLENGE_PERIOD = 8 +const PROMISE_CANCELORFAULT_PERIOD = 8 -//order -const ORDER_QUANTITY1 = 1; -const ORDER_QUANTITY2 = 1; +// order +const ORDER_QUANTITY1 = 1 +const ORDER_QUANTITY2 = 1 - -const buyer_deposit = '40000000000000000'; // 0.04 -const buyer_incorrect_deposit = '4000000000000000'; // 0.004 -const seller_deposit = '50000000000000000'; // 0.05 -const product_price = '300000000000000000'; // 0.3 -const incorrect_product_price = '30000000000000000'; // 0.03 +const buyer_deposit = '40000000000000000' // 0.04 +const buyer_incorrect_deposit = '4000000000000000' // 0.004 +const seller_deposit = '50000000000000000' // 0.05 +const product_price = '300000000000000000' // 0.3 +const incorrect_product_price = '30000000000000000' // 0.03 const QTY_10 = 10 const QTY_20 = 20 const QTY_1 = 1 -//fund limits -const ETHER_LIMIT = (5 * 10 ** 18).toString(); -const ABOVE_ETH_LIMIT = (10 * 10 ** 18).toString(); +// fund limits +const ETHER_LIMIT = (5 * 10 ** 18).toString() +const ABOVE_ETH_LIMIT = (10 * 10 ** 18).toString() -const TOKEN_LIMIT = (5 * 10 ** 18).toString(); -const ABOVE_TOKEN_LIMIT = (10 * 10 ** 18).toString(); +const TOKEN_LIMIT = (5 * 10 ** 18).toString() +const ABOVE_TOKEN_LIMIT = (10 * 10 ** 18).toString() module.exports = { - ASSET_VERSION, - ASSET_TITLE, - ASSET_TITLE2, - ASSET_TITLE3, - ASSET_PIN1, - ASSET_PIN2, - ASSET_QR1, - ASSET_QR2, - ASSET_DESCRIPTION, - CATEGORY1, - CATEGORY2, - PROMISE_VALID_FROM, - PROMISE_VALID_TO, - PROMISE_PRICE1, - PROMISE_PRICE2, - PROMISE_DEPOSITSE1, - PROMISE_DEPOSITSE2, - PROMISE_DEPOSITBU1, - PROMISE_DEPOSITBU2, - PROMISE_CHALLENGE_PERIOD, - PROMISE_CANCELORFAULT_PERIOD, - ORDER_QUANTITY1, - ORDER_QUANTITY2, - SECONDS_IN_DAY, - ZERO_ADDRESS, - buyer_deposit, - buyer_incorrect_deposit, - seller_deposit, - product_price, - incorrect_product_price, - QTY_1, - QTY_10, - QTY_1, - QTY_20, - ETHER_LIMIT, - ABOVE_ETH_LIMIT, - TOKEN_LIMIT, - ABOVE_TOKEN_LIMIT + ASSET_VERSION, + ASSET_TITLE, + ASSET_TITLE2, + ASSET_TITLE3, + ASSET_PIN1, + ASSET_PIN2, + ASSET_QR1, + ASSET_QR2, + ASSET_DESCRIPTION, + CATEGORY1, + CATEGORY2, + PROMISE_VALID_FROM, + PROMISE_VALID_TO, + PROMISE_PRICE1, + PROMISE_PRICE2, + PROMISE_DEPOSITSE1, + PROMISE_DEPOSITSE2, + PROMISE_DEPOSITBU1, + PROMISE_DEPOSITBU2, + PROMISE_CHALLENGE_PERIOD, + PROMISE_CANCELORFAULT_PERIOD, + ORDER_QUANTITY1, + ORDER_QUANTITY2, + SECONDS_IN_DAY, + ZERO_ADDRESS, + buyer_deposit, + buyer_incorrect_deposit, + seller_deposit, + product_price, + incorrect_product_price, + QTY_1, + QTY_10, + QTY_20, + ETHER_LIMIT, + ABOVE_ETH_LIMIT, + TOKEN_LIMIT, + ABOVE_TOKEN_LIMIT } \ No newline at end of file diff --git a/testHelpers/permitUtils.js b/testHelpers/permitUtils.js index 448c747f..8d89b745 100644 --- a/testHelpers/permitUtils.js +++ b/testHelpers/permitUtils.js @@ -1,106 +1,128 @@ - const { - hexlify, - getAddress, - keccak256, - defaultAbiCoder, - toUtf8Bytes, - solidityPack, - AbiCoder, - Interface, -} = require('ethers').utils; - + keccak256, + defaultAbiCoder, + toUtf8Bytes, + solidityPack, + AbiCoder, + Interface +} = require('ethers').utils const PERMIT_TYPEHASH = keccak256( - toUtf8Bytes('Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)') -); + toUtf8Bytes( + 'Permit(' + + 'address owner,' + + 'address spender,' + + 'uint256 value,' + + 'uint256 nonce,' + + 'uint256 deadline)') +) const toWei = (value) => { - return value + '0'.repeat(18); -}; + return value + '0'.repeat(18) +} -async function getApprovalDigest( - token, - owner, - spender, - value, - nonce, - deadline +async function getApprovalDigest ( + token, + owner, + spender, + value, + nonce, + deadline ) { - const name = await token.name(); - const DOMAIN_SEPARATOR = getDomainSeparator(name, token.address); - - return keccak256( - solidityPack( - ['bytes1', 'bytes1', 'bytes32', 'bytes32'], + const name = await token.name() + const DOMAIN_SEPARATOR = getDomainSeparator(name, token.address) + + return keccak256( + solidityPack( + [ 'bytes1', 'bytes1', 'bytes32', 'bytes32' ], + [ + '0x19', + '0x01', + DOMAIN_SEPARATOR, + keccak256( + defaultAbiCoder.encode( + [ + 'bytes32', + 'address', + 'address', + 'uint256', + 'uint256', + 'uint256' + ], [ - '0x19', - '0x01', - DOMAIN_SEPARATOR, - keccak256( - defaultAbiCoder.encode( - ['bytes32', 'address', 'address', 'uint256', 'uint256', 'uint256'], - [PERMIT_TYPEHASH, owner, spender, value.toString(), nonce.toString(), deadline] - ) - ) + PERMIT_TYPEHASH, + owner, + spender, + value.toString(), + nonce.toString(), + deadline ] + ) ) + ] ) + ) } -function getDomainSeparator(name, tokenAddress) { - return keccak256( - defaultAbiCoder.encode( - ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'], - [ - keccak256(toUtf8Bytes('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)')), - keccak256(toUtf8Bytes(name)), - keccak256(toUtf8Bytes('1')), - 1, - tokenAddress - ] - ) +function getDomainSeparator (name, tokenAddress) { + return keccak256( + defaultAbiCoder.encode( + [ 'bytes32', 'bytes32', 'bytes32', 'uint256', 'address' ], + [ + keccak256(toUtf8Bytes( + 'EIP712Domain(' + + 'string name,' + + 'string version,' + + 'uint256 chainId,' + + 'address verifyingContract)')), + keccak256(toUtf8Bytes(name)), + keccak256(toUtf8Bytes('1')), + 1, + tokenAddress + ] ) + ) } -async function getEncodedTopic(receipt, abi, eventName) { - const interface = new Interface(abi) - for (const log in receipt.logs) { - const topics = receipt.logs[log].topics; - for (const index in topics) { +async function getEncodedTopic (receipt, abi, eventName) { + const interface = new Interface(abi) + for (const log in receipt.logs) { + const topics = receipt.logs[log].topics + for (const index in topics) { - const encodedTopic = topics[index]; + const encodedTopic = topics[index] - try { - // CHECK IF TOPIC CORRESPONDS TO THE EVENT GIVEN TO FN - let event = await interface.getEvent(encodedTopic); + try { + // CHECK IF TOPIC CORRESPONDS TO THE EVENT GIVEN TO FN + let event = await interface.getEvent(encodedTopic) - if (event.name == eventName) return encodedTopic - } catch (error) { - // breaks silently as we do not need to do anything if the there is not such an event - } - - } + if (event.name === eventName) return encodedTopic + } catch (error) { + // breaks silently as we do not need to do anything if the there is not + // such an event + } } + } - - return '' + return '' } -async function decodeData(receipt, encodedTopic, paramsArr) { - const decoder = new AbiCoder(); +async function decodeData (receipt, encodedTopic, paramsArr) { + const decoder = new AbiCoder() - const encodedData = receipt.logs.filter(e => e.topics.includes(encodedTopic))[0].data - return decoder.decode(paramsArr, encodedData) + const encodedData = receipt + .logs + .filter(e => e.topics.includes(encodedTopic))[0] + .data + return decoder.decode(paramsArr, encodedData) } - module.exports = { - PERMIT_TYPEHASH, - toWei, - getApprovalDigest, - getEncodedTopic, - decodeData + PERMIT_TYPEHASH, + toWei, + getApprovalDigest, + getEncodedTopic, + decodeData } \ No newline at end of file diff --git a/testHelpers/timemachine.js b/testHelpers/timemachine.js index faa7a289..00a6fbf8 100644 --- a/testHelpers/timemachine.js +++ b/testHelpers/timemachine.js @@ -1,56 +1,55 @@ -function advanceTimeBlocks(_blocks) { - return new Promise(function(resolve) { - web3.currentProvider.send({ - jsonrpc: "2.0", - method: "evm_mine", - params: [_blocks], - id: new Date().getTime() - }, resolve); - }); -}; +function advanceTimeBlocks (_blocks) { + return new Promise(function (resolve) { + web3.currentProvider.send({ + jsonrpc: "2.0", + method: "evm_mine", + params: [ _blocks ], + id: new Date().getTime() + }, resolve) + }) +} -function advanceTimeSeconds(_seconds) { - return new Promise(function(resolve) { - web3.currentProvider.send({ - jsonrpc: "2.0", - method: "evm_increaseTime", - params: [_seconds], - id: new Date().getTime() - }, resolve); - }); -}; +function advanceTimeSeconds (_seconds) { + return new Promise(function (resolve) { + web3.currentProvider.send({ + jsonrpc: "2.0", + method: "evm_increaseTime", + params: [ _seconds ], + id: new Date().getTime() + }, resolve) + }) +} function takeSnapshot () { - return new Promise((resolve, reject) => { - web3.currentProvider.send({ - jsonrpc: '2.0', - method: 'evm_snapshot', - id: new Date().getTime() - }, (err, snapshotId) => { - if (err) { return reject(err) } - return resolve(snapshotId) - }) + return new Promise((resolve, reject) => { + web3.currentProvider.send({ + jsonrpc: '2.0', + method: 'evm_snapshot', + id: new Date().getTime() + }, (err, snapshotId) => { + if (err) { return reject(err) } + return resolve(snapshotId) }) + }) } -function revertToSnapShot (id) { - return new Promise((resolve, reject) => { - web3.currentProvider.send({ - jsonrpc: '2.0', - method: 'evm_revert', - params: [id], - id: new Date().getTime() - }, (err, result) => { - if (err) { return reject(err) } - return resolve(result) - }) +function revertToSnapShot (id) { + return new Promise((resolve, reject) => { + web3.currentProvider.send({ + jsonrpc: '2.0', + method: 'evm_revert', + params: [ id ], + id: new Date().getTime() + }, (err, result) => { + if (err) { return reject(err) } + return resolve(result) }) + }) } - Object.assign(exports, { - advanceTimeBlocks, - advanceTimeSeconds, - takeSnapshot, - revertToSnapShot -}); \ No newline at end of file + advanceTimeBlocks, + advanceTimeSeconds, + takeSnapshot, + revertToSnapShot +}) diff --git a/testHelpers/utils.js b/testHelpers/utils.js index 9437f04c..02c56e91 100644 --- a/testHelpers/utils.js +++ b/testHelpers/utils.js @@ -1,438 +1,549 @@ - const helpers = require('./constants') -const config = require('./config.json') const BN = web3.utils.BN const truffleAssert = require('truffle-assertions') -const { ecsign } = require('ethereumjs-util'); +const { ecsign } = require('ethereumjs-util') const { - PERMIT_TYPEHASH, - toWei, - getApprovalDigest -} = require('../testHelpers/permitUtils'); + toWei, + getApprovalDigest +} = require('../testHelpers/permitUtils') class Utils { - - constructor() { - this.createOrder = '' - this.commitToBuy = '' - this.deadline = toWei(1) - } - - setContracts(erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit) { - this.contractERC1155ERC721 = erc1155721 - this.contractVoucherKernel = voucherKernel - this.contractCashier = cashier - this.contractBSNTokenPrice = bsnTokenPrice - this.contractBSNTokenDeposit = bsnTokenDeposit - this.contractBSNTokenSAME = bsnTokenPrice - } - - async requestCreateOrder_ETH_ETH(seller, from, to, sellerDeposit, qty, returnTx = false) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) - - let txOrder = await this.contractCashier.requestCreateOrder_ETH_ETH( - [from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty], - { - from: seller.address, - value: txValue - } - ); - - return returnTx ? txOrder: (txOrder.logs[0].args._tokenIdSupply).toString() - } - - async requestCreateOrder_TKN_TKN_Same_WithPermit(seller, from, to, sellerDeposit, qty) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) - - const nonce = await this.contractBSNTokenSAME.nonces(seller.address); - - const digest = await getApprovalDigest( - this.contractBSNTokenSAME, - seller.address, - this.contractCashier.address, - txValue, - nonce, - this.deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.pk.slice(2), 'hex')); - - let txOrder = await this.contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - this.contractBSNTokenSAME.address, - this.contractBSNTokenSAME.address, - txValue, - this.deadline, - v,r,s, - [ - from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty - ], - { - from: seller.address - } - ); - - return (txOrder.logs[0].args._tokenIdSupply).toString() - } - - - async requestCreateOrder_TKN_TKN_WithPermit(seller, from, to, sellerDeposit, qty) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) - - const nonce = await this.contractBSNTokenDeposit.nonces(seller.address); - - const digest = await getApprovalDigest( - this.contractBSNTokenDeposit, - seller.address, - this.contractCashier.address, - txValue, - nonce, - this.deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.pk.slice(2), 'hex')); - - let txOrder = await this.contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - this.contractBSNTokenPrice.address, - this.contractBSNTokenDeposit.address, - txValue, - this.deadline, - v,r,s, - [ - from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty - ], - { - from: seller.address - } - ); - - return (txOrder.logs[0].args._tokenIdSupply).toString() - } - - async requestCreateOrder_ETH_TKN_WithPermit(seller, from, to, sellerDeposit, qty, returnTx = false) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)); - const nonce = await this.contractBSNTokenDeposit.nonces(seller.address); - - const digest = await getApprovalDigest( - this.contractBSNTokenDeposit, - seller.address, - this.contractCashier.address, - txValue, - nonce, - this.deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.pk.slice(2), 'hex')); - - - let txOrder = await this.contractCashier.requestCreateOrder_ETH_TKN_WithPermit( - this.contractBSNTokenDeposit.address, - txValue, - this.deadline, - v, r, s, - [ - from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty - ], - { - from: seller.address - } - ); - - return returnTx ? txOrder : (txOrder.logs[0].args._tokenIdSupply).toString() - } - - async requestCreateOrder_TKN_ETH(seller, from, to, sellerDeposit, qty) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)); - - let txOrder = await this.contractCashier.requestCreateOrder_TKN_ETH( - this.contractBSNTokenPrice.address, - [ - from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty - ], - { - from: seller.address, - value: txValue - } - ); - - return (txOrder.logs[0].args._tokenIdSupply).toString() - } - - async commitToBuy_TKN_TKN_WithPermit(buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)) - const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address); - - const digestDeposit = await getApprovalDigest( - this.contractBSNTokenDeposit, - buyer.address, - this.contractCashier.address, - helpers.buyer_deposit, - nonce1, - this.deadline - ) - - let VRS_DEPOSIT = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')); - - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s - - const nonce2 = await this.contractBSNTokenPrice.nonces(buyer.address); - - const digestPrice = await getApprovalDigest( - this.contractBSNTokenPrice, - buyer.address, - this.contractCashier.address, - helpers.product_price, - nonce2, - this.deadline - ) - - let VRS_PRICE = ecsign( - Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')); - - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s - - let CommitTx = await this.contractCashier.requestVoucher_TKN_TKN_WithPermit( - tokenSupplyId, - seller.address, - txValue, - this.deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, - { from: buyer.address }); - - let nestedValue = (await truffleAssert.createTransactionResult(this.contractVoucherKernel, CommitTx.tx)).logs - - let filtered = nestedValue.filter(e => e.event == 'LogVoucherDelivered')[0] - return filtered.returnValues['_tokenIdVoucher'] - } - - async commitToBuy_TKN_TKN_Same_WithPermit(buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)) - const nonce = await this.contractBSNTokenSAME.nonces(buyer.address); - - const digestTxValue = await getApprovalDigest( - this.contractBSNTokenSAME, - buyer.address, - this.contractCashier.address, - txValue, - nonce, - this.deadline - ) - - let VRS_TX_VALUE = ecsign( - Buffer.from(digestTxValue.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')); - - let v = VRS_TX_VALUE.v - let r = VRS_TX_VALUE.r - let s = VRS_TX_VALUE.s - - let CommitTx = await this.contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( - tokenSupplyId, - seller.address, - txValue, - this.deadline, - v, r, s, - { from: buyer.address }); - - let nestedValue = (await truffleAssert.createTransactionResult(this.contractVoucherKernel, CommitTx.tx)).logs - - let filtered = nestedValue.filter(e => e.event == 'LogVoucherDelivered')[0] - return filtered.returnValues['_tokenIdVoucher'] - } - - async commitToBuy_ETH_TKN_WithPermit(buyer, seller, tokenSupplyId) { - const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address); - - const digestDeposit = await getApprovalDigest( - this.contractBSNTokenDeposit, - buyer.address, - this.contractCashier.address, - helpers.buyer_deposit, - nonce1, - this.deadline - ) - - let { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')); - - - let txOrder = await this.contractCashier.requestVoucher_ETH_TKN_WithPermit( - tokenSupplyId, - seller.address, - helpers.buyer_deposit, - this.deadline, - v, r, s, - { from: buyer.address, value: helpers.product_price.toString() } - ); - - let nestedValue = (await truffleAssert.createTransactionResult(this.contractVoucherKernel, txOrder.tx)).logs - - let filtered = nestedValue.filter(e => e.event == 'LogVoucherDelivered')[0] - return filtered.returnValues['_tokenIdVoucher'] - } - - async commitToBuy_ETH_ETH(buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)) - - let CommitTx = await this.contractCashier.requestVoucher_ETH_ETH(tokenSupplyId, seller.address, { from: buyer.address, value: txValue.toString() }); - - let nestedValue = (await truffleAssert.createTransactionResult(this.contractVoucherKernel, CommitTx.tx)).logs - - let filtered = nestedValue.filter(e => e.event == 'LogVoucherDelivered')[0] - return filtered.returnValues['_tokenIdVoucher'] - } - - async commitToBuy_TKN_ETH_WithPermit(buyer, seller, tokenSupplyId) { - const nonce1 = await this.contractBSNTokenPrice.nonces(buyer.address); - - const digestDeposit = await getApprovalDigest( - this.contractBSNTokenPrice, - buyer.address, - this.contractCashier.address, - helpers.product_price, - nonce1, - this.deadline - ) - - let { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')); - - - let txOrder = await this.contractCashier.requestVoucher_TKN_ETH_WithPermit( - tokenSupplyId, - seller.address, - helpers.product_price, - this.deadline, - v, r, s, - { from: buyer.address, value: helpers.buyer_deposit } - ); - - let nestedValue = (await truffleAssert.createTransactionResult(this.contractVoucherKernel, txOrder.tx)).logs - - let filtered = nestedValue.filter(e => e.event == 'LogVoucherDelivered')[0] - return filtered.returnValues['_tokenIdVoucher'] - } - - async refund(voucherID, buyer) { - await this.contractVoucherKernel.refund(voucherID, { from: buyer }); - } - - async redeem(voucherID, buyer) { - await this.contractVoucherKernel.redeem(voucherID, { from: buyer }); - } - - async complain(voucherID, buyer) { - await this.contractVoucherKernel.complain(voucherID, { from: buyer }); - } - - async cancel(voucherID, seller) { - await this.contractVoucherKernel.cancelOrFault(voucherID, { from: seller }); - } - - async finalize(voucherID, deployer) { - await this.contractVoucherKernel.triggerFinalizeVoucher(voucherID, {from: deployer}) - } - - async withdraw(voucherID, deployer) { - const tx = await this.contractCashier.withdraw(voucherID, {from: deployer}); - console.log('GAS USED: ', tx.receipt.gasUsed); - return tx - } - - async withdrawWhenPaused(voucherID, executor) { - const tx = await this.contractCashier.withdrawWhenPaused(voucherID, {from: executor}); - console.log('GAS USED: ', tx.receipt.gasUsed); - return tx - } - - async pause(deployer) { - await this.contractCashier.pause({from: deployer}) - } - - async safeTransfer721(oldVoucherOwner, newVoucherOwner, voucherID, from) { - const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') - return await this.contractERC1155ERC721 - .methods['safeTransferFrom(address,address,uint256,bytes)'] - (oldVoucherOwner, newVoucherOwner, voucherID, arbitraryBytes, from); - } - - async safeTransfer1155(oldSupplyOwner, newSupplyOwner, supplyID, qty, from) { - const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') - return await this.contractERC1155ERC721 - .methods['safeTransferFrom(address,address,uint256,uint256,bytes)'] - (oldSupplyOwner, newSupplyOwner, supplyID, qty, arbitraryBytes, from); - } - - async safeBatchTransfer1155(oldSupplyOwner, newSupplyOwner, supplyIDs, values, from) { - const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') - return await this.contractERC1155ERC721 - .methods['safeBatchTransferFrom(address,address,uint256[],uint256[],bytes)'] - (oldSupplyOwner, newSupplyOwner, supplyIDs, values, arbitraryBytes, from); - } - - calcTotalAmountToRecipients(event, distributionAmounts, recipient, buyer, seller) { - if (event[recipient] == buyer) { - distributionAmounts.buyerAmount = new BN(distributionAmounts.buyerAmount.toString()).add(new BN(event._payment.toString())) - } else if (event[recipient] == seller) { - distributionAmounts.sellerAmount = new BN(distributionAmounts.sellerAmount.toString()).add(new BN(event._payment.toString())) - } else { - distributionAmounts.escrowAmount = new BN(distributionAmounts.escrowAmount.toString()).add(new BN(event._payment.toString())) + constructor () { + this.createOrder = '' + this.commitToBuy = '' + this.deadline = toWei(1) + } + + setContracts ( + erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit + ) { + this.contractERC1155ERC721 = erc1155721 + this.contractVoucherKernel = voucherKernel + this.contractCashier = cashier + this.contractBSNTokenPrice = bsnTokenPrice + this.contractBSNTokenDeposit = bsnTokenDeposit + this.contractBSNTokenSAME = bsnTokenPrice + } + + async requestCreateOrder_ETH_ETH ( + seller, from, to, sellerDeposit, qty, returnTx = false + ) { + const txValue = new BN(sellerDeposit).mul(new BN(qty)) + + let txOrder = await this.contractCashier.requestCreateOrder_ETH_ETH( + [ from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty ], + { + from: seller.address, + value: txValue + } + ) + + return returnTx ? + txOrder : + (txOrder.logs[0].args._tokenIdSupply).toString() + } + + async requestCreateOrder_TKN_TKN_Same_WithPermit ( + seller, from, to, sellerDeposit, qty + ) { + const txValue = new BN(sellerDeposit).mul(new BN(qty)) + + const nonce = await this.contractBSNTokenSAME.nonces(seller.address) + + const digest = await getApprovalDigest( + this.contractBSNTokenSAME, + seller.address, + this.contractCashier.address, + txValue, + nonce, + this.deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(seller.pk.slice(2), 'hex')) + + let txOrder = await this.contractCashier + .requestCreateOrder_TKN_TKN_WithPermit( + this.contractBSNTokenSAME.address, + this.contractBSNTokenSAME.address, + txValue, + this.deadline, + v, r, s, + [ + from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty + ], + { + from: seller.address + } + ) + + return (txOrder.logs[0].args._tokenIdSupply).toString() + } + + async requestCreateOrder_TKN_TKN_WithPermit ( + seller, from, to, sellerDeposit, qty + ) { + const txValue = new BN(sellerDeposit).mul(new BN(qty)) + + const nonce = await this.contractBSNTokenDeposit.nonces(seller.address) + + const digest = await getApprovalDigest( + this.contractBSNTokenDeposit, + seller.address, + this.contractCashier.address, + txValue, + nonce, + this.deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(seller.pk.slice(2), 'hex')) + + let txOrder = await this.contractCashier + .requestCreateOrder_TKN_TKN_WithPermit( + this.contractBSNTokenPrice.address, + this.contractBSNTokenDeposit.address, + txValue, + this.deadline, + v, r, s, + [ + from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty + ], + { + from: seller.address } + ) + + return (txOrder.logs[0].args._tokenIdSupply).toString() + } + + async requestCreateOrder_ETH_TKN_WithPermit ( + seller, from, to, sellerDeposit, qty, returnTx = false + ) { + const txValue = new BN(sellerDeposit).mul(new BN(qty)) + const nonce = await this.contractBSNTokenDeposit.nonces(seller.address) + + const digest = await getApprovalDigest( + this.contractBSNTokenDeposit, + seller.address, + this.contractCashier.address, + txValue, + nonce, + this.deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(seller.pk.slice(2), 'hex')) + + let txOrder = await this.contractCashier + .requestCreateOrder_ETH_TKN_WithPermit( + this.contractBSNTokenDeposit.address, + txValue, + this.deadline, + v, r, s, + [ + from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty + ], + { + from: seller.address + } + ) + + return returnTx ? + txOrder : + (txOrder.logs[0].args._tokenIdSupply).toString() + } + + async requestCreateOrder_TKN_ETH ( + seller, from, to, sellerDeposit, qty + ) { + const txValue = new BN(sellerDeposit).mul(new BN(qty)) + + let txOrder = await this.contractCashier.requestCreateOrder_TKN_ETH( + this.contractBSNTokenPrice.address, + [ + from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty + ], + { + from: seller.address, + value: txValue + } + ) + + return (txOrder.logs[0].args._tokenIdSupply).toString() + } + + async commitToBuy_TKN_TKN_WithPermit (buyer, seller, tokenSupplyId) { + const txValue = new BN(helpers.buyer_deposit) + .add(new BN(helpers.product_price)) + const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address) + + const digestDeposit = await getApprovalDigest( + this.contractBSNTokenDeposit, + buyer.address, + this.contractCashier.address, + helpers.buyer_deposit, + nonce1, + this.deadline + ) + + let VRS_DEPOSIT = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(buyer.pk.slice(2), 'hex')) + + let vDeposit = VRS_DEPOSIT.v + let rDeposit = VRS_DEPOSIT.r + let sDeposit = VRS_DEPOSIT.s + + const nonce2 = await this.contractBSNTokenPrice.nonces(buyer.address) + + const digestPrice = await getApprovalDigest( + this.contractBSNTokenPrice, + buyer.address, + this.contractCashier.address, + helpers.product_price, + nonce2, + this.deadline + ) + + let VRS_PRICE = ecsign( + Buffer.from(digestPrice.slice(2), 'hex'), + Buffer.from(buyer.pk.slice(2), 'hex')) + + let vPrice = VRS_PRICE.v + let rPrice = VRS_PRICE.r + let sPrice = VRS_PRICE.s + + let CommitTx = await this.contractCashier + .requestVoucher_TKN_TKN_WithPermit( + tokenSupplyId, + seller.address, + txValue, + this.deadline, + vPrice, rPrice, sPrice, + vDeposit, rDeposit, sDeposit, + { from: buyer.address }) + + let nestedValue = + (await truffleAssert + .createTransactionResult(this.contractVoucherKernel, CommitTx.tx)) + .logs + + let filtered = nestedValue + .filter(e => e.event === 'LogVoucherDelivered')[0] + + return filtered.returnValues['_tokenIdVoucher'] + } + + async commitToBuy_TKN_TKN_Same_WithPermit (buyer, seller, tokenSupplyId) { + const txValue = new BN(helpers.buyer_deposit) + .add(new BN(helpers.product_price)) + const nonce = await this.contractBSNTokenSAME.nonces(buyer.address) + + const digestTxValue = await getApprovalDigest( + this.contractBSNTokenSAME, + buyer.address, + this.contractCashier.address, + txValue, + nonce, + this.deadline + ) + + let VRS_TX_VALUE = ecsign( + Buffer.from(digestTxValue.slice(2), 'hex'), + Buffer.from(buyer.pk.slice(2), 'hex')) + + let v = VRS_TX_VALUE.v + let r = VRS_TX_VALUE.r + let s = VRS_TX_VALUE.s + + let CommitTx = await this.contractCashier + .requestVoucher_TKN_TKN_Same_WithPermit( + tokenSupplyId, + seller.address, + txValue, + this.deadline, + v, r, s, + { from: buyer.address }) + + let nestedValue = + (await truffleAssert + .createTransactionResult(this.contractVoucherKernel, CommitTx.tx)) + .logs + + let filtered = nestedValue + .filter(e => e.event === 'LogVoucherDelivered')[0] + + return filtered.returnValues['_tokenIdVoucher'] + } + + async commitToBuy_ETH_TKN_WithPermit (buyer, seller, tokenSupplyId) { + const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address) + + const digestDeposit = await getApprovalDigest( + this.contractBSNTokenDeposit, + buyer.address, + this.contractCashier.address, + helpers.buyer_deposit, + nonce1, + this.deadline + ) + + let { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(buyer.pk.slice(2), 'hex')) + + let txOrder = await this.contractCashier + .requestVoucher_ETH_TKN_WithPermit( + tokenSupplyId, + seller.address, + helpers.buyer_deposit, + this.deadline, + v, r, s, + { from: buyer.address, value: helpers.product_price.toString() } + ) + + let nestedValue = + (await truffleAssert + .createTransactionResult(this.contractVoucherKernel, txOrder.tx)) + .logs + + let filtered = nestedValue + .filter(e => e.event === 'LogVoucherDelivered')[0] + + return filtered.returnValues['_tokenIdVoucher'] + } + + async commitToBuy_ETH_ETH (buyer, seller, tokenSupplyId) { + const txValue = new BN(helpers.buyer_deposit) + .add(new BN(helpers.product_price)) + + let CommitTx = await this.contractCashier + .requestVoucher_ETH_ETH( + tokenSupplyId, + seller.address, + { + from: buyer.address, + value: txValue.toString() + }) + + let nestedValue = + (await truffleAssert + .createTransactionResult(this.contractVoucherKernel, CommitTx.tx)) + .logs + + let filtered = nestedValue + .filter(e => e.event === 'LogVoucherDelivered')[0] + + return filtered.returnValues['_tokenIdVoucher'] + } + + async commitToBuy_TKN_ETH_WithPermit (buyer, seller, tokenSupplyId) { + const nonce1 = await this.contractBSNTokenPrice.nonces(buyer.address) + + const digestDeposit = await getApprovalDigest( + this.contractBSNTokenPrice, + buyer.address, + this.contractCashier.address, + helpers.product_price, + nonce1, + this.deadline + ) + + let { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(buyer.pk.slice(2), 'hex')) + + let txOrder = await this.contractCashier + .requestVoucher_TKN_ETH_WithPermit( + tokenSupplyId, + seller.address, + helpers.product_price, + this.deadline, + v, r, s, + { from: buyer.address, value: helpers.buyer_deposit } + ) + + let nestedValue = + (await truffleAssert + .createTransactionResult(this.contractVoucherKernel, txOrder.tx)) + .logs + + let filtered = nestedValue + .filter(e => e.event === 'LogVoucherDelivered')[0] + + return filtered.returnValues['_tokenIdVoucher'] + } + + async refund (voucherID, buyer) { + await this.contractVoucherKernel + .refund(voucherID, { from: buyer }) + } + + async redeem (voucherID, buyer) { + await this.contractVoucherKernel + .redeem(voucherID, { from: buyer }) + } + + async complain (voucherID, buyer) { + await this.contractVoucherKernel + .complain(voucherID, { from: buyer }) + } + + async cancel (voucherID, seller) { + await this.contractVoucherKernel + .cancelOrFault(voucherID, { from: seller }) + } + + async finalize (voucherID, deployer) { + await this.contractVoucherKernel + .triggerFinalizeVoucher(voucherID, { from: deployer }) + } + + async withdraw (voucherID, deployer) { + const tx = await this.contractCashier + .withdraw(voucherID, { from: deployer }) + + console.log('GAS USED: ', tx.receipt.gasUsed) + + return tx + } + + async withdrawWhenPaused (voucherID, executor) { + const tx = await this.contractCashier + .withdrawWhenPaused(voucherID, { from: executor }) + + console.log('GAS USED: ', tx.receipt.gasUsed) + + return tx + } + + async pause (deployer) { + await this.contractCashier.pause({ from: deployer }) + } + + async safeTransfer721 ( + oldVoucherOwner, newVoucherOwner, voucherID, from + ) { + const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') + + const methodSignature = 'safeTransferFrom(' + + 'address,' + + 'address,' + + 'uint256,' + + 'bytes)' + const method = this.contractERC1155ERC721.methods[methodSignature] + + return await method( + oldVoucherOwner, + newVoucherOwner, + voucherID, + arbitraryBytes, + from) + } + + async safeTransfer1155 ( + oldSupplyOwner, newSupplyOwner, supplyID, qty, from + ) { + const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') + + const methodSignature = 'safeTransferFrom(' + + 'address,' + + 'address,' + + 'uint256,' + + 'uint256,' + + 'bytes)' + const method = this.contractERC1155ERC721.methods[methodSignature] + + return await method( + oldSupplyOwner, + newSupplyOwner, + supplyID, + qty, + arbitraryBytes, + from) + } + + async safeBatchTransfer1155 ( + oldSupplyOwner, newSupplyOwner, supplyIDs, values, from + ) { + const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') + + const methodSignature = 'safeBatchTransferFrom(' + + 'address,' + + 'address,' + + 'uint256[],' + + 'uint256[],' + + 'bytes)' + const method = this.contractERC1155ERC721.methods[methodSignature] + + return await method( + oldSupplyOwner, + newSupplyOwner, + supplyIDs, + values, + arbitraryBytes, + from) + } + + calcTotalAmountToRecipients ( + event, distributionAmounts, recipient, buyer, seller + ) { + if (event[recipient] === buyer) { + distributionAmounts.buyerAmount = + new BN(distributionAmounts.buyerAmount.toString()) + .add(new BN(event._payment.toString())) + } else if (event[recipient] === seller) { + distributionAmounts.sellerAmount = + new BN(distributionAmounts.sellerAmount.toString()) + .add(new BN(event._payment.toString())) + } else { + distributionAmounts.escrowAmount = + new BN(distributionAmounts.escrowAmount.toString()) + .add(new BN(event._payment.toString())) } + } - async mintTokens(tokenContract, to, value) { - - await this[tokenContract].mint(to, value); - } + async mintTokens (tokenContract, to, value) { + await this[tokenContract].mint(to, value) + } - static async getCurrTimestamp() { - let blockNumber = await web3.eth.getBlockNumber() - let block = await web3.eth.getBlock(blockNumber) + static async getCurrTimestamp () { + let blockNumber = await web3.eth.getBlockNumber() + let block = await web3.eth.getBlock(blockNumber) - return block.timestamp - } + return block.timestamp + } } -module.exports = Utils \ No newline at end of file +module.exports = Utils diff --git a/testHelpers/utilsBuilder.js b/testHelpers/utilsBuilder.js index 58ad2d74..aff462b0 100644 --- a/testHelpers/utilsBuilder.js +++ b/testHelpers/utilsBuilder.js @@ -1,67 +1,81 @@ - // @ts-nocheck const Utils = require('./utils') class UtilsBuilder { - - constructor() { - this.utils = new Utils() - } - - static NEW () { - return new UtilsBuilder() - }; - - ETH_ETH () { - this.utils.createOrder = this.utils.requestCreateOrder_ETH_ETH - this.utils.commitToBuy = this.utils.commitToBuy_ETH_ETH - - return this - } - - ERC20withPermit () { - this.ETH_TKN = this.ETH_TKN_WithPermit - this.TKN_TKN = this.TKN_TKN_WithPermit - this.TKN_ETH = this.TKN_ETH_WithPermit - this.TKN_TKN_SAME = this.TKN_TKN_SameWithPermit - - return this - } - - build(erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit) { - this.utils.setContracts(erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit); - return this.utils; - } - - ETH_TKN_WithPermit() { - this.utils.createOrder = this.utils.requestCreateOrder_ETH_TKN_WithPermit - this.utils.commitToBuy = this.utils.commitToBuy_ETH_TKN_WithPermit - - return this - } - - TKN_TKN_WithPermit() { - this.utils.createOrder = this.utils.requestCreateOrder_TKN_TKN_WithPermit - this.utils.commitToBuy = this.utils.commitToBuy_TKN_TKN_WithPermit - - return this - } - - TKN_TKN_SameWithPermit() { - this.utils.createOrder = this.utils.requestCreateOrder_TKN_TKN_Same_WithPermit - this.utils.commitToBuy = this.utils.commitToBuy_TKN_TKN_Same_WithPermit - - return this - } - - TKN_ETH_WithPermit() { - this.utils.createOrder = this.utils.requestCreateOrder_TKN_ETH - this.utils.commitToBuy = this.utils.commitToBuy_TKN_ETH_WithPermit - - return this - } - - + constructor () { + this.utils = new Utils() + } + + static NEW () { + return new UtilsBuilder() + }; + + ETH_ETH () { + this.utils.createOrder = + this.utils.requestCreateOrder_ETH_ETH + this.utils.commitToBuy = + this.utils.commitToBuy_ETH_ETH + + return this + } + + ERC20withPermit () { + this.ETH_TKN = this.ETH_TKN_WithPermit + this.TKN_TKN = this.TKN_TKN_WithPermit + this.TKN_ETH = this.TKN_ETH_WithPermit + this.TKN_TKN_SAME = this.TKN_TKN_SameWithPermit + + return this + } + + build ( + erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit + ) { + this.utils.setContracts( + erc1155721, + voucherKernel, + cashier, + bsnTokenPrice, + bsnTokenDeposit) + + return this.utils + } + + ETH_TKN_WithPermit () { + this.utils.createOrder = + this.utils.requestCreateOrder_ETH_TKN_WithPermit + this.utils.commitToBuy = + this.utils.commitToBuy_ETH_TKN_WithPermit + + return this + } + + TKN_TKN_WithPermit () { + this.utils.createOrder = + this.utils.requestCreateOrder_TKN_TKN_WithPermit + this.utils.commitToBuy = + this.utils.commitToBuy_TKN_TKN_WithPermit + + return this + } + + TKN_TKN_SameWithPermit () { + this.utils.createOrder = + this.utils.requestCreateOrder_TKN_TKN_Same_WithPermit + this.utils.commitToBuy = + this.utils.commitToBuy_TKN_TKN_Same_WithPermit + + return this + } + + TKN_ETH_WithPermit () { + this.utils.createOrder = + this.utils.requestCreateOrder_TKN_ETH + this.utils.commitToBuy = + this.utils.commitToBuy_TKN_ETH_WithPermit + + return this + } } -module.exports = UtilsBuilder; \ No newline at end of file +module.exports = UtilsBuilder diff --git a/truffle-config.js b/truffle-config.js index ad5693bd..eeae6bfa 100644 --- a/truffle-config.js +++ b/truffle-config.js @@ -47,14 +47,20 @@ module.exports = { // development: { host: '127.0.0.1', // Localhost (default: none) - port: 8545, // Standard Ethereum port (default: none) - network_id: '*' // Any network (default: none) + port: 8545, // Standard Ethereum port (default: none) + network_id: '*' // Any network (default: none) + }, + + test: { + host: process.env.HOST, // Localhost (default: none) + port: process.env.PORT, // Standard Ethereum port (default: none) + network_id: '*' // Any network (default: none) }, coverage: { host: '127.0.0.1', // Localhost (default: none) - port: 8555, // Test Coverage Port - network_id: '*' // Any network (default: none) + port: 8555, // Test Coverage Port + network_id: '*' // Any network (default: none) }, ropsten: { From 26f4367afacfa9d3c98a2717de3d2f14e0637458 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Wed, 20 Jan 2021 22:08:45 +0000 Subject: [PATCH 09/22] Determine accounts and users dynamically in tests. Reformat. --- CODE_OF_CONDUCT.md | 1 - Rakefile | 59 +- lib/ganache.rb | 131 + test/1_test_fullpath.js | 97 +- test/2_test_fullpath_with_permit.js | 6540 +++++++++++++++------------ test/3_withdrawals.js | 6281 +++++++++++++++---------- test/4_Boson_Token.js | 685 +-- test/5_pausing_contracts.js | 2674 ++++++----- test/6_fundLimits.js | 264 +- testHelpers/accounts.js | 19 - testHelpers/config.json | 33 - testHelpers/users.js | 80 + testHelpers/utils.js | 16 +- testHelpers/utilsBuilder.js | 2 +- 14 files changed, 9967 insertions(+), 6915 deletions(-) create mode 100644 lib/ganache.rb delete mode 100644 testHelpers/accounts.js delete mode 100644 testHelpers/config.json create mode 100644 testHelpers/users.js diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 0375ea9e..797c4121 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,3 @@ - # Contributor Covenant Code of Conduct ## Our Pledge diff --git a/Rakefile b/Rakefile index 0304c906..665e5924 100644 --- a/Rakefile +++ b/Rakefile @@ -1,36 +1,31 @@ -require 'random-port' -require 'childprocess' +require_relative 'lib/ganache' task :default => :"contracts:compile" namespace :ganache do task :start, [:port] do |_, args| - port = args.port.to_s + port = args.port puts "Starting ganache on port #{port}..." - process = ChildProcess.build( - './node_modules/.bin/ganache-cli', - '--allowUnlimitedContractSize', - '-p', port) - # process.io.inherit! - process.leader = true - process.detach = true - process.start - - FileUtils.mkdir_p('run/pid') - File.open("run/pid/ganache-#{port}.pid", "w") do |pidfile| - pidfile.write(process.pid) - end + ganache = Ganache.builder + .on_port(port) + .allowing_unlimited_contract_size + .build + ganache.start + puts "Started ganache on port #{port}" + puts " - with pidfile at #{ganache.pidfile}" + puts " - with account keys file at #{ganache.account_keys_file}" end task :stop, [:port] do |_, args| - port = args.port.to_s + port = args.port puts "Stopping ganache on port #{port}..." - pid = File.read("run/pid/ganache-#{port}.pid").to_i - - Process.kill('INT', pid) - File.unlink("run/pid/ganache-#{port}.pid") + ganache = Ganache.builder + .on_port(port) + .build + ganache.stop + puts "Stopped ganache on port #{port}" end end @@ -44,18 +39,16 @@ end namespace :test do desc "Run all contract integration tests" task :integration do - RandomPort::Pool.new.acquire do |port| - begin - Rake::Task[:'ganache:start'].invoke(port) - - puts "Running integration tests against node listening on #{port}..." - sh({ - "HOST" => "127.0.0.1", - "PORT" => "#{port}" - }, 'npm run test:integration') - ensure - Rake::Task[:'ganache:stop'].invoke(port) - end + Ganache.on_available_port( + allow_unlimited_contract_size: true) do |ganache| + puts "Running integration tests against ganache node listening on " + + "#{ganache.port}..." + + sh({ + "HOST" => "127.0.0.1", + "PORT" => "#{ganache.port}", + "ACCOUNT_KEYS_FILE" => "#{ganache.account_keys_file}" + }, 'npm run test:integration') end end end diff --git a/lib/ganache.rb b/lib/ganache.rb new file mode 100644 index 00000000..d53cce0a --- /dev/null +++ b/lib/ganache.rb @@ -0,0 +1,131 @@ +require 'childprocess' +require 'random-port' +require 'fileutils' + +module Ganache + def self.builder + Builder.new + end + + def self.on_available_port(options = {}, &block) + RandomPort::Pool.new.acquire do |port| + begin + instance = Builder.new(options.merge(port: port)).build + instance.start + block.call(instance) + ensure + instance.stop + end + end + end + + class Instance + attr_reader( + :binary, + :port, + :account_keys_directory, + :pidfile_directory, + :allow_unlimited_contract_size) + + def initialize(options) + @binary = options[:binary] + @port = options[:port] + @account_keys_directory = options[:account_keys_directory] + @pidfile_directory = options[:pidfile_directory] + @allow_unlimited_contract_size = options[:allow_unlimited_contract_size] + + @started = false + end + + def started? + @started + end + + def pidfile + "#{@pidfile_directory}/ganache-#{@port}.pid" + end + + def account_keys_file + "#{@account_keys_directory}/accounts-#{@port}.json" + end + + def start + FileUtils.mkdir_p(@pidfile_directory) + FileUtils.mkdir_p(@account_keys_directory) + + command = [@binary, '--port', @port.to_s] + if @allow_unlimited_contract_size + command = command.concat(['--allowUnlimitedContractSize']) + end + if @account_keys_directory + command = command.concat(['--acctKeys', account_keys_file]) + end + + process = ChildProcess.build(*command) + # process.io.inherit! + process.leader = true + process.detach = true + process.start + + File.open(pidfile, "w") { |pidfile| pidfile.write(process.pid) } + + @started = true + end + + def stop + pid = File.read(pidfile).to_i + + Process.kill('INT', pid) + File.unlink(pidfile) + File.unlink(account_keys_file) + + @started = false + end + end + + class Builder + def initialize(options = {}) + @binary = options[:binary] || './node_modules/.bin/ganache-cli' + @port = options[:port] || 8545 + @pidfile_directory = options[:pidfile_directory] || 'run/pid' + @account_keys_directory = + options[:account_keys_directory] || 'build/ganache' + @allow_unlimited_contract_size = + options[:allow_unlimited_contract_size] || false + end + + def clone(options) + Builder.new(to_h.merge(options)) + end + + def on_port(port) + clone(port: port) + end + + def allowing_unlimited_contract_size + clone(allow_unlimited_contract_size: true) + end + + def saving_account_keys_to(directory) + clone(account_keys_directory: directory) + end + + def saving_pidfile_to(directory) + clone(pidfile_directory: directory) + end + + def build + Instance.new(to_h) + end + + def to_h + { + binary: @binary, + port: @port, + pidfile_directory: @pidfile_directory, + account_keys_directory: @account_keys_directory, + allow_unlimited_contract_size: @allow_unlimited_contract_size + } + end + end +end diff --git a/test/1_test_fullpath.js b/test/1_test_fullpath.js index 5eded716..a2631f64 100644 --- a/test/1_test_fullpath.js +++ b/test/1_test_fullpath.js @@ -5,7 +5,7 @@ const truffleAssert = require('truffle-assertions') const constants = require("../testHelpers/constants") const timemachine = require('../testHelpers/timemachine') const Utils = require('../testHelpers/utils') -const Accounts = require('../testHelpers/accounts') +const Users = require('../testHelpers/users') const ERC1155ERC721 = artifacts.require("ERC1155ERC721") const VoucherKernel = artifacts.require("VoucherKernel") @@ -14,8 +14,8 @@ const FundLimitsOracle = artifacts.require('FundLimitsOracle') let snapshot -contract("Voucher tests", async accountSet => { - const accounts = new Accounts(accountSet) +contract("Voucher tests", async addresses => { + const users = new Users(addresses) let contractERC1155ERC721, contractVoucherKernel, @@ -49,22 +49,23 @@ contract("Voucher tests", async accountSet => { await contractVoucherKernel.setCashierAddress( contractCashier.address) - console.log("Seller: " + accounts.seller) - console.log("Buyer: " + accounts.buyer) - console.log("Attacker: " + accounts.attacker + "\n") + console.log("Seller: " + users.seller.address) + console.log("Buyer: " + users.buyer.address) + console.log("Attacker: " + users.attacker.address) + console.log() }) describe('Direct minting', function () { it("must fail: unauthorized minting ERC-1155", async () => { await truffleAssert.reverts( - contractERC1155ERC721.mint(accounts.attacker, 666, 1, []), + contractERC1155ERC721.mint(users.attacker.address, 666, 1, []), truffleAssert.ErrorType.REVERT ) }) it("must fail: unauthorized minting ERC-721", async () => { await truffleAssert.reverts( - contractERC1155ERC721.mint(accounts.attacker, 666), + contractERC1155ERC721.mint(users.attacker.address, 666), truffleAssert.ErrorType.REVERT ) }) @@ -81,7 +82,7 @@ contract("Voucher tests", async accountSet => { constants.PROMISE_DEPOSITBU1, constants.ORDER_QUANTITY1 ], { - from: accounts.buyer, + from: users.buyer.address, to: contractCashier.address, value: constants.PROMISE_DEPOSITSE1 }) @@ -104,7 +105,7 @@ contract("Voucher tests", async accountSet => { 'LogOrderCreated', (ev) => { tokenSupplyKey1 = ev._tokenIdSupply - return ev._seller === accounts.buyer + return ev._seller === users.buyer.address }, "order1 not created successfully") }) @@ -119,7 +120,7 @@ contract("Voucher tests", async accountSet => { constants.PROMISE_DEPOSITBU2, constants.ORDER_QUANTITY2 ], { - from: accounts.buyer, + from: users.buyer.address, to: contractCashier.address, value: constants.PROMISE_DEPOSITSE2 }) @@ -129,7 +130,7 @@ contract("Voucher tests", async accountSet => { 'LogOrderCreated', (ev) => { tokenSupplyKey2 = ev._tokenIdSupply - return ev._seller === accounts.buyer + return ev._seller === users.buyer.address }, "order2 not created successfully") }) @@ -137,8 +138,8 @@ contract("Voucher tests", async accountSet => { const txFillOrder = await contractCashier .requestVoucher_ETH_ETH( tokenSupplyKey1, - accounts.buyer, { - from: accounts.buyer, + users.buyer.address, { + from: users.buyer.address, to: contractCashier.address, value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1 }) @@ -149,7 +150,7 @@ contract("Voucher tests", async accountSet => { internalTx, 'LogVoucherDelivered', (ev) => { - return ev._issuer === accounts.buyer + return ev._issuer === users.buyer.address }, "order1 not created successfully") const filtered = internalTx.logs @@ -162,8 +163,8 @@ contract("Voucher tests", async accountSet => { const txFillOrder = await contractCashier .requestVoucher_ETH_ETH( tokenSupplyKey2, - accounts.buyer, { - from: accounts.buyer, + users.buyer.address, { + from: users.buyer.address, to: contractCashier.address, value: constants.PROMISE_PRICE2 + constants.PROMISE_DEPOSITBU2 }) @@ -190,7 +191,7 @@ contract("Voucher tests", async accountSet => { constants.PROMISE_DEPOSITBU1, constants.ORDER_QUANTITY1 ], { - from: accounts.buyer, + from: users.buyer.address, to: contractCashier.address, value: 0 }), @@ -202,8 +203,8 @@ contract("Voucher tests", async accountSet => { await truffleAssert.reverts( contractCashier.requestVoucher_ETH_ETH( tokenSupplyKey1, - accounts.buyer, { - from: accounts.buyer, + users.buyer.address, { + from: users.buyer.address, to: contractCashier.address, value: 0 }), @@ -215,7 +216,7 @@ contract("Voucher tests", async accountSet => { describe('Voucher tokens', function () { it("redeeming one voucher", async () => { const txRedeem = await contractVoucherKernel - .redeem(tokenVoucherKey1, { from: accounts.buyer }) + .redeem(tokenVoucherKey1, { from: users.buyer.address }) truffleAssert.eventEmitted( txRedeem, @@ -252,7 +253,7 @@ contract("Voucher tests", async accountSet => { it("mark voucher as finalized", async () => { const txFinalize = await contractVoucherKernel - .triggerFinalizeVoucher(tokenVoucherKey1, { from: accounts.buyer }) + .triggerFinalizeVoucher(tokenVoucherKey1, { from: users.buyer.address }) truffleAssert.eventEmitted( txFinalize, @@ -265,7 +266,7 @@ contract("Voucher tests", async accountSet => { it("must fail: unauthorized redemption", async () => { await truffleAssert.reverts( contractVoucherKernel.redeem( - tokenVoucherKey1, { from: accounts.attacker }), + tokenVoucherKey1, { from: users.attacker.address }), truffleAssert.ErrorType.REVERT ) }) @@ -275,12 +276,12 @@ contract("Voucher tests", async accountSet => { it("withdraw the escrowed payment from one redeemed voucher", async () => { const escrowedBefore = await contractCashier - .getEscrowAmount.call(accounts.buyer) + .getEscrowAmount.call(users.buyer.address) await contractCashier.withdraw(tokenVoucherKey1) const escrowedAfter = await contractCashier - .getEscrowAmount.call(accounts.buyer) + .getEscrowAmount.call(users.buyer.address) assert.isBelow( escrowedAfter.toNumber(), @@ -302,8 +303,8 @@ contract("Voucher tests", async accountSet => { }) }) -contract("Voucher tests - UNHAPPY PATH", async accountSet => { - const accounts = new Accounts(accountSet) +contract("Voucher tests - UNHAPPY PATH", async addresses => { + const users = new Users(addresses) let contractERC1155ERC721, contractVoucherKernel, @@ -348,7 +349,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { constants.PROMISE_DEPOSITBU1, constants.ORDER_QUANTITY1 ], { - from: accounts.seller, + from: users.seller.address, to: contractCashier.address, value: constants.PROMISE_DEPOSITSE1 }) @@ -358,15 +359,15 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { 'LogOrderCreated', (ev) => { tokenSupplyKey1 = ev._tokenIdSupply - return ev._seller === accounts.seller + return ev._seller === users.seller.address }, "order1 not created successfully") const txFillOrder = await contractCashier .requestVoucher_ETH_ETH( tokenSupplyKey1, - accounts.seller, + users.seller.address, { - from: accounts.buyer, + from: users.buyer.address, to: contractCashier.address, value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1 }) @@ -378,7 +379,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { 'LogVoucherDelivered', (ev) => { tokenVoucherKey1 = ev._tokenIdVoucher - return ev._issuer === accounts.seller + return ev._issuer === users.seller.address }, "order1 not created successfully") }) @@ -406,7 +407,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { await truffleAssert.reverts( contractVoucherKernel.setComplainPeriod( - complainPeriodSeconds, { from: accounts.attacker }), + complainPeriodSeconds, { from: users.attacker.address }), truffleAssert.ErrorType.REVERT ) }) @@ -432,7 +433,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { constants.PROMISE_CANCELORFAULT_PERIOD * constants.SECONDS_IN_DAY await truffleAssert.reverts( contractVoucherKernel.setCancelFaultPeriod( - cancelFaultPeriodSeconds, { from: accounts.attacker }), + cancelFaultPeriodSeconds, { from: users.attacker.address }), truffleAssert.ErrorType.REVERT ) }) @@ -442,7 +443,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { it("refunding one voucher", async () => { const txRefund = await contractVoucherKernel.refund( tokenVoucherKey1, { - from: accounts.buyer + from: users.buyer.address }) const statusAfter = await contractVoucherKernel @@ -458,11 +459,11 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { it("refunding one voucher, then complain", async () => { const txRefund = await contractVoucherKernel.refund( tokenVoucherKey1, { - from: accounts.buyer + from: users.buyer.address }) const txComplain = await contractVoucherKernel.complain( tokenVoucherKey1, { - from: accounts.buyer + from: users.buyer.address }) const statusAfter = await contractVoucherKernel @@ -479,15 +480,15 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { async () => { const txRefund = await contractVoucherKernel.refund( tokenVoucherKey1, { - from: accounts.buyer + from: users.buyer.address }) const txComplain = await contractVoucherKernel.complain( tokenVoucherKey1, { - from: accounts.buyer + from: users.buyer.address }) const txCoF = await contractVoucherKernel.cancelOrFault( tokenVoucherKey1, { - from: accounts.seller + from: users.seller.address }) const statusAfter = await contractVoucherKernel @@ -504,12 +505,12 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { it("must fail: refund then try to redeem", async () => { const txRefund = await contractVoucherKernel.refund( tokenVoucherKey1, { - from: accounts.buyer + from: users.buyer.address }) await truffleAssert.reverts( contractVoucherKernel.redeem( - tokenVoucherKey1, { from: accounts.buyer }), + tokenVoucherKey1, { from: users.buyer.address }), truffleAssert.ErrorType.REVERT ) }) @@ -520,7 +521,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { const txCoF = await contractVoucherKernel .cancelOrFault( tokenVoucherKey1, { - from: accounts.seller + from: users.seller.address }) const statusAfter = await contractVoucherKernel @@ -537,12 +538,12 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { const txCoF = await contractVoucherKernel .cancelOrFault( tokenVoucherKey1, { - from: accounts.seller + from: users.seller.address }) await truffleAssert.reverts( contractVoucherKernel.redeem( - tokenVoucherKey1, { from: accounts.buyer }), + tokenVoucherKey1, { from: users.buyer.address }), truffleAssert.ErrorType.REVERT ) }) @@ -568,7 +569,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { "end voucher status not as expected (EXPIRED)") const txComplain = await contractVoucherKernel - .complain(tokenVoucherKey1, { from: accounts.buyer }) + .complain(tokenVoucherKey1, { from: users.buyer.address }) statusAfter = await contractVoucherKernel .getVoucherStatus.call(tokenVoucherKey1) @@ -581,7 +582,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { // in the same test, because the EVM time machine is funky ... const txCoF = await contractVoucherKernel - .cancelOrFault(tokenVoucherKey1, { from: accounts.seller }) + .cancelOrFault(tokenVoucherKey1, { from: users.seller.address }) statusAfter = await contractVoucherKernel .getVoucherStatus.call(tokenVoucherKey1) @@ -596,7 +597,7 @@ contract("Voucher tests - UNHAPPY PATH", async accountSet => { // in the same test, because the EVM time machine is funky ... await truffleAssert.reverts( contractVoucherKernel.redeem( - tokenVoucherKey1, { from: accounts.buyer }), + tokenVoucherKey1, { from: users.buyer.address }), truffleAssert.ErrorType.REVERT ) }) diff --git a/test/2_test_fullpath_with_permit.js b/test/2_test_fullpath_with_permit.js index 2451f993..9ef65bdc 100644 --- a/test/2_test_fullpath_with_permit.js +++ b/test/2_test_fullpath_with_permit.js @@ -1,2820 +1,3736 @@ -const helpers = require("../testHelpers/constants"); -const timemachine = require('../testHelpers/timemachine'); -const truffleAssert = require('truffle-assertions'); -//later consider using https://github.com/OpenZeppelin/openzeppelin-test-helpers - -const ERC1155ERC721 = artifacts.require("ERC1155ERC721"); -const VoucherKernel = artifacts.require("VoucherKernel"); -const Cashier = artifacts.require("Cashier"); -const BosonToken = artifacts.require('BosonTokenPrice'); -const FundLimitsOracle = artifacts.require('FundLimitsOracle'); +const { assert } = require("chai") +const { ecsign } = require('ethereumjs-util') +const truffleAssert = require('truffle-assertions') +// later consider using +// https://github.com/OpenZeppelin/openzeppelin-test-helpers + +const constants = require("../testHelpers/constants") +const timemachine = require('../testHelpers/timemachine') +const Users = require('../testHelpers/users') +const Utils = require('../testHelpers/utils') +const UtilsBuilder = require('../testHelpers/utilsBuilder') +const { toWei, getApprovalDigest } = require('../testHelpers/permitUtils') + +const ERC1155ERC721 = artifacts.require("ERC1155ERC721") +const VoucherKernel = artifacts.require("VoucherKernel") +const Cashier = artifacts.require("Cashier") +const BosonToken = artifacts.require('BosonTokenPrice') +const FundLimitsOracle = artifacts.require('FundLimitsOracle') const BN = web3.utils.BN -const UtilsBuilder = require('../testHelpers/utilsBuilder'); -const Utils = require('../testHelpers/utils'); -let utils; -const config = require('../testHelpers/config.json') - - -const { ecsign } = require('ethereumjs-util'); -const { - PERMIT_TYPEHASH, - toWei, - getApprovalDigest -} = require('../testHelpers/permitUtils'); -const { assert } = require("chai"); - -contract("Cashier && VK", async accounts => { - let Deployer = config.accounts.deployer - let Seller = config.accounts.seller - let Buyer = config.accounts.buyer - let Attacker = config.accounts.attacker - - let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit, contractFundLimitsOracle; - let tokenSupplyKey, tokenVoucherKey; - const ONE_VOUCHER = 1 - const deadline = toWei(1) - let timestamp - let ZERO = new BN(0); - - let distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - async function deployContracts() { - const timestamp = await Utils.getCurrTimestamp() - helpers.PROMISE_VALID_FROM = timestamp - helpers.PROMISE_VALID_TO = timestamp + 2 * helpers.SECONDS_IN_DAY; - - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new(); - contractVoucherKernel = await VoucherKernel.new(contractERC1155ERC721.address); - contractCashier = await Cashier.new(contractVoucherKernel.address, contractERC1155ERC721.address, contractFundLimitsOracle.address); - - contractBSNTokenPrice = await BosonToken.new("BosonTokenPrice", "BPRC"); - contractBSNTokenDeposit = await BosonToken.new("BosonTokenDeposit", "BDEP"); - - await contractERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true'); - await contractERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address); - await contractVoucherKernel.setCashierAddress(contractCashier.address); - - await contractERC1155ERC721.setCashierContract(contractCashier.address); - await contractCashier.setTokenContractAddress(contractERC1155ERC721.address); - - await contractVoucherKernel.setComplainPeriod(60); //60 seconds - await contractVoucherKernel.setCancelFaultPeriod(60); //60 seconds - - await contractFundLimitsOracle.setTokenLimit(contractBSNTokenPrice.address, helpers.TOKEN_LIMIT) - await contractFundLimitsOracle.setTokenLimit(contractBSNTokenDeposit.address, helpers.TOKEN_LIMIT) - await contractFundLimitsOracle.setETHLimit(helpers.ETHER_LIMIT) - - } - - describe('TOKEN SUPPLY CREATION (Voucher batch creation)', () => { - - let remQty = helpers.QTY_10 - let vouchersToBuy = 5 - - const paymentMethods = { - ETH_ETH: 1, - ETH_TKN: 2, - TKN_ETH: 3, - TKN_TKN: 4 - } - - afterEach(() => { - remQty = helpers.QTY_10 - }) - - describe("ETH_ETH", () => { - - before(async() => { - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, helpers.QTY_10); - - timestamp = await Utils.getCurrTimestamp() - - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10) - }) - - it("ESCROW has correct initial balance", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(remQty)) - const escrowAmount = await contractCashier.getEscrowAmount(Seller.address); - - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }) - - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - - assert.equal(remainingQtyInContract, remQty, "Remaining qty is not correct") - - for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(Buyer, Seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - - assert.equal(remainingQtyInContract, --remQty , "Remaining qty is not correct") +let utils + +contract("Cashier && VK", async addresses => { + const users = new Users(addresses) + + let contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit, + contractFundLimitsOracle + let tokenSupplyKey, + tokenVoucherKey + + const ZERO = new BN(0) + const ONE_VOUCHER = 1 + const deadline = toWei(1) + + let timestamp + + let distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } + + async function deployContracts () { + const timestamp = await Utils.getCurrTimestamp() + const sixtySeconds = 60 + + constants.PROMISE_VALID_FROM = timestamp + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY + + contractFundLimitsOracle = await FundLimitsOracle.new() + contractERC1155ERC721 = await ERC1155ERC721.new() + contractVoucherKernel = await VoucherKernel.new( + contractERC1155ERC721.address) + contractCashier = await Cashier.new( + contractVoucherKernel.address, + contractERC1155ERC721.address, + contractFundLimitsOracle.address) + + contractBSNTokenPrice = await BosonToken.new("BosonTokenPrice", "BPRC") + contractBSNTokenDeposit = await BosonToken.new("BosonTokenDeposit", "BDEP") + + await contractERC1155ERC721 + .setApprovalForAll(contractVoucherKernel.address, 'true') + await contractERC1155ERC721 + .setVoucherKernelAddress(contractVoucherKernel.address) + await contractVoucherKernel + .setCashierAddress(contractCashier.address) + + await contractERC1155ERC721 + .setCashierContract(contractCashier.address) + await contractCashier + .setTokenContractAddress(contractERC1155ERC721.address) + + await contractVoucherKernel.setComplainPeriod(sixtySeconds) + await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds) + + await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenPrice.address, constants.TOKEN_LIMIT) + await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenDeposit.address, constants.TOKEN_LIMIT) + await contractFundLimitsOracle + .setETHLimit(constants.ETHER_LIMIT) + } + + describe('TOKEN SUPPLY CREATION (Voucher batch creation)', () => { + let remQty = constants.QTY_10 + let vouchersToBuy = 5 + + const paymentMethods = { + ETH_ETH: 1, + ETH_TKN: 2, + TKN_ETH: 3, + TKN_TKN: 4 + } + + afterEach(() => { + remQty = constants.QTY_10 + }) + + describe("ETH_ETH", () => { + before(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + constants.QTY_10) + + timestamp = await Utils.getCurrTimestamp() + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) + + it("ESCROW has correct initial balance", async () => { + const expectedBalance = + new BN(constants.seller_deposit).mul(new BN(remQty)) + const escrowAmount = await contractCashier + .getEscrowAmount(users.seller.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") + }) + + it("Get correct remaining qty for supply", async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + remQty, + "Remaining qty is not correct") + + for (let i = 0; i < vouchersToBuy; i++) { + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) + remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + --remQty, + "Remaining qty is not correct") + } + }) + + it("Should create payment method ETH_ETH", async () => { + timestamp = await Utils.getCurrTimestamp() + + let tokenSupplyKey = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + + const paymentDetails = await contractVoucherKernel + .paymentDetails(tokenSupplyKey) + + assert.equal( + paymentDetails.paymentMethod.toString(), + paymentMethods.ETH_ETH, + "Payment Method ETH_ETH not set correctly") + assert.equal( + paymentDetails.addressTokenPrice.toString(), + constants.ZERO_ADDRESS, + "ETH_ETH Method Price Token Address mismatch") + assert.equal( + paymentDetails.addressTokenDeposits.toString(), + constants.ZERO_ADDRESS, + "ETH_ETH Method Deposit Token Address mismatch") + }) + + it("[NEGATIVE] Should fail if additional token address is provided", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + timestamp = await Utils.getCurrTimestamp() + + await truffleAssert.fails( + contractCashier.requestCreateOrder_ETH_ETH( + contractBSNTokenDeposit.address, + [ + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, + value: txValue + } + ) + ) + }) + + it("[NEGATIVE] Should not create a supply if price is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_ETH( + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_ETH_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, + value: txValue + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositBu is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_ETH( + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_ETH_LIMIT, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, + value: txValue + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositSe is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_ETH( + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_ETH_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, + value: txValue + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("[WITH PERMIT]", () => { + describe("ETH_TKN", () => { + before(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const tokensToMint = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_20)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMint) + + timestamp = await Utils.getCurrTimestamp() + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + it("ESCROW has correct initial balance", async () => { + const expectedBalance = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_10)) + const escrowAmount = await contractBSNTokenDeposit + .balanceOf(contractCashier.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") + }) + + it("Get correct remaining qty for supply", async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + remQty, + "Remaining qty is not correct") + + for (let i = 0; i < vouchersToBuy; i++) { + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) + remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + --remQty, + "Remaining qty is not correct") + } + }) + + it("Should create payment method ETH_TKN", async () => { + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + + const paymentDetails = await contractVoucherKernel + .paymentDetails(tokenSupplyKey) + + assert.equal( + paymentDetails.paymentMethod.toString(), + paymentMethods.ETH_TKN, + "Payment Method ETH_TKN not set correctly") + assert.equal( + paymentDetails.addressTokenPrice.toString(), + constants.ZERO_ADDRESS, + "ETH_TKN Method Price Token Address mismatch") + assert.equal( + paymentDetails.addressTokenDeposits.toString(), + contractBSNTokenDeposit.address, + "ETH_TKN Method Deposit Token Address mismatch") + }) + + it("[NEGATIVE] Should fail if token deposit contract address is not provided", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.fails( + contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + '', + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address } - - }); - - it("Should create payment method ETH_ETH", async () => { - timestamp = await Utils.getCurrTimestamp() - let tokenSupplyKey = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10); - - const paymentDetails = await contractVoucherKernel.paymentDetails(tokenSupplyKey); - - assert.equal(paymentDetails.paymentMethod.toString(), paymentMethods.ETH_ETH, "Payment Method ETH_ETH not set correctly") - assert.equal(paymentDetails.addressTokenPrice.toString(), helpers.ZERO_ADDRESS, "ETH_ETH Method Price Token Address mismatch") - assert.equal(paymentDetails.addressTokenDeposits.toString(), helpers.ZERO_ADDRESS, "ETH_ETH Method Deposit Token Address mismatch") - }) - - it("[NEGATIVE] Should fail if additional token address is provided", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - timestamp = await Utils.getCurrTimestamp() - - await truffleAssert.fails( - contractCashier.requestCreateOrder_ETH_ETH( - contractBSNTokenDeposit.address, - [ - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue} - ) - ); - - }) - - it("[NEGATIVE] Should not create a supply if price is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_ETH( - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.ABOVE_ETH_LIMIT, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_ETH( - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.ABOVE_ETH_LIMIT, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_ETH( - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.ABOVE_ETH_LIMIT, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("[WITH PERMIT]", () => { - - describe("ETH_TKN", () => { - - before(async() => { - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const tokensToMint = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_20)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMint); - - timestamp = await Utils.getCurrTimestamp() - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - - }) - - it("ESCROW has correct initial balance", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_10)) - const escrowAmount = await contractBSNTokenDeposit.balanceOf(contractCashier.address) - - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }) - - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - assert.equal(remainingQtyInContract, remQty, "Remaining qty is not correct") - - for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(Buyer, Seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - - assert.equal(remainingQtyInContract, --remQty , "Remaining qty is not correct") - } - }); - - it("Should create payment method ETH_TKN", async () => { - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10, - ); - - const paymentDetails = await contractVoucherKernel.paymentDetails(tokenSupplyKey); - - assert.equal(paymentDetails.paymentMethod.toString(), paymentMethods.ETH_TKN, "Payment Method ETH_TKN not set correctly") - assert.equal(paymentDetails.addressTokenPrice.toString(), helpers.ZERO_ADDRESS, "ETH_TKN Method Price Token Address mismatch") - assert.equal(paymentDetails.addressTokenDeposits.toString(), contractBSNTokenDeposit.address, "ETH_TKN Method Deposit Token Address mismatch") - }) - - it("[NEGATIVE] Should fail if token deposit contract address is not provided", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - await truffleAssert.fails( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( - '', - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ) - ) - }) - - it("[NEGATIVE] Should revert if token deposit contract address is zero address", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( - helpers.ZERO_ADDRESS, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Should not create a supply if price is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - const deadline = toWei(1) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.ABOVE_ETH_LIMIT, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - const deadline = toWei(1) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.ABOVE_TOKEN_LIMIT, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - const deadline = toWei(1) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.ABOVE_TOKEN_LIMIT, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("TKN_ETH", () => { - - before(async () => { - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, '') - - timestamp = await Utils.getCurrTimestamp() - - const tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMint); - - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) - - it("ESCROW has correct initial balance", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(remQty)) - const escrowAmount = await contractCashier.getEscrowAmount(Seller.address); - - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }) - - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - - assert.equal(remainingQtyInContract, remQty, "Remaining qty is not correct") - - for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(Buyer, Seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - - assert.equal(remainingQtyInContract, --remQty , "Remaining qty is not correct") - } - }); - - it("Should create payment method TKN_ETH", async () => { - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_1 - ) - - const paymentDetails = await contractVoucherKernel.paymentDetails(tokenSupplyKey); - - assert.equal(paymentDetails.paymentMethod.toString(), paymentMethods.TKN_ETH, "Payment Method TKN_ETH not set correctly") - assert.equal(paymentDetails.addressTokenPrice.toString(), contractBSNTokenPrice.address, "TKN_ETH Method Price Token Address mismatch") - assert.equal(paymentDetails.addressTokenDeposits.toString(), helpers.ZERO_ADDRESS, "TKN_ETH Method Deposit Token Address mismatch") - }) - - it("[NEGATIVE] Should fail if price token contract address is not provided", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.fails( - contractCashier.requestCreateOrder_TKN_ETH( - '', - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue.toString() } - ) - ); - - }) - - it("[NEGATIVE] Should fail if token price contract is zero address", async () => { - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( - helpers.ZERO_ADDRESS, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ); - - }) - - it("[NEGATIVE] Should not create a supply if price is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( - contractBSNTokenPrice.address, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.ABOVE_TOKEN_LIMIT, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue.toString() } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( - contractBSNTokenPrice.address, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.ABOVE_ETH_LIMIT, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue.toString() } - ), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( - contractBSNTokenPrice.address, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.ABOVE_ETH_LIMIT, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address, value: txValue.toString() } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("TKN_TKN", () => { - - before(async () => { - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - timestamp = await Utils.getCurrTimestamp() - - const tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_20)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMint); - - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) - - it("ESCROW has correct initial balance", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(remQty)) - const escrowAmount = await contractBSNTokenDeposit.balanceOf(contractCashier.address) - - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }) - - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - - assert.equal(remainingQtyInContract, remQty, "Remaining qty is not correct") - - for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(Buyer, Seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(tokenSupplyKey, Seller.address) - - assert.equal(remainingQtyInContract, --remQty , "Remaining qty is not correct") - } - }); - - it("Should create payment method TKN_TKN", async () => { - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_1 - ) - - const paymentDetails = await contractVoucherKernel.paymentDetails(tokenSupplyKey); - - assert.equal(paymentDetails.paymentMethod.toString(), paymentMethods.TKN_TKN, "Payment Method TKN_TKN not set correctly") - assert.equal(paymentDetails.addressTokenPrice.toString(), contractBSNTokenPrice.address, "TKN_TKN Method Price Token Address mismatch") - assert.equal(paymentDetails.addressTokenDeposits.toString(), contractBSNTokenDeposit.address, "TKN_TKN Method Deposit Token Address mismatch") - }) - - it("[NEGATIVE] Should fail if token price contract address is not provided", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.fails( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - '', - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ) - ); - - }) - - it("[NEGATIVE] Should fail if token deposit contract address is not provided", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.fails( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - contractBSNTokenPrice.address, - '', - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ) - ); - - }) - - it("[NEGATIVE] Should revert if token price contract address is zero address", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - helpers.ZERO_ADDRESS, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ); - - }) - - it("[NEGATIVE] Should revert if token deposit contract address is zero address", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - const deadline = toWei(1) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - contractBSNTokenPrice.address, - helpers.ZERO_ADDRESS, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ); - - }) - - it("[NEGATIVE] Should not create a supply if price is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_1)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - contractBSNTokenPrice.address, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.ABOVE_TOKEN_LIMIT, - helpers.seller_deposit, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_1)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - contractBSNTokenPrice.address, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.seller_deposit, - helpers.ABOVE_TOKEN_LIMIT, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", async () => { - const txValue = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_1)) - const nonce = await contractBSNTokenDeposit.nonces(Seller.address); - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - Seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Seller.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( - contractBSNTokenPrice.address, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.PROMISE_PRICE1, - helpers.ABOVE_TOKEN_LIMIT, - helpers.PROMISE_DEPOSITBU1, - helpers.ORDER_QUANTITY1 - ], - { from: Seller.address } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - }) - }) - - describe("VOUCHER CREATION (Commit to buy)", () => { - const ORDER_QTY = 5 - let TOKEN_SUPPLY_ID; - - before(async()=>{ - await deployContracts(); - }) - - describe("ETH_ETH", async () => { - before(async () => { - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier) - - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.seller_deposit, helpers.QTY_10) - }) - - it("Should create order", async () => { - const txValue = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)) - let txFillOrder = await contractCashier.requestVoucher_ETH_ETH( - TOKEN_SUPPLY_ID, - Seller.address, - { - from: Buyer.address, value: txValue - }); - - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === Seller.address; - }, "order1 not created successfully"); - }) - - it("[NEGATIVE] Should not create order with incorrect price", async () => { - const txValue = new BN(helpers.buyer_deposit).add(new BN(helpers.incorrect_product_price)) - - await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_ETH( - TOKEN_SUPPLY_ID, - Seller.address, - { from: Buyer.address, value: txValue}), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", async () => { - const txValue = new BN(helpers.buyer_incorrect_deposit).add(new BN(helpers.product_price)) - - await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_ETH( - TOKEN_SUPPLY_ID, - Seller.address, - { from: Buyer.address, value: txValue }), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("[WITH PERMIT]", () => { - - describe("ETH_TKN", async () => { - - before(async () => { - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - - const tokensToMintSeller = new BN(helpers.seller_deposit).mul(new BN(ORDER_QTY)) - const tokensToMintBuyer = new BN(helpers.buyer_deposit).mul(new BN(ORDER_QTY)) - - await contractBSNTokenDeposit.mint(Seller.address, tokensToMintSeller) - await contractBSNTokenDeposit.mint(Buyer.address, tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.seller_deposit, - ORDER_QTY - ) - - }) - - it("Should create order", async () => { - const nonce = await contractBSNTokenDeposit.nonces(Buyer.address); - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - Buyer.address, - contractCashier.address, - helpers.buyer_deposit, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - const txFillOrder = await contractCashier.requestVoucher_ETH_TKN_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - helpers.buyer_deposit, - deadline, - v, r, s, - { from: Buyer.address, value: helpers.product_price} - ) - - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === Seller.address; - }, "order1 not created successfully"); - }) - - it("[NEGATIVE] Should not create order with incorrect price", async () => { - const nonce = await contractBSNTokenDeposit.nonces(Buyer.address); - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - Buyer.address, - contractCashier.address, - helpers.buyer_deposit, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_TKN_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - helpers.buyer_deposit, - deadline, - v, r, s, - { from: Buyer.address, value: helpers.incorrect_product_price } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", async () => { - const nonce = await contractBSNTokenDeposit.nonces(Buyer.address); - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - Buyer.address, - contractCashier.address, - helpers.buyer_deposit, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_TKN_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - helpers.buyer_incorrect_deposit, - deadline, - v, r, s, - { from: Buyer.address, value: helpers.product_price } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("TKN_TKN", () => { - before(async () => { - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - - const tokensToMintSeller = new BN(helpers.seller_deposit).mul(new BN(ORDER_QTY)) - const tokensToMintBuyer = new BN(helpers.product_price).mul(new BN(ORDER_QTY)) - - await contractBSNTokenDeposit.mint(Seller.address, tokensToMintSeller) - await contractBSNTokenDeposit.mint(Buyer.address, tokensToMintBuyer) - await contractBSNTokenPrice.mint(Buyer.address, tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.seller_deposit, - ORDER_QTY - ) - - }) - - it("Should create order", async () => { - const nonce1 = await contractBSNTokenDeposit.nonces(Buyer.address); - const tokensToSend = new BN(helpers.product_price).add(new BN(helpers.buyer_deposit)) - - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - Buyer.address, - contractCashier.address, - helpers.buyer_deposit, - nonce1, - deadline - ) - - let VRS_DEPOSIT = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s - - const nonce2 = await contractBSNTokenPrice.nonces(Buyer.address); - - const digestPrice = await getApprovalDigest( - contractBSNTokenPrice, - Buyer.address, - contractCashier.address, - helpers.product_price, - nonce2, - deadline - ) - - let VRS_PRICE = ecsign( - Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s - - let txFillOrder = await contractCashier.requestVoucher_TKN_TKN_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - tokensToSend, - deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, - { from: Buyer.address }); - - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === Seller.address; - }, "order1 not created successfully"); - }) - - it("[NEGATIVE] Should not create order with incorrect price", async () => { - const nonce1 = await contractBSNTokenDeposit.nonces(Buyer.address); - const tokensToSend = new BN(helpers.incorrect_product_price).add(new BN(helpers.buyer_deposit)) - - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - Buyer.address, - contractCashier.address, - helpers.buyer_deposit, - nonce1, - deadline - ) - - let VRS_DEPOSIT = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s - - const nonce2 = await contractBSNTokenPrice.nonces(Buyer.address); - - const digestPrice = await getApprovalDigest( - contractBSNTokenPrice, - Buyer.address, - contractCashier.address, - helpers.product_price, - nonce2, - deadline - ) - - let VRS_PRICE = ecsign( - Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s - - await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - tokensToSend, - deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, - { from: Buyer.address }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", async () => { - const nonce1 = await contractBSNTokenDeposit.nonces(Buyer.address); - const tokensToSend = new BN(helpers.product_price).add(new BN(helpers.buyer_incorrect_deposit)) - - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - Buyer.address, - contractCashier.address, - helpers.buyer_deposit, - nonce1, - deadline - ) - - let VRS_DEPOSIT = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s - - const nonce2 = await contractBSNTokenPrice.nonces(Buyer.address); - - const digestPrice = await getApprovalDigest( - contractBSNTokenPrice, - Buyer.address, - contractCashier.address, - helpers.product_price, - nonce2, - deadline - ) - - let VRS_PRICE = ecsign( - Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s - - await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - tokensToSend, - deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, - { from: Buyer.address }), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - // Ignored due to deployment failure. - xdescribe("TKN_TKN_SAME", () => { - - const tokensToMintSeller = new BN(helpers.seller_deposit).mul(new BN(ORDER_QTY)) - const tokensToMintBuyer = new BN(helpers.product_price).mul(new BN(ORDER_QTY)) - - before(async () => { - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN_SAME() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - await utils.contractBSNTokenSAME.mint(Seller.address, tokensToMintSeller) - await utils.contractBSNTokenSAME.mint(Buyer.address, tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.seller_deposit, - ORDER_QTY - ) - - }) - - it("Should create voucher", async () => { - - const nonce = await utils.contractBSNTokenSAME.nonces(Buyer.address); - const tokensToSend = new BN(helpers.product_price).add(new BN(helpers.buyer_deposit)) - - const digestTokens = await getApprovalDigest( - utils.contractBSNTokenSAME, - Buyer.address, - contractCashier.address, - tokensToSend, - nonce, - deadline - ) - - let VRS_TOKENS = ecsign( - Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s - - let txFillOrder = await contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - tokensToSend, - deadline, - v, r, s, - { from: Buyer.address }); - - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey1 = ev._tokenIdVoucher - return ev._issuer === Seller.address; - }, "order1 not created successfully"); - }) - - it("[NEGATIVE] Should not create order with incorrect price", async () => { - - const nonce = await contractBSNTokenDeposit.nonces(Buyer.address); - const incorrectTokensToSign = new BN(helpers.incorrect_product_price).add(new BN(helpers.buyer_deposit)) - const digestTokens = await getApprovalDigest( - utils.contractBSNTokenSAME, - Buyer.address, - contractCashier.address, - incorrectTokensToSign, - nonce, - deadline - ) - - let VRS_TOKENS = ecsign( - Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s - - await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - incorrectTokensToSign, - deadline, - v, r, s, - { from: Buyer.address }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", async () => { - - const nonce = await contractBSNTokenDeposit.nonces(Buyer.address); - const incorrectTokensToSign = new BN(helpers.product_price).add(new BN(helpers.buyer_incorrect_deposit)) - const digestTokens = await getApprovalDigest( - utils.contractBSNTokenSAME, - Buyer.address, - contractCashier.address, - incorrectTokensToSign, - nonce, - deadline - ) - - let VRS_TOKENS = ecsign( - Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s - - - await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - incorrectTokensToSign, - deadline, - v, r, s, - { from: Buyer.address }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should revert if Price Token and Deposit Token are diff contracts", async () => { - - let utilsTKN_TKN = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - await contractBSNTokenDeposit.mint(Seller.address, tokensToMintSeller) - await contractBSNTokenDeposit.mint(Buyer.address, tokensToMintBuyer) - await contractBSNTokenPrice.mint(Buyer.address, tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utilsTKN_TKN.createOrder( - Seller, - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.seller_deposit, - ORDER_QTY - ) - - const nonce = await utils.contractBSNTokenSAME.nonces(Buyer.address); - const tokensToSend = new BN(helpers.product_price).add(new BN(helpers.buyer_deposit)) - - const digestTokens = await getApprovalDigest( - utils.contractBSNTokenSAME, - Buyer.address, - contractCashier.address, - tokensToSend, - nonce, - deadline - ) - - let VRS_TOKENS = ecsign( - Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s - - await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - tokensToSend, - deadline, - v, r, s, - { from: Buyer.address } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKN_ETH", () => { - before(async () => { - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const tokensToMintBuyer = new BN(helpers.product_price).mul(new BN(ORDER_QTY)) - - await contractBSNTokenPrice.mint(Buyer.address, tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.seller_deposit, - ORDER_QTY - ) - - }) - - it("Should create order", async () => { - const nonce = await contractBSNTokenPrice.nonces(Buyer.address); - - const digestDeposit = await getApprovalDigest( - contractBSNTokenPrice, - Buyer.address, - contractCashier.address, - helpers.product_price, - nonce, - deadline - ) - - let { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - let txFillOrder = await contractCashier.requestVoucher_TKN_ETH_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - helpers.product_price, - deadline, - v, r, s, - { from: Buyer.address, value: helpers.buyer_deposit } - ); - - let internalTx = (await truffleAssert.createTransactionResult(contractVoucherKernel, txFillOrder.tx)) - - truffleAssert.eventEmitted(internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === Seller.address; - }, "order1 not created successfully"); - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", async () => { - const nonce = await contractBSNTokenPrice.nonces(Buyer.address); - - const digestDeposit = await getApprovalDigest( - contractBSNTokenPrice, - Buyer.address, - contractCashier.address, - helpers.product_price, - nonce, - deadline - ) - - let { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - - await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_ETH_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - helpers.product_price, - deadline, - v, r, s, - { from: Buyer.address, value: helpers.buyer_incorrect_deposit } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create order with incorrect price", async () => { - const nonce = await contractBSNTokenPrice.nonces(Buyer.address); - - const digestDeposit = await getApprovalDigest( - contractBSNTokenPrice, - Buyer.address, - contractCashier.address, - helpers.product_price, - nonce, - deadline - ) - - let { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_ETH_WithPermit( - TOKEN_SUPPLY_ID, - Seller.address, - helpers.incorrect_product_price, - deadline, - v, r, s, - { from: Buyer.address, value: helpers.buyer_deposit } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) - - describe("TOKEN SUPPLY TRANSFER", () => { - let OldSupplyOwner = config.accounts.randomUser - let NewSupplyOwner = config.accounts.randomUser2 - - let actualOldOwnerBalanceFromEscrow = new BN(0); - let actualNewOwnerBalanceFromEscrow = new BN(0); - let expectedBalanceInEscrow = new BN(0); - - afterEach(()=> { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - }) - - describe("Common transfer", () => { - - beforeEach(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier) - - const timestamp = await Utils.getCurrTimestamp() - - tokenSupplyKey = await utils.createOrder(OldSupplyOwner, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) - - }) - - it("Should transfer voucher supply", async () => { - - let transferTx = await utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_10, {from: OldSupplyOwner.address}); - - truffleAssert.eventEmitted(transferTx, 'TransferSingle', (ev) => { - assert.equal(ev._from, OldSupplyOwner.address) - assert.equal(ev._to, NewSupplyOwner.address) - assert.equal(ev._id.toString(), tokenSupplyKey) - assert.equal(ev._value.toString(), helpers.QTY_10) - - return true - }, "TransferSingle not emitted") - - }) - - it("[NEGATIVE] Should revert if owner tries to transfer voucher supply partially", async () => { - - await truffleAssert.reverts( - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Should revert if Attacker tries to transfer voucher supply", async () => { - - await truffleAssert.reverts( - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_10, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("Should transfer batch voucher supply", async () => { - - let transferTx = await utils.safeBatchTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, [tokenSupplyKey], [helpers.QTY_10], {from: OldSupplyOwner.address}); - - truffleAssert.eventEmitted(transferTx, 'TransferBatch', (ev) => { - - assert.equal(ev._from, OldSupplyOwner.address) - assert.equal(ev._to, NewSupplyOwner.address) - assert.equal(JSON.stringify(ev._ids), JSON.stringify([new BN(tokenSupplyKey)])) - assert.equal(JSON.stringify(ev._values), JSON.stringify([new BN(helpers.QTY_10)])) - - return true - }, "TransferSingle not emitted") - - }) - - it("[NEGATIVE] Should revert if owner tries to transfer voucher supply batch partially", async () => { - - await truffleAssert.reverts( - utils.safeBatchTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, [tokenSupplyKey], [helpers.QTY_1], {from: OldSupplyOwner.address}), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Should revert if Attacker tries to transfer batch voucher supply", async () => { - - await truffleAssert.reverts( - utils.safeBatchTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, [tokenSupplyKey], [helpers.QTY_10], {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - - }) - - }) - - describe("ETH_ETH", () => { - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier) - - tokenSupplyKey = await utils.createOrder(OldSupplyOwner, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.seller_deposit, helpers.QTY_1) - }) - - it("Should update escrow amounts after transfer", async () => { - - expectedBalanceInEscrow = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_1)) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldSupplyOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewSupplyOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(ZERO), "New owner balance from escrow does not match") - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}), - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldSupplyOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewSupplyOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(ZERO), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "New owner balance from escrow does not match") - - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerAmount = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerAmount = new BN(helpers.seller_deposit).add(new BN(helpers.product_price)) // 0.35 - const expectedEscrowAmount = new BN(0) // 0 - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - let withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, NewSupplyOwner.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - - }) - - it("New owner should be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await utils.cancel(voucherID, NewSupplyOwner.address) - }) - - it("[NEGATIVE] Old owner should not be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await truffleAssert.reverts( - utils.cancel(voucherID, OldSupplyOwner.address), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("[WITH PERMIT]", () => { - - describe("ETH_TKN", () => { - - let balanceBuyerFromDeposits = new BN(0) - - let balanceSellerFromDeposits = new BN(0) - - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - const tokensToMint = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_1)) - - await utils.mintTokens('contractBSNTokenDeposit', OldSupplyOwner.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, helpers.buyer_deposit); - - tokenSupplyKey = await utils.createOrder( - OldSupplyOwner, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_1 - ) - - }) - - async function getBalancesDepositToken() { - - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Buyer.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(NewSupplyOwner.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Deployer.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf(utils.contractCashier.address) - + ) + ) + }) + + it("[NEGATIVE] Should revert if token deposit contract address is zero address", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + constants.ZERO_ADDRESS, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address } - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) //// 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(0) - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy( - Buyer, - NewSupplyOwner, - tokenSupplyKey - ) - - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - let withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - await getBalancesDepositToken(); - - // Payment should have been sent to seller - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, NewSupplyOwner.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDeposits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDeposits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("New owner should be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await utils.cancel(voucherID, NewSupplyOwner.address) - }) - - it("[NEGATIVE] Old owner should not be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await truffleAssert.reverts( - utils.cancel(voucherID, OldSupplyOwner.address), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKN_TKN", () => { - - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDeposits = new BN(0) - - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDeposits = new BN(0) - - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - const supplyQty = 1 - const tokensToMint = new BN(helpers.seller_deposit).mul(new BN(supplyQty)) - - await utils.mintTokens('contractBSNTokenDeposit', OldSupplyOwner.address, tokensToMint); - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, helpers.product_price); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, helpers.buyer_deposit); - - tokenSupplyKey = await utils.createOrder( - OldSupplyOwner, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - supplyQty - ) - - }) - - async function getBalancesFromPiceTokenAndDepositToken() { - - balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Buyer.address) - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Buyer.address) - - balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf(NewSupplyOwner.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(NewSupplyOwner.address) - - escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf(Deployer.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Deployer.address) - - cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf(utils.contractCashier.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf(utils.contractCashier.address) - - } - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) //// 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDeposits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDeposits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(ZERO), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(ZERO), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("New owner should be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await utils.cancel(voucherID, NewSupplyOwner.address) - }) - - it("[NEGATIVE] Old owner should not be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await truffleAssert.reverts( - utils.cancel(voucherID, OldSupplyOwner.address), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKN_ETH", () => { - let balanceBuyerFromPayment = new BN(0) - let balanceSellerFromPayment = new BN(0) - let escrowBalanceFromPayment = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, '') - - const timestamp = await Utils.getCurrTimestamp() - - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, helpers.product_price); - - tokenSupplyKey = await utils.createOrder( - OldSupplyOwner, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_1 - ) - }) - - async function getBalancesPriceToken() { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Buyer.address) - balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf(NewSupplyOwner.address) - escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf(Deployer.address) - cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf(utils.contractCashier.address) + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if price is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + const deadline = toWei(1) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_ETH_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address } - - it("Should update escrow amounts after transfer", async () => { - - expectedBalanceInEscrow = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_1)) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldSupplyOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewSupplyOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(ZERO), "New owner balance from escrow does not match") - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldSupplyOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewSupplyOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(ZERO), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerPrice = new BN(0) - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(0) - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy( - Buyer, - NewSupplyOwner, - tokenSupplyKey - ) - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - let withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, NewSupplyOwner.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("New owner should be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await utils.cancel(voucherID, NewSupplyOwner.address) - }) - - it("[NEGATIVE] Old owner should not be able to COF", async () => { - - utils.safeTransfer1155(OldSupplyOwner.address, NewSupplyOwner.address, tokenSupplyKey, helpers.QTY_1, {from: OldSupplyOwner.address}) - - const voucherID = await utils.commitToBuy(Buyer, NewSupplyOwner, tokenSupplyKey) - - await utils.redeem(voucherID, Buyer.address) - - await truffleAssert.reverts( - utils.cancel(voucherID, OldSupplyOwner.address), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - }) - }) - - describe("VOUCHER TRANSFER", () => { - - let OldVoucherOwner = config.accounts.randomUser - let NewVoucherOwner = config.accounts.randomUser2 - - let actualOldOwnerBalanceFromEscrow = new BN(0); - let actualNewOwnerBalanceFromEscrow = new BN(0); - let expectedBalanceInEscrow = new BN(0); - - afterEach(() => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - actualOldOwnerBalanceFromEscrow = new BN(0); - actualNewOwnerBalanceFromEscrow = new BN(0); - expectedBalanceInEscrow = new BN(0); - }) - - describe("Common transfer", () => { - - before(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier) - - tokenSupplyKey = await utils.createOrder(Seller, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.seller_deposit, helpers.QTY_10) - }) - - it("Should transfer a voucher", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - let transferTx = await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - truffleAssert.eventEmitted(transferTx, 'Transfer', (ev) => { - - assert.equal(ev._from, OldVoucherOwner.address) - assert.equal(ev._to, NewVoucherOwner.address) - assert.equal(ev._tokenId.toString(), voucherID) - - return true - }, "Transfer not emitted") - }) - }) - - describe("ETH_ETH", async () => { - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier) - - tokenSupplyKey = await utils.createOrder(Seller, helpers.PROMISE_VALID_FROM, helpers.PROMISE_VALID_TO, helpers.seller_deposit, helpers.QTY_10) - }) - - it("Should update escrow amounts after transfer", async () => { - - expectedBalanceInEscrow = new BN(helpers.product_price).add(new BN(helpers.buyer_deposit)) - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldVoucherOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewVoucherOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(ZERO), "New owner balance from escrow does not match") - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldVoucherOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewVoucherOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(ZERO), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerAmount = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.3 + 0.04 + 0.025 - const expectedSellerAmount = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmount = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - await utils.refund(voucherID, NewVoucherOwner.address) - await utils.complain(voucherID, NewVoucherOwner.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', NewVoucherOwner.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - await truffleAssert.reverts( - utils.redeem(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - await truffleAssert.reverts( - utils.refund(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await truffleAssert.reverts( - utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("[WITH PERMIT]", () => { - - describe("ETH_TKN", () => { - let balanceBuyerFromDeposits = new BN(0) - let balanceSellerFromDeposits = new BN(0) - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - - async function getBalancesDepositToken() { - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(NewVoucherOwner.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Seller.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Deployer.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf(utils.contractCashier.address) - } - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - const supplyQty = 1 - const tokensToMint = new BN(helpers.seller_deposit).mul(new BN(supplyQty)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', OldVoucherOwner.address, helpers.buyer_deposit); - - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - supplyQty - ) - }) - - afterEach(async () => { - - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyerFromPayment = new BN(0) - balanceBuyerFromDeposits = new BN(0) - - balanceSellerFromPayment = new BN(0) - balanceSellerFromDeposits = new BN(0) - - escrowBalanceFromPayment = new BN(0) - escrowBalanceFromDeposits = new BN(0) - - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) - - const isPaused = await contractCashier.paused(); - if (isPaused) { - await contractCashier.unpause(); - } - - }) - - it("Should update escrow amounts after transfer", async () => { - - expectedBalanceInEscrow = new BN(helpers.product_price) - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldVoucherOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewVoucherOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(ZERO), "New owner balance from escrow does not match") - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldVoucherOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewVoucherOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(ZERO), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - await utils.refund(voucherID, NewVoucherOwner.address) - await utils.complain(voucherID, NewVoucherOwner.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - await getBalancesDepositToken(); - - // Payment should have been returned to buyer - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, NewVoucherOwner.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogAmountDistribution was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDeposits.eq(expectedBuyerDeposit), "NewVoucherOwner did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDeposits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', NewVoucherOwner.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - await truffleAssert.reverts( - utils.redeem(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - await truffleAssert.reverts( - utils.refund(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await truffleAssert.reverts( - utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKN_TKN", () => { - - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDeposits = new BN(0) - - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDeposits = new BN(0) - - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - - async function getBalancesFromPiceTokenAndDepositToken() { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf(NewVoucherOwner.address) - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(NewVoucherOwner.address) - - balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Seller.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Seller.address) - - escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf(Deployer.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Deployer.address) - - cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf(utils.contractCashier.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf(utils.contractCashier.address) + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositBu is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + const deadline = toWei(1) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_TOKEN_LIMIT, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address } - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - const supplyQty = 1 - const tokensToMint = new BN(helpers.seller_deposit).mul(new BN(supplyQty)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenPrice', OldVoucherOwner.address, helpers.product_price); - await utils.mintTokens('contractBSNTokenDeposit', OldVoucherOwner.address, helpers.buyer_deposit); - - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - supplyQty - ) - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountPrice = new BN(0) - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - await utils.refund(voucherID, NewVoucherOwner.address) - await utils.complain(voucherID, NewVoucherOwner.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDeposits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDeposits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}) - - await truffleAssert.reverts( - utils.redeem(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - await truffleAssert.reverts( - utils.refund(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await truffleAssert.reverts( - utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKN_ETH", () => { - - let balanceBuyerFromPayment = new BN(0) - let balanceSellerFromPayment = new BN(0) - let escrowBalanceFromPayment = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - beforeEach(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, '') - - const timestamp = await Utils.getCurrTimestamp() - - await utils.mintTokens('contractBSNTokenPrice', OldVoucherOwner.address, helpers.product_price); - - tokenSupplyKey = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_1 - ) - - }) - - async function getBalancesPriceToken() { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf(NewVoucherOwner.address) - balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Seller.address) - escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf(Deployer.address) - cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf(utils.contractCashier.address) + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositSe is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + const deadline = toWei(1) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_TOKEN_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address } - - it("Should update escrow amounts after transfer", async () => { - - expectedBalanceInEscrow = new BN(helpers.buyer_deposit) - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldVoucherOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewVoucherOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(ZERO), "New owner balance from escrow does not match") - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}), - - actualOldOwnerBalanceFromEscrow = await contractCashier.escrow(OldVoucherOwner.address) - actualNewOwnerBalanceFromEscrow = await contractCashier.escrow(NewVoucherOwner.address) - - assert.isTrue(actualOldOwnerBalanceFromEscrow.eq(ZERO), "Old owner balance from escrow does not match") - assert.isTrue(actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", async () => { - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}), - - await utils.refund(voucherID, NewVoucherOwner.address) - await utils.complain(voucherID, NewVoucherOwner.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await utils.withdraw(voucherID, Deployer.address); - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', NewVoucherOwner.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: OldVoucherOwner.address}), - - await truffleAssert.reverts( - utils.redeem(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - await truffleAssert.reverts( - utils.refund(voucherID, OldVoucherOwner.address), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", async () => { - - voucherID = await utils.commitToBuy(OldVoucherOwner, Seller, tokenSupplyKey) - - await truffleAssert.reverts( - utils.safeTransfer721(OldVoucherOwner.address, NewVoucherOwner.address, voucherID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - }) - - }) -}); - - - - - - + ), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("TKN_ETH", () => { + before(async () => { + await deployContracts() + + utils = UtilsBuilder + .create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '') + + timestamp = await Utils.getCurrTimestamp() + + const tokensToMint = + new BN(constants.product_price).mul(new BN(constants.QTY_10)) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMint) + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + it("ESCROW has correct initial balance", async () => { + const expectedBalance = + new BN(constants.seller_deposit).mul(new BN(remQty)) + const escrowAmount = await contractCashier + .getEscrowAmount(users.seller.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") + }) + + it("Get correct remaining qty for supply", async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + remQty, + "Remaining qty is not correct") + + for (let i = 0; i < vouchersToBuy; i++) { + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) + remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + --remQty, + "Remaining qty is not correct") + } + }) + + it("Should create payment method TKN_ETH", async () => { + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ) + + const paymentDetails = await contractVoucherKernel + .paymentDetails(tokenSupplyKey) + + assert.equal( + paymentDetails.paymentMethod.toString(), + paymentMethods.TKN_ETH, + "Payment Method TKN_ETH not set correctly") + assert.equal( + paymentDetails.addressTokenPrice.toString(), + contractBSNTokenPrice.address, + "TKN_ETH Method Price Token Address mismatch") + assert.equal( + paymentDetails.addressTokenDeposits.toString(), + constants.ZERO_ADDRESS, + "TKN_ETH Method Deposit Token Address mismatch") + }) + + it("[NEGATIVE] Should fail if price token contract address is not provided", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + await truffleAssert.fails( + contractCashier.requestCreateOrder_TKN_ETH( + '', + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, + value: txValue.toString() + } + ) + ) + }) + + it("[NEGATIVE] Should fail if token price contract is zero address", + async () => { + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_ETH( + constants.ZERO_ADDRESS, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if price is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_ETH( + contractBSNTokenPrice.address, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_TOKEN_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, value: txValue.toString() + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositBu is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_ETH( + contractBSNTokenPrice.address, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_ETH_LIMIT, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, + value: txValue.toString() + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositSe is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_ETH( + contractBSNTokenPrice.address, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_ETH_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address, + value: txValue.toString() + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("TKN_TKN", () => { + before(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + timestamp = await Utils.getCurrTimestamp() + + const tokensToMint = + new BN(constants.product_price).mul(new BN(constants.QTY_20)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMint) + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + it("ESCROW has correct initial balance", async () => { + const expectedBalance = + new BN(constants.seller_deposit).mul(new BN(remQty)) + const escrowAmount = await contractBSNTokenDeposit + .balanceOf(contractCashier.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") + }) + + it("Get correct remaining qty for supply", async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + remQty, + "Remaining qty is not correct") + + for (let i = 0; i < vouchersToBuy; i++) { + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) + remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + + assert.equal( + remainingQtyInContract, + --remQty, + "Remaining qty is not correct") + } + }) + + it("Should create payment method TKN_TKN", async () => { + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ) + + const paymentDetails = await contractVoucherKernel + .paymentDetails(tokenSupplyKey) + + assert.equal( + paymentDetails.paymentMethod.toString(), + paymentMethods.TKN_TKN, + "Payment Method TKN_TKN not set correctly") + assert.equal( + paymentDetails.addressTokenPrice.toString(), + contractBSNTokenPrice.address, + "TKN_TKN Method Price Token Address mismatch") + assert.equal( + paymentDetails.addressTokenDeposits.toString(), + contractBSNTokenDeposit.address, + "TKN_TKN Method Deposit Token Address mismatch") + }) + + it("[NEGATIVE] Should fail if token price contract address is not provided", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.fails( + contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + '', + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ) + ) + + }) + + it("[NEGATIVE] Should fail if token deposit contract address is not provided", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.fails( + contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractBSNTokenPrice.address, + '', + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ) + ) + + }) + + it("[NEGATIVE] Should revert if token price contract address is zero address", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + constants.ZERO_ADDRESS, + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ), + truffleAssert.ErrorType.REVERT + ) + + }) + + it("[NEGATIVE] Should revert if token deposit contract address is zero address", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + const deadline = toWei(1) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractBSNTokenPrice.address, + constants.ZERO_ADDRESS, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ), + truffleAssert.ErrorType.REVERT + ) + + }) + + it("[NEGATIVE] Should not create a supply if price is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractBSNTokenPrice.address, + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_TOKEN_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositBu is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractBSNTokenPrice.address, + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_TOKEN_LIMIT, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create a supply if depositSe is above the limit", + async () => { + const txValue = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + const nonce = await contractBSNTokenDeposit + .nonces(users.seller.address) + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractBSNTokenPrice.address, + contractBSNTokenDeposit.address, + txValue, + deadline, + v, r, s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_TOKEN_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1 + ], { + from: users.seller.address + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + }) + }) + }) + + describe("VOUCHER CREATION (Commit to buy)", () => { + const ORDER_QTY = 5 + let TOKEN_SUPPLY_ID + + before(async () => { + await deployContracts() + }) + + describe("ETH_ETH", async () => { + before(async () => { + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + constants.QTY_10) + }) + + it("Should create order", async () => { + const txValue = + new BN(constants.buyer_deposit).add(new BN(constants.product_price)) + let txFillOrder = await contractCashier + .requestVoucher_ETH_ETH( + TOKEN_SUPPLY_ID, + users.seller.address, + { + from: users.buyer.address, + value: txValue + }) + + let internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey = ev._tokenIdVoucher + return ev._issuer === users.seller.address + }, "order1 not created successfully") + }) + + it("[NEGATIVE] Should not create order with incorrect price", + async () => { + const txValue = + new BN(constants.buyer_deposit) + .add(new BN(constants.incorrect_product_price)) + + await truffleAssert.reverts( + contractCashier.requestVoucher_ETH_ETH( + TOKEN_SUPPLY_ID, + users.seller.address, + { + from: users.buyer.address, + value: txValue + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create order with incorrect deposit", + async () => { + const txValue = + new BN(constants.buyer_incorrect_deposit) + .add(new BN(constants.product_price)) + + await truffleAssert.reverts( + contractCashier.requestVoucher_ETH_ETH( + TOKEN_SUPPLY_ID, + users.seller.address, + { + from: users.buyer.address, + value: txValue + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("[WITH PERMIT]", () => { + describe("ETH_TKN", async () => { + before(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const tokensToMintSeller = + new BN(constants.seller_deposit).mul(new BN(ORDER_QTY)) + const tokensToMintBuyer = + new BN(constants.buyer_deposit).mul(new BN(ORDER_QTY)) + + await contractBSNTokenDeposit + .mint(users.seller.address, tokensToMintSeller) + await contractBSNTokenDeposit + .mint(users.buyer.address, tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + ORDER_QTY + ) + }) + + it("Should create order", async () => { + const nonce = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + const txFillOrder = await contractCashier + .requestVoucher_ETH_TKN_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.buyer_deposit, + deadline, + v, r, s, + { + from: users.buyer.address, + value: constants.product_price + } + ) + + let internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey = ev._tokenIdVoucher + return ev._issuer === users.seller.address + }, "order1 not created successfully") + }) + + it("[NEGATIVE] Should not create order with incorrect price", + async () => { + const nonce = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestVoucher_ETH_TKN_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.buyer_deposit, + deadline, + v, r, s, + { + from: users.buyer.address, + value: constants.incorrect_product_price + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create order with incorrect deposit", + async () => { + const nonce = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestVoucher_ETH_TKN_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.buyer_incorrect_deposit, + deadline, + v, r, s, + { + from: users.buyer.address, + value: constants.product_price + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("TKN_TKN", () => { + before(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const tokensToMintSeller = + new BN(constants.seller_deposit).mul(new BN(ORDER_QTY)) + const tokensToMintBuyer = + new BN(constants.product_price).mul(new BN(ORDER_QTY)) + + await contractBSNTokenDeposit + .mint(users.seller.address, tokensToMintSeller) + await contractBSNTokenDeposit + .mint(users.buyer.address, tokensToMintBuyer) + await contractBSNTokenPrice + .mint(users.buyer.address, tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + ORDER_QTY + ) + }) + + it("Should create order", async () => { + const nonce1 = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const tokensToSend = + new BN(constants.product_price) + .add(new BN(constants.buyer_deposit)) + + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce1, + deadline + ) + + let VRS_DEPOSIT = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let vDeposit = VRS_DEPOSIT.v + let rDeposit = VRS_DEPOSIT.r + let sDeposit = VRS_DEPOSIT.s + + const nonce2 = await contractBSNTokenPrice.nonces(users.buyer.address) + + const digestPrice = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce2, + deadline + ) + + let VRS_PRICE = ecsign( + Buffer.from(digestPrice.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let vPrice = VRS_PRICE.v + let rPrice = VRS_PRICE.r + let sPrice = VRS_PRICE.s + + let txFillOrder = await contractCashier + .requestVoucher_TKN_TKN_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + vPrice, rPrice, sPrice, + vDeposit, rDeposit, sDeposit, + { + from: users.buyer.address + }) + + let internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey = ev._tokenIdVoucher + return ev._issuer === users.seller.address + }, "order1 not created successfully") + }) + + it("[NEGATIVE] Should not create order with incorrect price", + async () => { + const nonce1 = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const tokensToSend = + new BN(constants.incorrect_product_price) + .add(new BN(constants.buyer_deposit)) + + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce1, + deadline + ) + + let VRS_DEPOSIT = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let vDeposit = VRS_DEPOSIT.v + let rDeposit = VRS_DEPOSIT.r + let sDeposit = VRS_DEPOSIT.s + + const nonce2 = await contractBSNTokenPrice + .nonces(users.buyer.address) + + const digestPrice = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce2, + deadline + ) + + let VRS_PRICE = ecsign( + Buffer.from(digestPrice.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let vPrice = VRS_PRICE.v + let rPrice = VRS_PRICE.r + let sPrice = VRS_PRICE.s + + await truffleAssert.reverts( + contractCashier.requestVoucher_TKN_TKN_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + vPrice, rPrice, sPrice, + vDeposit, rDeposit, sDeposit, + { + from: users.buyer.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create order with incorrect deposit", + async () => { + const nonce1 = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const tokensToSend = + new BN(constants.product_price) + .add(new BN(constants.buyer_incorrect_deposit)) + + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce1, + deadline + ) + + let VRS_DEPOSIT = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let vDeposit = VRS_DEPOSIT.v + let rDeposit = VRS_DEPOSIT.r + let sDeposit = VRS_DEPOSIT.s + + const nonce2 = await contractBSNTokenPrice + .nonces(users.buyer.address) + + const digestPrice = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce2, + deadline + ) + + let VRS_PRICE = ecsign( + Buffer.from(digestPrice.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let vPrice = VRS_PRICE.v + let rPrice = VRS_PRICE.r + let sPrice = VRS_PRICE.s + + await truffleAssert.reverts( + contractCashier.requestVoucher_TKN_TKN_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + vPrice, rPrice, sPrice, + vDeposit, rDeposit, sDeposit, + { + from: users.buyer.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + }) + + // Ignored due to deployment failure. + xdescribe("TKN_TKN_SAME", () => { + const tokensToMintSeller = + new BN(constants.seller_deposit) + .mul(new BN(ORDER_QTY)) + const tokensToMintBuyer = + new BN(constants.product_price) + .mul(new BN(ORDER_QTY)) + + before(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN_SAME() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + await utils.contractBSNTokenSAME + .mint(users.seller.address, tokensToMintSeller) + await utils.contractBSNTokenSAME + .mint(users.buyer.address, tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + ORDER_QTY + ) + }) + + it("Should create voucher", async () => { + const nonce = await utils.contractBSNTokenSAME + .nonces(users.buyer.address) + const tokensToSend = + new BN(constants.product_price) + .add(new BN(constants.buyer_deposit)) + + const digestTokens = await getApprovalDigest( + utils.contractBSNTokenSAME, + users.buyer.address, + contractCashier.address, + tokensToSend, + nonce, + deadline + ) + + let VRS_TOKENS = ecsign( + Buffer.from(digestTokens.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let v = VRS_TOKENS.v + let r = VRS_TOKENS.r + let s = VRS_TOKENS.s + + let txFillOrder = await contractCashier + .requestVoucher_TKN_TKN_Same_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + v, r, s, + { + from: users.buyer.address + }) + + let internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey1 = ev._tokenIdVoucher + return ev._issuer === users.seller.address + }, "order1 not created successfully") + }) + + it("[NEGATIVE] Should not create order with incorrect price", + async () => { + const nonce = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const incorrectTokensToSign = + new BN(constants.incorrect_product_price) + .add(new BN(constants.buyer_deposit)) + const digestTokens = await getApprovalDigest( + utils.contractBSNTokenSAME, + users.buyer.address, + contractCashier.address, + incorrectTokensToSign, + nonce, + deadline + ) + + let VRS_TOKENS = ecsign( + Buffer.from(digestTokens.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let v = VRS_TOKENS.v + let r = VRS_TOKENS.r + let s = VRS_TOKENS.s + + await truffleAssert.reverts( + contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + incorrectTokensToSign, + deadline, + v, r, s, + { + from: users.buyer.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create order with incorrect deposit", + async () => { + const nonce = await contractBSNTokenDeposit + .nonces(users.buyer.address) + const incorrectTokensToSign = + new BN(constants.product_price) + .add(new BN(constants.buyer_incorrect_deposit)) + const digestTokens = await getApprovalDigest( + utils.contractBSNTokenSAME, + users.buyer.address, + contractCashier.address, + incorrectTokensToSign, + nonce, + deadline + ) + + let VRS_TOKENS = ecsign( + Buffer.from(digestTokens.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let v = VRS_TOKENS.v + let r = VRS_TOKENS.r + let s = VRS_TOKENS.s + + await truffleAssert.reverts( + contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + incorrectTokensToSign, + deadline, + v, r, s, + { + from: users.buyer.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should revert if Price Token and Deposit Token are diff contracts", + async () => { + let utilsTKN_TKN = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + await contractBSNTokenDeposit + .mint(users.seller.address, tokensToMintSeller) + await contractBSNTokenDeposit + .mint(users.buyer.address, tokensToMintBuyer) + await contractBSNTokenPrice + .mint(users.buyer.address, tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utilsTKN_TKN.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + ORDER_QTY + ) + + const nonce = await utils.contractBSNTokenSAME + .nonces(users.buyer.address) + const tokensToSend = + new BN(constants.product_price) + .add(new BN(constants.buyer_deposit)) + + const digestTokens = await getApprovalDigest( + utils.contractBSNTokenSAME, + users.buyer.address, + contractCashier.address, + tokensToSend, + nonce, + deadline + ) + + let VRS_TOKENS = ecsign( + Buffer.from(digestTokens.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let v = VRS_TOKENS.v + let r = VRS_TOKENS.r + let s = VRS_TOKENS.s + + await truffleAssert.reverts( + contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + v, r, s, + { + from: users.buyer.address + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("TKN_ETH", () => { + before(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const tokensToMintBuyer = + new BN(constants.product_price).mul(new BN(ORDER_QTY)) + + await contractBSNTokenPrice + .mint(users.buyer.address, tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + ORDER_QTY + ) + }) + + it("Should create order", async () => { + const nonce = await contractBSNTokenPrice + .nonces(users.buyer.address) + + const digestDeposit = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce, + deadline + ) + + let { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + let txFillOrder = await contractCashier + .requestVoucher_TKN_ETH_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.product_price, + deadline, + v, r, s, + { + from: users.buyer.address, + value: constants.buyer_deposit + } + ) + + let internalTx = await truffleAssert + .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey = ev._tokenIdVoucher + return ev._issuer === users.seller.address + }, "order1 not created successfully") + }) + + it("[NEGATIVE] Should not create order with incorrect deposit", + async () => { + const nonce = await contractBSNTokenPrice + .nonces(users.buyer.address) + + const digestDeposit = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce, + deadline + ) + + let { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestVoucher_TKN_ETH_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.product_price, + deadline, + v, r, s, + { + from: users.buyer.address, + value: constants.buyer_incorrect_deposit + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not create order with incorrect price", + async () => { + const nonce = await contractBSNTokenPrice + .nonces(users.buyer.address) + + const digestDeposit = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce, + deadline + ) + + let { v, r, s } = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts( + contractCashier.requestVoucher_TKN_ETH_WithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.incorrect_product_price, + deadline, + v, r, s, + { + from: users.buyer.address, + value: constants.buyer_deposit + } + ), + truffleAssert.ErrorType.REVERT + ) + }) + }) + }) + }) + + describe("TOKEN SUPPLY TRANSFER", () => { + let actualOldOwnerBalanceFromEscrow = new BN(0) + let actualNewOwnerBalanceFromEscrow = new BN(0) + let expectedBalanceInEscrow = new BN(0) + + afterEach(() => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } + }) + + describe("Common transfer", () => { + + beforeEach(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + const timestamp = await Utils.getCurrTimestamp() + + tokenSupplyKey = await utils.createOrder( + users.other1, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) + + it("Should transfer voucher supply", async () => { + let transferTx = await utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_10, { + from: users.other1.address + }) + + truffleAssert.eventEmitted( + transferTx, + 'TransferSingle', + (ev) => { + assert.equal(ev._from, users.other1.address) + assert.equal(ev._to, users.other2.address) + assert.equal(ev._id.toString(), tokenSupplyKey) + assert.equal(ev._value.toString(), constants.QTY_10) + + return true + }, "TransferSingle not emitted") + + }) + + it("[NEGATIVE] Should revert if owner tries to transfer voucher supply partially", + async () => { + await truffleAssert.reverts( + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should revert if Attacker tries to transfer voucher supply", + async () => { + await truffleAssert.reverts( + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_10, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("Should transfer batch voucher supply", async () => { + let transferTx = await utils.safeBatchTransfer1155( + users.other1.address, + users.other2.address, + [ tokenSupplyKey ], + [ constants.QTY_10 ], { + from: users.other1.address + }) + + truffleAssert.eventEmitted( + transferTx, + 'TransferBatch', + (ev) => { + assert.equal(ev._from, users.other1.address) + assert.equal(ev._to, users.other2.address) + assert.equal( + JSON.stringify(ev._ids), + JSON.stringify([ new BN(tokenSupplyKey) ])) + assert.equal( + JSON.stringify(ev._values), + JSON.stringify([ new BN(constants.QTY_10) ])) + + return true + }, "TransferSingle not emitted") + }) + + it("[NEGATIVE] Should revert if owner tries to transfer voucher supply batch partially", + async () => { + await truffleAssert.reverts( + utils.safeBatchTransfer1155( + users.other1.address, + users.other2.address, + [ tokenSupplyKey ], + [ constants.QTY_1 ], { + from: users.other1.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should revert if Attacker tries to transfer batch voucher supply", + async () => { + await truffleAssert.reverts( + utils.safeBatchTransfer1155( + users.other1.address, + users.other2.address, + [ tokenSupplyKey ], + [ constants.QTY_10 ], { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("ETH_ETH", () => { + beforeEach(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + tokenSupplyKey = await utils.createOrder( + users.other1, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + constants.QTY_1) + }) + + it("Should update escrow amounts after transfer", async () => { + expectedBalanceInEscrow = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(ZERO), + "New owner balance from escrow does not match") + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(ZERO), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "New owner balance from escrow does not match") + }) + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + // 0.04 + const expectedBuyerAmount = + new BN(constants.buyer_deposit) + // 0.35 + const expectedSellerAmount = + new BN(constants.seller_deposit) + .add(new BN(constants.product_price)) + // 0 + const expectedEscrowAmount = new BN(0) + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + let withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.other2.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) + + it("New owner should be able to COF", async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await utils.cancel(voucherID, users.other2.address) + }) + + it("[NEGATIVE] Old owner should not be able to COF", async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await truffleAssert.reverts( + utils.cancel(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("[WITH PERMIT]", () => { + describe("ETH_TKN", () => { + let balanceBuyerFromDeposits = new BN(0) + + let balanceSellerFromDeposits = new BN(0) + + let escrowBalanceFromDeposits = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + beforeEach(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + const tokensToMint = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.other1.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + constants.buyer_deposit) + + tokenSupplyKey = await utils.createOrder( + users.other1, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ) + }) + + async function getBalancesDepositToken () { + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.buyer.address) + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.other2.address) + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.deployer.address) + cashierDepositLeft = await utils.contractBSNTokenDeposit + .balanceOf(utils.contractCashier.address) + } + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN(0) + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ) + + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + let withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + await getBalancesDepositToken() + + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.other2.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedSellerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("New owner should be able to COF", async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await utils.cancel(voucherID, users.other2.address) + }) + + it("[NEGATIVE] Old owner should not be able to COF", + async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await truffleAssert.reverts( + utils.cancel(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("TKN_TKN", () => { + let balanceBuyerFromPayment = new BN(0) + let balanceBuyerFromDeposits = new BN(0) + + let balanceSellerFromPayment = new BN(0) + let balanceSellerFromDeposits = new BN(0) + + let escrowBalanceFromPayment = new BN(0) + let escrowBalanceFromDeposits = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + beforeEach(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + const supplyQty = 1 + const tokensToMint = + new BN(constants.seller_deposit).mul(new BN(supplyQty)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.other1.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + constants.product_price) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + constants.buyer_deposit) + + tokenSupplyKey = await utils.createOrder( + users.other1, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ) + + }) + + async function getBalancesFromPriceTokenAndDepositToken () { + + balanceBuyerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.buyer.address) + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.buyer.address) + + balanceSellerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.other2.address) + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.other2.address) + + escrowBalanceFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.deployer.address) + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.deployer.address) + + cashierPaymentLeft = await utils.contractBSNTokenPrice + .balanceOf(utils.contractCashier.address) + cashierDepositLeft = await utils.contractBSNTokenDeposit + .balanceOf(utils.contractCashier.address) + } + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + const expectedBuyerPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN(0) + const expectedEscrowAmountPrice = new BN(0) + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(ZERO), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(ZERO), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("New owner should be able to COF", async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await utils.cancel(voucherID, users.other2.address) + }) + + it("[NEGATIVE] Old owner should not be able to COF", + async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await truffleAssert.reverts( + utils.cancel(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("TKN_ETH", () => { + let balanceBuyerFromPayment = new BN(0) + let balanceSellerFromPayment = new BN(0) + let escrowBalanceFromPayment = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + beforeEach(async () => { + + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '') + + const timestamp = await Utils.getCurrTimestamp() + + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + constants.product_price) + + tokenSupplyKey = await utils.createOrder( + users.other1, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ) + }) + + async function getBalancesPriceToken () { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.buyer.address) + balanceSellerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.other2.address) + escrowBalanceFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.deployer.address) + cashierPaymentLeft = await utils.contractBSNTokenPrice + .balanceOf(utils.contractCashier.address) + } + + it("Should update escrow amounts after transfer", async () => { + expectedBalanceInEscrow = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(ZERO), + "New owner balance from escrow does not match") + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(ZERO), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "New owner balance from escrow does not match") + }) + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + const expectedBuyerPrice = new BN(0) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedEscrowPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN(0) + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ) + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + let withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been sent to seller + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + //Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.other2.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + //Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("New owner should be able to COF", async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await utils.cancel(voucherID, users.other2.address) + }) + + it("[NEGATIVE] Old owner should not be able to COF", + async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, { + from: users.other1.address + }) + + const voucherID = await utils + .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + + await utils.redeem(voucherID, users.buyer.address) + + await truffleAssert.reverts( + utils.cancel(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) + }) + }) + + describe("VOUCHER TRANSFER", () => { + let actualOldOwnerBalanceFromEscrow = new BN(0) + let actualNewOwnerBalanceFromEscrow = new BN(0) + let expectedBalanceInEscrow = new BN(0) + + afterEach(() => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } + + actualOldOwnerBalanceFromEscrow = new BN(0) + actualNewOwnerBalanceFromEscrow = new BN(0) + expectedBalanceInEscrow = new BN(0) + }) + + describe("Common transfer", () => { + + before(async () => { + + await deployContracts() + + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + tokenSupplyKey = await utils + .createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + constants.QTY_10) + }) + + it("Should transfer a voucher", async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey) + + let transferTx = await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + truffleAssert.eventEmitted( + transferTx, + 'Transfer', + (ev) => { + assert.equal(ev._from, users.other1.address) + assert.equal(ev._to, users.other2.address) + assert.equal(ev._tokenId.toString(), voucherID) + + return true + }, "Transfer not emitted") + }) + }) + + describe("ETH_ETH", async () => { + beforeEach(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + tokenSupplyKey = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + constants.QTY_10) + }) + + it("Should update escrow amounts after transfer", async () => { + expectedBalanceInEscrow = + new BN(constants.product_price) + .add(new BN(constants.buyer_deposit)) + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(ZERO), + "New owner balance from escrow does not match") + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, voucherID, { + from: users.other1.address + }) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(ZERO), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "New owner balance from escrow does not match") + }) + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = + new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.0125 + const expectedSellerAmount = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmount = + new BN(constants.seller_deposit).div(new BN(4)) + + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await utils.refund(voucherID, users.other2.address) + await utils.complain(voucherID, users.other2.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.other2.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) + + it("[NEGATIVE] Old owner should not be able to interact with the voucher", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await truffleAssert.reverts( + utils.redeem(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + + await truffleAssert.reverts( + utils.refund(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await truffleAssert.reverts( + utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("[WITH PERMIT]", () => { + describe("ETH_TKN", () => { + let balanceBuyerFromDeposits = new BN(0) + let balanceSellerFromDeposits = new BN(0) + let escrowBalanceFromDeposits = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + async function getBalancesDepositToken () { + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.other2.address) + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.seller.address) + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.deployer.address) + cashierDepositLeft = await utils.contractBSNTokenDeposit + .balanceOf(utils.contractCashier.address) + } + + beforeEach(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + const supplyQty = 1 + const tokensToMint = + new BN(constants.seller_deposit).mul(new BN(supplyQty)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.other1.address, + constants.buyer_deposit) + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ) + }) + + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } + + balanceBuyerFromPayment = new BN(0) + balanceBuyerFromDeposits = new BN(0) + + balanceSellerFromPayment = new BN(0) + balanceSellerFromDeposits = new BN(0) + + escrowBalanceFromPayment = new BN(0) + escrowBalanceFromDeposits = new BN(0) + + cashierPaymentLeft = new BN(0) + cashierDepositLeft = new BN(0) + + const isPaused = await contractCashier.paused() + if (isPaused) { + await contractCashier.unpause() + } + }) + + it("Should update escrow amounts after transfer", + async () => { + expectedBalanceInEscrow = new BN(constants.product_price) + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(ZERO), + "New owner balance from escrow does not match") + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(ZERO), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "New owner balance from escrow does not match") + }) + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await utils.refund(voucherID, users.other2.address) + await utils.complain(voucherID, users.other2.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + await getBalancesDepositToken() + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.other2.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedBuyerPrice)) + + return true + }, "Event LogAmountDistribution was not emitted") + + //Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "NewVoucherOwner did not get expected tokens from " + + "DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + //Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.other2.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + }) + + it("[NEGATIVE] Old owner should not be able to interact with the voucher", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await truffleAssert.reverts( + utils.redeem(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + + await truffleAssert.reverts( + utils.refund(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await truffleAssert.reverts( + utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("TKN_TKN", () => { + let balanceBuyerFromPayment = new BN(0) + let balanceBuyerFromDeposits = new BN(0) + + let balanceSellerFromPayment = new BN(0) + let balanceSellerFromDeposits = new BN(0) + + let escrowBalanceFromPayment = new BN(0) + let escrowBalanceFromDeposits = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + async function getBalancesFromPriceTokenAndDepositToken () { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.other2.address) + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.other2.address) + + balanceSellerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.seller.address) + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.seller.address) + + escrowBalanceFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.deployer.address) + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.deployer.address) + + cashierPaymentLeft = await utils.contractBSNTokenPrice + .balanceOf(utils.contractCashier.address) + cashierDepositLeft = await utils.contractBSNTokenDeposit + .balanceOf(utils.contractCashier.address) + } + + beforeEach(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + const supplyQty = 1 + const tokensToMint = + new BN(constants.seller_deposit).mul(new BN(supplyQty)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.other1.address, + constants.product_price) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.other1.address, + constants.buyer_deposit) + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ) + }) + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedSellerPrice = new BN(0) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + const expectedEscrowAmountPrice = new BN(0) + + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await utils.refund(voucherID, users.other2.address) + await utils.complain(voucherID, users.other2.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("[NEGATIVE] Old owner should not be able to interact with the voucher", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await truffleAssert.reverts( + utils.redeem(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + + await truffleAssert.reverts( + utils.refund(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + + }) + + it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await truffleAssert.reverts( + utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + }) + + describe("TKN_ETH", () => { + let balanceBuyerFromPayment = new BN(0) + let balanceSellerFromPayment = new BN(0) + let escrowBalanceFromPayment = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + beforeEach(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '') + + const timestamp = await Utils.getCurrTimestamp() + + await utils.mintTokens( + 'contractBSNTokenPrice', + users.other1.address, + constants.product_price) + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ) + }) + + async function getBalancesPriceToken () { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.other2.address) + balanceSellerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.seller.address) + escrowBalanceFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.deployer.address) + cashierPaymentLeft = await utils.contractBSNTokenPrice + .balanceOf(utils.contractCashier.address) + } + + it("Should update escrow amounts after transfer", async () => { + expectedBalanceInEscrow = new BN(constants.buyer_deposit) + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(ZERO), + "New owner balance from escrow does not match") + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + actualOldOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other1.address) + actualNewOwnerBalanceFromEscrow = await contractCashier + .escrow(users.other2.address) + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(ZERO), + "Old owner balance from escrow does not match") + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + "New owner balance from escrow does not match") + }) + + it("Should finalize 1 voucher to ensure payments are sent to the new owner", + async () => { + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedSellerPrice = new BN(0) + const expectedEscrowPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await utils.refund(voucherID, users.other2.address) + await utils.complain(voucherID, users.other2.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await utils + .withdraw(voucherID, users.deployer.address) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.other2.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("[NEGATIVE] Old owner should not be able to interact with the voucher", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.other1.address + }) + + await truffleAssert.reverts( + utils.redeem(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + + await truffleAssert.reverts( + utils.refund(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", + async () => { + voucherID = await utils + .commitToBuy(users.other1, users.seller, tokenSupplyKey) + + await truffleAssert.reverts( + utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + }) + }) +}) diff --git a/test/3_withdrawals.js b/test/3_withdrawals.js index 89dbf9db..f6a3eeb2 100644 --- a/test/3_withdrawals.js +++ b/test/3_withdrawals.js @@ -1,2567 +1,3986 @@ const chai = require('chai') -const assert = chai.assert +const truffleAssert = require('truffle-assertions') -const BN = web3.utils.BN +const constants = require("../testHelpers/constants") +const timemachine = require('../testHelpers/timemachine') +const Users = require('../testHelpers/users') const UtilsBuilder = require('../testHelpers/utilsBuilder') const Utils = require('../testHelpers/utils') -let utils + +const assert = chai.assert + +const BN = web3.utils.BN const ERC1155ERC721 = artifacts.require("ERC1155ERC721") const VoucherKernel = artifacts.require("VoucherKernel") const Cashier = artifacts.require("Cashier") const BosonTKN = artifacts.require("BosonTokenPrice") -const FundLimitsOracle = artifacts.require('FundLimitsOracle'); +const FundLimitsOracle = artifacts.require('FundLimitsOracle') -const helpers = require("../testHelpers/constants") -const timemachine = require('../testHelpers/timemachine') -const truffleAssert = require('truffle-assertions') -const config = require('../testHelpers/config.json') +let utils let TOKEN_SUPPLY_ID -contract("Cashier withdrawals ", async accounts => { - - let Deployer = config.accounts.deployer - let Seller = config.accounts.seller - let Buyer = config.accounts.buyer - let Attacker = config.accounts.attacker - let RandomUser = config.accounts.randomUser // will be used to clear tokens received after every successful test - - let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit,contractFundLimitsOracle - const PAUSED_WITHPERMIT = 1; - const PAUSED_LABEL = "[PAUSED]"; - - let distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) +contract("Cashier withdrawals ", async addresses => { + const users = new Users(addresses) + + let contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit, + contractFundLimitsOracle + + const PAUSED_WITH_PERMIT = 1 + const PAUSED_LABEL = "[PAUSED]" + + let distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } + + async function deployContracts () { + const sixtySeconds = 60 + + contractFundLimitsOracle = await FundLimitsOracle.new() + contractERC1155ERC721 = await ERC1155ERC721.new() + contractVoucherKernel = + await VoucherKernel.new(contractERC1155ERC721.address) + contractCashier = await Cashier.new( + contractVoucherKernel.address, + contractERC1155ERC721.address, + contractFundLimitsOracle.address) + contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC') + contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP') + + await contractERC1155ERC721 + .setApprovalForAll(contractVoucherKernel.address, 'true') + await contractERC1155ERC721 + .setVoucherKernelAddress(contractVoucherKernel.address) + await contractVoucherKernel + .setCashierAddress(contractCashier.address) + + await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenPrice.address, constants.TOKEN_LIMIT) + await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenDeposit.address, constants.TOKEN_LIMIT) + await contractFundLimitsOracle + .setETHLimit(constants.ETHER_LIMIT) + + await contractVoucherKernel.setComplainPeriod(sixtySeconds) + await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds) + } + + // this functions is used after each interaction with tokens to clear + // balances + async function giveAwayToRandom () { + const balanceBuyerFromPayment = await contractBSNTokenPrice + .balanceOf(users.buyer.address) + const balanceBuyerFromDesosits = await contractBSNTokenDeposit + .balanceOf(users.buyer.address) + + const balanceSellerFromPayment = await contractBSNTokenPrice + .balanceOf(users.seller.address) + const balanceSellerFromDesosits = await contractBSNTokenDeposit + .balanceOf(users.seller.address) + + const escrowBalanceFromPayment = await contractBSNTokenPrice + .balanceOf(users.deployer.address) + const escrowBalanceFromDeposits = await contractBSNTokenDeposit + .balanceOf(users.deployer.address) + + await contractBSNTokenPrice + .transfer( + users.other1.address, + balanceBuyerFromPayment, { + from: users.buyer.address + }) + await contractBSNTokenDeposit + .transfer( + users.other1.address, + balanceBuyerFromDesosits, { + from: users.buyer.address + }) + await contractBSNTokenPrice + .transfer( + users.other1.address, + balanceSellerFromPayment, { + from: users.seller.address + }) + await contractBSNTokenDeposit + .transfer( + users.other1.address, + balanceSellerFromDesosits, { + from: users.seller.address + }) + await contractBSNTokenPrice + .transfer( + users.other1.address, + escrowBalanceFromPayment, { + from: users.deployer.address + }) + await contractBSNTokenDeposit + .transfer( + users.other1.address, + escrowBalanceFromDeposits, { + from: users.deployer.address + }) + } + + async function withdraw (utils, index, voucherID) { + if (index === 1) { + await utils.pause(users.deployer.address) + return await utils.withdrawWhenPaused(voucherID, users.seller.address) + } else { + return await utils.withdraw(voucherID, users.deployer.address) } + } - async function deployContracts() { - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new() - contractVoucherKernel = await VoucherKernel.new(contractERC1155ERC721.address) - contractCashier = await Cashier.new(contractVoucherKernel.address, contractERC1155ERC721.address, contractFundLimitsOracle.address) - contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC'); - contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP'); + for (let i = 0; i <= PAUSED_WITH_PERMIT; i++) { + describe('Withdraw scenarios', async () => { - await contractERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true') - await contractERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address) - await contractVoucherKernel.setCashierAddress(contractCashier.address) + before(async () => { + await deployContracts() + }) - await contractFundLimitsOracle.setTokenLimit(contractBSNTokenPrice.address, helpers.TOKEN_LIMIT) - await contractFundLimitsOracle.setTokenLimit(contractBSNTokenDeposit.address, helpers.TOKEN_LIMIT) - await contractFundLimitsOracle.setETHLimit(helpers.ETHER_LIMIT) - - await contractVoucherKernel.setComplainPeriod(60); //60 seconds - await contractVoucherKernel.setCancelFaultPeriod(60); //60 seconds - } - - // this functions is used after each interaction with tokens to clear balances - async function giveAwayToRandom() { - const balanceBuyerFromPayment = await contractBSNTokenPrice.balanceOf(Buyer.address) - const balanceBuyerFromDesosits = await contractBSNTokenDeposit.balanceOf(Buyer.address) - - const balanceSellerFromPayment = await contractBSNTokenPrice.balanceOf(Seller.address) - const balanceSellerFromDesosits = await contractBSNTokenDeposit.balanceOf(Seller.address) - - const escrowBalanceFromPayment = await contractBSNTokenPrice.balanceOf(Deployer.address) - const escrowBalanceFromDeposits = await contractBSNTokenDeposit.balanceOf(Deployer.address) - - await contractBSNTokenPrice.transfer(RandomUser.address, balanceBuyerFromPayment, { from: Buyer.address }) - await contractBSNTokenDeposit.transfer(RandomUser.address, balanceBuyerFromDesosits, { from: Buyer.address }) - await contractBSNTokenPrice.transfer(RandomUser.address, balanceSellerFromPayment, { from: Seller.address }) - await contractBSNTokenDeposit.transfer(RandomUser.address, balanceSellerFromDesosits, { from: Seller.address }) - await contractBSNTokenPrice.transfer(RandomUser.address, escrowBalanceFromPayment, { from: Deployer.address }) - await contractBSNTokenDeposit.transfer(RandomUser.address, escrowBalanceFromDeposits, { from: Deployer.address }) - - } - - async function withdraw(utils, index, voucherID) { - if (index == 1) { - await utils.pause(Deployer.address) - return await utils.withdrawWhenPaused(voucherID, Seller.address); - } else { - return await utils.withdraw(voucherID, Deployer.address); + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) } - } - for (let i = 0; i <= PAUSED_WITHPERMIT; i++) { - describe('Withdraw scenarios', async () => { - - before(async () => { - await deployContracts(); + const isPaused = await contractCashier.paused() + if (isPaused) { + await contractCashier.unpause() + } + }) + + describe(`ETH - ETH${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, + async () => { + before(async () => { + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + const timestamp = await Utils.getCurrTimestamp() + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) + + it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = + new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.0125 + const expectedSellerAmount = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmount = + new BN(constants.seller_deposit).div(new BN(4)) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') }) - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - const isPaused = await contractCashier.paused(); - if (isPaused) { - await contractCashier.unpause(); - } + it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", + async () => { + // 0.3 + const expectedBuyerAmount = new BN(constants.product_price) + // 0 + const expectedSellerAmount = new BN(0) + // 0.09 + const expectedEscrowAmount = + new BN(constants.seller_deposit) + .add(new BN(constants.buyer_deposit)) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await timemachine.advanceTimeSeconds(60) + + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') }) - describe(`ETH - ETH${i == PAUSED_WITHPERMIT ? PAUSED_LABEL : ''}`, async () => { - - before(async () => { - - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier) - - const timestamp = await Utils.getCurrTimestamp() - - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) - - }) - - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - - const expectedBuyerAmount = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.3 + 0.04 + 0.025 - const expectedSellerAmount = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmount = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - const withdrawTx = await withdraw(utils, i, voucherID) + it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", + async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = + new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.025 + const expectedSellerAmount = + new BN(constants.seller_deposit).div(new BN(2)) + // 0 + const expectedEscrowAmount = new BN(0) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { + // 0.3 + const expectedBuyerAmount = new BN(constants.product_price) + // 0.05 + const expectedSellerAmount = new BN(constants.seller_deposit) + // 0.04 + const expectedEscrowAmount = new BN(constants.buyer_deposit) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) + + it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = + new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.025 + const expectedSellerAmount = + new BN(constants.seller_deposit).div(new BN(2)) + // 0 + const expectedEscrowAmount = new BN(0) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) + + it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { + // 0.04 + const expectedBuyerAmount = new BN(constants.buyer_deposit) + // 0.35 + const expectedSellerAmount = + new BN(constants.seller_deposit) + .add(new BN(constants.product_price)) + // 0 + const expectedEscrowAmount = new BN(0) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) + + it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { + // 0.04 + const expectedBuyerAmount = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerAmount = new BN(constants.product_price) + // 0.05 + const expectedEscrowAmount = new BN(constants.seller_deposit) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) + + it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + // 0.065 + const expectedBuyerAmount = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit) + .div(new BN(2))) + // 0.3125 + const expectedSellerAmount = + new BN(constants.product_price) + .add(new BN(constants.seller_deposit).div(new BN(4))) + // 0.0125 + const expectedEscrowAmount = + new BN(constants.seller_deposit).div(new BN(4)) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { + // 0.065 + const expectedBuyerAmount = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.325 + const expectedSellerAmount = + new BN(constants.product_price) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0 + const expectedEscrowAmount = new BN(0) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected') + }) + }) - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.product_price) // 0.3 - const expectedSellerAmount = new BN(0) // 0 - const expectedEscrowAmount = new BN(helpers.seller_deposit).add(new BN(helpers.buyer_deposit)) // 0.09 + describe("TKN - TKN [WITH PERMIT]" + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, + async () => { + let balanceBuyerFromPayment = new BN(0) + let balanceBuyerFromDeposits = new BN(0) + + let balanceSellerFromPayment = new BN(0) + let balanceSellerFromDeposits = new BN(0) + + let escrowBalanceFromPayment = new BN(0) + let escrowBalanceFromDeposits = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + async function getBalancesFromPriceTokenAndDepositToken () { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.buyer.address) + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.buyer.address) + + balanceSellerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.seller.address) + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.seller.address) + + escrowBalanceFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.deployer.address) + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.deployer.address) + + cashierPaymentLeft = await utils.contractBSNTokenPrice + .balanceOf(utils.contractCashier.address) + cashierDepositLeft = await utils.contractBSNTokenDeposit + .balanceOf(utils.contractCashier.address) + } + + beforeEach(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + const supplyQty = 1 + const tokensToMint = + new BN(constants.seller_deposit).mul(new BN(supplyQty)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + constants.product_price) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + constants.buyer_deposit) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ) + }) + + it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedSellerPrice = new BN(0) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await timemachine.advanceTimeSeconds(60); + }) - await utils.finalize(voucherID, Deployer.address) + it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedBuyerDeposit = new BN(0) + const expectedSellerPrice = new BN(0) + const expectedSellerDeposit = new BN(0) + // 0.09 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit) + .add(new BN(constants.buyer_deposit)) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") - const withdrawTx = await withdraw(utils, i, voucherID) + }) - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedSellerPrice = new BN(0) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedBuyerDeposit = new BN(0) + const expectedSellerPrice = new BN(0) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + //Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedSellerPrice = new BN(0) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountPrice = new BN(0) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN(0) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedSellerDeposit = new BN(0) + const expectedEscrowAmountPrice = new BN(0) + // 0.05 + const expectedEscrowAmountDeposit = new BN(constants.seller_deposit) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.3 + 0.04 + 0.025 - const expectedSellerAmount = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmount = new BN(0) //0 + it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.3 + const expectedSellerPrice = + new BN(constants.product_price) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + const expectedEscrowAmountPrice = new BN(0) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) + it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountPrice = new BN(0) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesFromPriceTokenAndDepositToken() + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PriceTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PriceTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + "Escrow did not get expected tokens from PriceTokenContract") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - await timemachine.advanceTimeSeconds(60) + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } - await utils.finalize(voucherID, Deployer.address) + balanceBuyerFromPayment = new BN(0) + balanceBuyerFromDeposits = new BN(0) - const withdrawTx = await withdraw(utils, i, voucherID) + balanceSellerFromPayment = new BN(0) + balanceSellerFromDeposits = new BN(0) - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + escrowBalanceFromPayment = new BN(0) + escrowBalanceFromDeposits = new BN(0) - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + cashierPaymentLeft = new BN(0) + cashierDepositLeft = new BN(0) - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.product_price) // 0.3 - const expectedSellerAmount = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmount = new BN(helpers.buyer_deposit) // 0.04 + await giveAwayToRandom() - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) + const isPaused = await contractCashier.paused() + if (isPaused) { + await contractCashier.unpause() + } + }) - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) + }) - const withdrawTx = await withdraw(utils, i, voucherID) + // Ignored due to deployment failure. + xdescribe("TKN - TKN SAME [WITH PERMIT]" + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { + let balanceBuyer = new BN(0) + let balanceSeller = new BN(0) + let escrowBalance = new BN(0) + let cashierBalance = new BN(0) + + async function getBalancesFromSameTokenContract () { + balanceBuyer = await utils.contractBSNTokenSAME + .balanceOf(users.buyer.address) + balanceSeller = await utils.contractBSNTokenSAME + .balanceOf(users.seller.address) + escrowBalance = await utils.contractBSNTokenSAME + .balanceOf(users.deployer.address) + cashierBalance = await utils.contractBSNTokenSAME + .balanceOf(utils.contractCashier.address) + } - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + beforeEach(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN_SAME() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + const supplyQty = 1 + const tokensToMintSeller = + new BN(constants.seller_deposit).mul(new BN(supplyQty)) + const tokensToMintBuyer = + new BN(constants.product_price) + .add(new BN(constants.buyer_deposit)) + + await utils.mintTokens( + 'contractBSNTokenSAME', + users.seller.address, + tokensToMintSeller) + await utils.mintTokens( + 'contractBSNTokenSAME', + users.buyer.address, + tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ) + }) - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.buyer_deposit).add(new BN(helpers.product_price)).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.3 + 0.04 + 0.025 - const expectedSellerAmount = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmount = new BN(0) // 0 + balanceBuyer = new BN(0) + balanceSeller = new BN(0) + escrowBalance = new BN(0) + cashierBalance = new BN(0) - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.cancel(voucherID, Seller.address) + await giveAwayToRandom() - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) + const isPaused = await contractCashier.paused() + if (isPaused) { + await contractCashier.unpause() + } + }) - const withdrawTx = await withdraw(utils, i, voucherID) + it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedSellerPrice = new BN(0) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + + }) + + it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedBuyerDeposit = new BN(0) + const expectedSellerPrice = new BN(0) + const expectedSellerDeposit = new BN(0) + // 0.09 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit) + .add(new BN(constants.buyer_deposit)) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedSellerPrice = new BN(0) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedBuyerDeposit = new BN(0) + const expectedSellerPrice = new BN(0) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) + const expectedEscrowAmountPrice = new BN(0) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedSellerPrice = new BN(0) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountPrice = new BN(0) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN(0) + const expectedEscrowAmountPrice = new BN(0) + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerAmount = new BN(helpers.seller_deposit).add(new BN(helpers.product_price)) // 0.35 - const expectedEscrowAmount = new BN(0) // 0 + it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedSellerDeposit = new BN(0) + const expectedEscrowAmountPrice = new BN(0) + // 0.05 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + const expectedEscrowAmountPrice = new BN(0) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.3 + const expectedSellerPrice = + new BN(constants.product_price) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountPrice = new BN(0) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesFromSameTokenContract() + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + "Buyer did not get expected tokens from SameTokenContract") + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + "Seller did not get expected tokens from SameTokenContract") + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice + .add(expectedEscrowAmountDeposit)), + "Escrow did not get expected tokens from SameTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.redeem(voucherID, Buyer.address) + }) - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) + }) - const withdrawTx = await withdraw(utils, i, voucherID) + describe("ETH - TKN [WITH PERMIT]" + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { + let balanceBuyerFromPayment = new BN(0) + let balanceBuyerFromDeposits = new BN(0) - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + let balanceSellerFromPayment = new BN(0) + let balanceSellerFromDeposits = new BN(0) - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + let escrowBalanceFromPayment = new BN(0) + let escrowBalanceFromDeposits = new BN(0) - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerAmount = new BN(helpers.product_price) // 0.3 - const expectedEscrowAmount = new BN(helpers.seller_deposit) // 0.05 + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) + async function getBalancesDepositToken () { + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.buyer.address) + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.seller.address) + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit + .balanceOf(users.deployer.address) + cashierDepositLeft = await utils.contractBSNTokenDeposit + .balanceOf(utils.contractCashier.address) + } - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) + beforeEach(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + const supplyQty = 1 + const tokensToMint = + new BN(constants.seller_deposit).mul(new BN(supplyQty)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + constants.buyer_deposit) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ) + }) - const withdrawTx = await withdraw(utils, i, voucherID) + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + balanceBuyerFromPayment = new BN(0) + balanceBuyerFromDeposits = new BN(0) - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + balanceSellerFromPayment = new BN(0) + balanceSellerFromDeposits = new BN(0) - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerAmount = new BN(helpers.product_price).add(new BN(helpers.seller_deposit).div(new BN(4))) // 0.3125 - const expectedEscrowAmount = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 + escrowBalanceFromPayment = new BN(0) + escrowBalanceFromDeposits = new BN(0) - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) + cashierPaymentLeft = new BN(0) + cashierDepositLeft = new BN(0) - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) + await giveAwayToRandom() - const withdrawTx = await withdraw(utils, i, voucherID) + const isPaused = await contractCashier.paused() + if (isPaused) { + await contractCashier.unpause() + } + }) - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + await getBalancesDepositToken() + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.buyer.address, + "Incorrect Payee") + assert.isTrue( + ev._payment.eq(expectedBuyerPrice)) + + return true + }, "Event LogAmountDistribution was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from " + + "DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from " + + "DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from " + + "DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedBuyerDeposit = new BN(0) + const expectedSellerDeposit = new BN(0) + // 0.09 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit) + .add(new BN(constants.buyer_deposit)) + + await getBalancesDepositToken() + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.buyer.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedBuyerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesDepositToken() + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.buyer.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedBuyerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from " + + "DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from " + + "DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from " + + "DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + }) - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { - const expectedBuyerAmount = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerAmount = new BN(helpers.product_price).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.325 - const expectedEscrowAmount = new BN(0) // 0 + it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedBuyerDeposit = new BN(0) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) + + await getBalancesDepositToken() + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.buyer.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedBuyerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.redeem(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) + it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesDepositToken() + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.buyer.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedBuyerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) + it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesDepositToken() + + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedSellerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - const withdrawTx = await withdraw(utils, i, voucherID) + it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedSellerDeposit = new BN(0) + // 0.05 + const expectedEscrowAmountDeposit = new BN(constants.seller_deposit) + + await getBalancesDepositToken() + + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedSellerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_to', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") + it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + await getBalancesDepositToken() + + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedSellerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesDepositToken() + + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedSellerPrice)) + + return true + }, "Event LogWithdrawal was not emitted") + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + "Buyer did not get expected tokens from DepositTokenContract") + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + "Seller did not get expected tokens from DepositTokenContract") + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + "Escrow did not get expected tokens from DepositTokenContract") + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + }) + + describe("TKN - ETH [WITH PERMIT]" + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { + let balanceBuyerFromPayment = new BN(0) + let balanceSellerFromPayment = new BN(0) + let escrowBalanceFromPayment = new BN(0) + + let cashierPaymentLeft = new BN(0) + let cashierDepositLeft = new BN(0) + + async function getBalancesPriceToken () { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.buyer.address) + balanceSellerFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.seller.address) + escrowBalanceFromPayment = await utils.contractBSNTokenPrice + .balanceOf(users.deployer.address) + cashierPaymentLeft = await utils.contractBSNTokenPrice + .balanceOf(utils.contractCashier.address) + } - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerAmount), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerAmount), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmount), 'Escrow Amount is not as expected') - }); + beforeEach(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '') + + const timestamp = await Utils.getCurrTimestamp() + + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + constants.product_price) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ) + }) - - }) + it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedSellerPrice = new BN(0) + const expectedEscrowPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedSellerPrice = new BN(0) + const expectedEscrowPrice = new BN(0) + const expectedBuyerDeposit = new BN(0) + const expectedSellerDeposit = new BN(0) + // 0.09 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit) + .add(new BN(constants.buyer_deposit)) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + + }) + + it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.refund(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedSellerPrice = new BN(0) + const expectedEscrowPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") - describe(`TKN - TKN [WITH PERMIT]${i == PAUSED_WITHPERMIT ? PAUSED_LABEL : ''}`, async () => { - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDesosits = new BN(0) + }) - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDesosits = new BN(0) + it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedSellerPrice = new BN(0) + const expectedEscrowPrice = new BN(0) + const expectedBuyerDeposit = new BN(0) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) + it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price) + const expectedSellerPrice = new BN(0) + const expectedEscrowPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) + it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedEscrowPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been sent to seller + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedEscrowPrice = new BN(0) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit) + const expectedSellerDeposit = new BN(0) + // 0.05 + const expectedEscrowAmountDeposit = new BN(constants.seller_deposit) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been sent to seller + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - async function getBalancesFromPiceTokenAndDepositToken() { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Buyer.address) - balanceBuyerFromDesosits = await utils.contractBSNTokenDeposit.balanceOf(Buyer.address) + it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", + async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + await utils.redeem(voucherID, users.buyer.address) + await utils.complain(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedEscrowPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.0125 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + // 0.0125 + const expectedEscrowAmountDeposit = + new BN(constants.seller_deposit).div(new BN(4)) + + await getBalancesPriceToken() + + // Payments in TKN + // Payment should have been sent to seller + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) + + it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ) + + await utils.redeem(voucherID, users.buyer.address) + await utils.cancel(voucherID, users.seller.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + const withdrawTx = await withdraw(utils, i, voucherID) + + const expectedBuyerPrice = new BN(0) + // 0.3 + const expectedSellerPrice = new BN(constants.product_price) + const expectedEscrowPrice = new BN(0) + // 0.065 + const expectedBuyerDeposit = + new BN(constants.buyer_deposit) + .add(new BN(constants.seller_deposit).div(new BN(2))) + // 0.025 + const expectedSellerDeposit = + new BN(constants.seller_deposit).div(new BN(2)) + const expectedEscrowAmountDeposit = new BN(0) + + await getBalancesPriceToken() + // Payments in TKN + // Payment should have been sent to seller + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + "Buyer did not get expected tokens from PaymentTokenContract") + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + "Seller did not get expected tokens from PaymentTokenContract") + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + "Escrow did not get expected tokens from PaymentTokenContract") + + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address) + return true + }, "Amounts not distributed successfully") + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected') + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected') + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected') + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + "Cashier Contract is not empty") + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + "Cashier Contract is not empty") + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Event LogAmountDistribution was not emitted") + }) - balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Seller.address) - balanceSellerFromDesosits = await utils.contractBSNTokenDeposit.balanceOf(Seller.address) + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0) + } - escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf(Deployer.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Deployer.address) + balanceBuyerFromPayment = new BN(0) + balanceSellerFromPayment = new BN(0) + escrowBalanceFromPayment = new BN(0) - cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf(utils.contractCashier.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf(utils.contractCashier.address) - } + cashierPaymentLeft = new BN(0) + cashierDepositLeft = new BN(0) - beforeEach(async () => { + await giveAwayToRandom() + }) + }) - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() + }) + } + + describe("[WHEN PAUSED] Seller withdraws deposit locked in escrow", + async () => { + let remQty = 10 + let voucherToBuyBeforeBurn = 5 + let tokensToMintSeller, tokensToMintBuyer + + describe("ETH ETH", () => { + before(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + const timestamp = await Utils.getCurrTimestamp() + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) - const supplyQty = 1 - const tokensToMint = new BN(helpers.seller_deposit).mul(new BN(supplyQty)) + after(() => { + remQty = 10 + voucherToBuyBeforeBurn = 5 + }) - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, helpers.product_price); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, helpers.buyer_deposit); + it("[NEGATIVE] Should revert if called when contract is not paused", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("Should pause the contract", async () => { + // Does nothing in particular .. + // Buys 5 vouchers before pausing the contract so as to test if the + // locked seller deposit should be returned correctly + // Pauses contract as below tests are dependant to paused contract + + for (let i = 0; i < voucherToBuyBeforeBurn; i++) { + await utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + remQty-- + } + + await contractCashier.pause() + }) - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - supplyQty - ) + it("[NEGATIVE] should revert if not called from the seller", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("Seller should be able to withdraw deposits for the " + + "remaining QTY in Token Supply", + async () => { + let withdrawTx = await contractCashier + .withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address }) - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60); - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).add(new BN(helpers.buyer_deposit)) // 0.09 - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) //// 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit) // 0.05 - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesFromPiceTokenAndDepositToken(); - - //Payments - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PriceTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PriceTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), "Escrow did not get expected tokens from PriceTokenContract"); - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - - }); - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyerFromPayment = new BN(0) - balanceBuyerFromDesosits = new BN(0) - - balanceSellerFromPayment = new BN(0) - balanceSellerFromDesosits = new BN(0) - - escrowBalanceFromPayment = new BN(0) - escrowBalanceFromDeposits = new BN(0) - - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) - - await giveAwayToRandom(); - - const isPaused = await contractCashier.paused(); - if (isPaused) { - await contractCashier.unpause(); - } - }) - + const expectedSellerDeposit = + new BN(constants.seller_deposit).mul(new BN(remQty)) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedSellerDeposit)) + + return true + }, "Event LogWithdrawal was not emitted") + }) + + it("Escrow should have correct balance after burning the " + + "rest of the supply", + async () => { + const expectedBalance = + new BN(constants.seller_deposit) + .mul(new BN(voucherToBuyBeforeBurn)) + const escrowAmount = await contractCashier + .getEscrowAmount(users.seller.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") + }) + + it("Remaining QTY for Token Supply should be ZERO", + async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) + + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + "Escrow amount is incorrect") + }) + + it("[NEGATIVE] Buyer should not be able to commit to buy " + + "anything from the burnt supply", + async () => { + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Seller should not be able withdraw its deposit " + + "for the Token Supply twice", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("[WITH PERMIT]", () => { + describe("ETH_TKN", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMintSeller = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_10)) + tokensToMintBuyer = + new BN(constants.product_price).mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMintSeller) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) + + after(() => { + remQty = 10 + voucherToBuyBeforeBurn = 5 + }) + + it("[NEGATIVE] Should revert if called when contract is not paused", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) }) - // Ignored due to deployment failure. - xdescribe(`TKN - TKN SAME [WITH PERMIT]${i == PAUSED_WITHPERMIT ? PAUSED_LABEL : ''}`, async () => { - - let balanceBuyer = new BN(0) - let balanceSeller = new BN(0) - let escrowBalance = new BN(0) - let cashierBalance = new BN(0) - - - async function getBalancesFromSameTokenContract() { - balanceBuyer = await utils.contractBSNTokenSAME.balanceOf(Buyer.address) - balanceSeller = await utils.contractBSNTokenSAME.balanceOf(Seller.address) - escrowBalance = await utils.contractBSNTokenSAME.balanceOf(Deployer.address) - cashierBalance = await utils.contractBSNTokenSAME.balanceOf(utils.contractCashier.address) - } - - beforeEach(async () => { - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN_SAME() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - const supplyQty = 1 - const tokensToMintSeller = new BN(helpers.seller_deposit).mul(new BN(supplyQty)) - const tokensToMintBuyer = new BN(helpers.product_price).add(new BN(helpers.buyer_deposit)) - - await utils.mintTokens('contractBSNTokenSAME', Seller.address, tokensToMintSeller) - await utils.mintTokens('contractBSNTokenSAME', Buyer.address, tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - supplyQty - ) - }) - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyer = new BN(0) - balanceSeller = new BN(0) - escrowBalance = new BN(0) - cashierBalance = new BN(0) - - await giveAwayToRandom(); - - const isPaused = await contractCashier.paused(); - if (isPaused) { - await contractCashier.unpause(); - } - }) - - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60); - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).add(new BN(helpers.buyer_deposit)) // 0.09 - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) //// 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit) // 0.05 - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesFromSameTokenContract(); - - assert.isTrue(balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), "Buyer did not get expected tokens from SameTokenContract"); - assert.isTrue(balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), "Seller did not get expected tokens from SameTokenContract"); - assert.isTrue(escrowBalance.eq(expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit)), "Escrow did not get expected tokens from SameTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierBalance.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - - }); - + it("Should pause the contract", async () => { + // Does nothing in particular .. + // Buys 5 vouchers before pausing the contract so as to test if + // the locked seller deposit should be returned correctly + // Pauses contract as below tests are dependant to paused contract + + for (let i = 0; i < voucherToBuyBeforeBurn; i++) { + await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID) + remQty-- + } + + await contractCashier.pause() + }) + + it("[NEGATIVE] should revert if not called from the seller", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) }) - - describe(`ETH - TKN [WITH PERMIT]${ i == PAUSED_WITHPERMIT ? PAUSED_LABEL : '' }`, async () => { - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDesosits = new BN(0) - - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDesosits = new BN(0) - - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - async function getBalancesDepositToken() { - balanceBuyerFromDesosits = await utils.contractBSNTokenDeposit.balanceOf(Buyer.address) - balanceSellerFromDesosits = await utils.contractBSNTokenDeposit.balanceOf(Seller.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf(Deployer.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf(utils.contractCashier.address) - } - - beforeEach(async () => { - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - const supplyQty = 1 - const tokensToMint = new BN(helpers.seller_deposit).mul(new BN(supplyQty)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, helpers.buyer_deposit); - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - supplyQty - ) - }) - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyerFromPayment = new BN(0) - balanceBuyerFromDesosits = new BN(0) - - balanceSellerFromPayment = new BN(0) - balanceSellerFromDesosits = new BN(0) - escrowBalanceFromPayment = new BN(0) - escrowBalanceFromDeposits = new BN(0) - - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) - - await giveAwayToRandom(); - - const isPaused = await contractCashier.paused(); - if (isPaused) { - await contractCashier.unpause(); - } + it("Seller should be able to withdraw deposits for the " + + "remaining QTY in Token Supply", + async () => { + let withdrawTx = await contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address }) - - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - await getBalancesDepositToken(); - - // Payment should have been returned to buyer - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Buyer.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogAmountDistribution was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60); - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(0) - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).add(new BN(helpers.buyer_deposit)) // 0.09 - - await getBalancesDepositToken(); - - // Payment should have been returned to buyer - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Buyer.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesDepositToken(); - - // Payment should have been returned to buyer - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Buyer.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(helpers.buyer_deposit) // 0.04 - - await getBalancesDepositToken(); - - // Payment should have been returned to buyer - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Buyer.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesDepositToken(); - - // Payment should have been returned to buyer - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Buyer.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) //// 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesDepositToken(); - - // Payment should have been sent to seller - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Seller.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit) // 0.05 - - await getBalancesDepositToken(); - - // Payment should have been sent to seller - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Seller.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - await getBalancesDepositToken(); - - // Payment should have been sent to seller - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Seller.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesDepositToken(); - - // Payment should have been sent to seller - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - - assert.equal(ev._payee, Seller.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - //Deposits - assert.isTrue(balanceBuyerFromDesosits.eq(expectedBuyerDeposit), "Buyer did not get expected tokens from DepositTokenContract"); - assert.isTrue(balanceSellerFromDesosits.eq(expectedSellerDeposit), "Seller did not get expected tokens from DepositTokenContract"); - assert.isTrue(escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), "Escrow did not get expected tokens from DepositTokenContract"); - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - + const expectedSellerDeposit = + new BN(constants.seller_deposit).mul(new BN(remQty)) + const internalTx = await truffleAssert + .createTransactionResult( + contractBSNTokenDeposit, + withdrawTx.tx) + + truffleAssert.eventEmitted( + internalTx, + 'Transfer', + (ev) => { + assert.equal( + ev.to, users.seller.address, "Incorrect Payee") + assert.isTrue(ev.value.eq(expectedSellerDeposit)) + + return true + }, "Event Transfer was not emitted") }) - describe(`TKN - ETH [WITH PERMIT]${i == PAUSED_WITHPERMIT ? PAUSED_LABEL : ''}`, async () => { - let balanceBuyerFromPayment = new BN(0) - let balanceSellerFromPayment = new BN(0) - let escrowBalanceFromPayment = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - async function getBalancesPriceToken() { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Buyer.address) - balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf(Seller.address) - escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf(Deployer.address) - cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf(utils.contractCashier.address) - } - - beforeEach(async () => { - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, '') + it("Escrow should have correct balance after burning the " + + "rest of the supply", + async () => { + const expectedBalance = + new BN(constants.seller_deposit) + .mul(new BN(voucherToBuyBeforeBurn)) + const escrowAmount = await contractBSNTokenDeposit + .balanceOf(users.seller.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") + }) - const timestamp = await Utils.getCurrTimestamp() + it("Remaining QTY for Token Supply should be ZERO", + async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, helpers.product_price); + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + "Escrow amount is incorrect") + }) - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_1 - ) - }) + it("[NEGATIVE] Buyer should not be able to commit to buy " + + "anything from the burnt supply", + async () => { + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) + }) - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60); - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(0) - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).add(new BN(helpers.buyer_deposit)) // 0.09 - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }); - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(0) - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(helpers.buyer_deposit) // 0.04 - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(helpers.product_price) // 0.3 - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerDeposit = new BN(helpers.seller_deposit) // 0.05 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit) // 0.04 - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit) // 0.05 - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, Buyer.address) - await utils.complain(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - const expectedEscrowAmountDeposit = new BN(helpers.seller_deposit).div(new BN(4)) // 0.0125 - - await getBalancesPriceToken(); - - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - Buyer, - Seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, Buyer.address) - await utils.cancel(voucherID, Seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - const expectedSellerPrice = new BN(helpers.product_price) // 0.3 - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(helpers.buyer_deposit).add(new BN(helpers.seller_deposit).div(new BN(2))) // 0.065 - const expectedSellerDeposit = new BN(helpers.seller_deposit).div(new BN(2)) // 0.025 - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesPriceToken(); - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue(balanceBuyerFromPayment.eq(expectedBuyerPrice), "Buyer did not get expected tokens from PaymentTokenContract"); - assert.isTrue(balanceSellerFromPayment.eq(expectedSellerPrice), "Seller did not get expected tokens from PaymentTokenContract"); - assert.isTrue(escrowBalanceFromPayment.eq(expectedEscrowPrice), "Escrow did not get expected tokens from PaymentTokenContract"); - - //Deposits in ETH - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients(ev, distributedAmounts, '_payee', Buyer.address, Seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue(distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), 'Buyer Amount is not as expected') - assert.isTrue(distributedAmounts.sellerAmount.eq(expectedSellerDeposit), 'Seller Amount is not as expected') - assert.isTrue(distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue(cashierPaymentLeft.eq(new BN(0)), "Cashier Contract is not empty"); - assert.isTrue(cashierDepositLeft.eq(new BN(0)), "Cashier Contract is not empty"); - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }); - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyerFromPayment = new BN(0) - balanceSellerFromPayment = new BN(0) - escrowBalanceFromPayment = new BN(0) - - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) - - await giveAwayToRandom(); - }) + it("[NEGATIVE] Seller should not be able withdraw its " + + "deposit for the Token Supply twice", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) }) }) - } - describe("[WHEN PAUSED] Seller withdraws deposit locked in escrow", async () => { - - let remQty = 10; - let voucherToBuyBeforeBurn = 5 - let tokensToMintSeller, tokensToMintBuyer - - describe("ETH ETH", () => { - - before(async () => { - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); - - const timestamp = await Utils.getCurrTimestamp() - - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) - + describe("TKN_ETH", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '') + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMintBuyer = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + after(() => { + remQty = 10 + voucherToBuyBeforeBurn = 5 + }) + + it("[NEGATIVE] Should revert if called when contract is " + + "not paused", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) }) - after(() => { - remQty = 10; - voucherToBuyBeforeBurn = 5 - }) - - it("[NEGATIVE] Should revert if called when contract is not paused", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) + it("Should pause the contract", async () => { + // Does nothing in particular .. + // Buys 5 vouchers before pausing the contract so as to test if + // the locked seller deposit should be returned correctly + // Pauses contract as below tests are dependant to paused contract + + for (let i = 0; i < voucherToBuyBeforeBurn; i++) { + await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID) + remQty-- + } + + await contractCashier.pause() + }) + + it("[NEGATIVE] should revert if not called from the seller", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) }) - it("Should pause the contract", async () => { - // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if the locked seller deposit should be returned correctly - // Pauses contract as below tests are dependant to paused contract - - for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - remQty--; - } - - await contractCashier.pause(); + it("Seller should be able to withdraw deposits for the " + + "remaining QTY in Token Supply", + async () => { + let withdrawTx = await contractCashier + .withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }) + const expectedSellerDeposit = + new BN(constants.seller_deposit).mul(new BN(remQty)) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + "Incorrect Payee") + assert.isTrue(ev._payment.eq(expectedSellerDeposit)) + + return true + }, "Event LogWithdrawal was not emitted") }) - it("[NEGATIVE] should revert if not called from the seller", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) + it("Escrow should have correct balance after burning the " + + "rest of the supply", + async () => { + const expectedBalance = + new BN(constants.seller_deposit) + .mul(new BN(voucherToBuyBeforeBurn)) + const escrowAmount = await contractCashier + .getEscrowAmount(users.seller.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") }) - it("Seller should be able to withdraw deposits for the remaining QTY in Token Supply", async () => { - let withdrawTx = await contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}); - const expectedSellerDeposit = new BN(helpers.seller_deposit).mul(new BN(remQty)) - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - assert.equal(ev._payee, Seller.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerDeposit)) - - return true - }, "Event LogWithdrawal was not emitted") - }); - - it("Escrow should have correct balance after burning the rest of the supply", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractCashier.getEscrowAmount(Seller.address); + it("Remaining QTY for Token Supply should be ZERO", + async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }); + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + "Escrow amount is incorrect") + }) - it("Remaining QTY for Token Supply should be ZERO", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(TOKEN_SUPPLY_ID, Seller.address) + it("[NEGATIVE] Buyer should not be able to commit to buy " + + "anything from the burnt supply", + async () => { + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) + }) - assert.isTrue(remainingQtyInContract.eq(new BN(0)), "Escrow amount is incorrect") + it("[NEGATIVE] Seller should not be able withdraw its " + + "deposit for the Token Supply twice", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) }) - it("[NEGATIVE] Buyer should not be able to commit to buy anything from the burnt supply", async () => { - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }); - - it("[NEGATIVE] Seller should not be able withdraw its deposit for the Token Supply twice", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) - }); - }) - describe("[WITH PERMIT]", () => { - - describe("ETH_TKN", () => { - before(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - tokensToMintSeller = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_10)) - tokensToMintBuyer = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMintSeller); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMintBuyer); - - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) - - }) - - after(() => { - remQty = 10; - voucherToBuyBeforeBurn = 5 - }) - - it("[NEGATIVE] Should revert if called when contract is not paused", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) + describe("TKN_TKN", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMintSeller = + new BN(constants.seller_deposit).mul(new BN(constants.QTY_10)) + tokensToMintBuyer = + new BN(constants.product_price).mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMintSeller) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMintBuyer) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMintBuyer) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + after(() => { + remQty = 10 + voucherToBuyBeforeBurn = 5 + }) + + it("[NEGATIVE] Should revert if called when contract " + + "is not paused", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) }) - it("Should pause the contract", async () => { - // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if the locked seller deposit should be returned correctly - // Pauses contract as below tests are dependant to paused contract - - for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - remQty--; - } - - await contractCashier.pause(); - }) - - it("[NEGATIVE] should revert if not called from the seller", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Seller should be able to withdraw deposits for the remaining QTY in Token Supply", async () => { - let withdrawTx = await contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}); - const expectedSellerDeposit = new BN(helpers.seller_deposit).mul(new BN(remQty)) - const internalTx = (await truffleAssert.createTransactionResult(contractBSNTokenDeposit, withdrawTx.tx)) - - truffleAssert.eventEmitted(internalTx, 'Transfer', (ev) => { - assert.equal(ev.to, Seller.address, "Incorrect Payee") - assert.isTrue(ev.value.eq(expectedSellerDeposit)) - - return true - }, "Event Transfer was not emitted") - }); - - it("Escrow should have correct balance after burning the rest of the supply", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractBSNTokenDeposit.balanceOf(Seller.address); - - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }); - - it("Remaining QTY for Token Supply should be ZERO", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(TOKEN_SUPPLY_ID, Seller.address) - - assert.isTrue(remainingQtyInContract.eq(new BN(0)), "Escrow amount is incorrect") - }) - - it("[NEGATIVE] Buyer should not be able to commit to buy anything from the burnt supply", async () => { - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }); - - it("[NEGATIVE] Seller should not be able withdraw its deposit for the Token Supply twice", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) - }); - + it("Should pause the contract", async () => { + // Does nothing in particular .. + // Buys 5 vouchers before pausing the contract so as to test if + // the locked seller deposit should be returned correctly + // Pauses contract as below tests are dependant to paused contract + + for (let i = 0; i < voucherToBuyBeforeBurn; i++) { + await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID) + remQty-- + } + + await contractCashier.pause() + }) + + it("[NEGATIVE] should revert if not called from the seller", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) }) - describe("TKN_ETH", () => { - before(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, '') - - const timestamp = await Utils.getCurrTimestamp() - - tokensToMintBuyer = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMintBuyer); - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) - - after(() => { - remQty = 10; - voucherToBuyBeforeBurn = 5 - }) - - it("[NEGATIVE] Should revert if called when contract is not paused", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) + it("Seller should be able to withdraw deposits for the " + + "remaining QTY in Token Supply", + async () => { + let withdrawTx = await contractCashier + .withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }) + const expectedSellerDeposit = + new BN(constants.seller_deposit).mul(new BN(remQty)) + const internalTx = await truffleAssert + .createTransactionResult( + contractBSNTokenDeposit, + withdrawTx.tx) + + truffleAssert.eventEmitted( + internalTx, + 'Transfer', + (ev) => { + assert.equal( + ev.to, + users.seller.address, + "Incorrect Payee") + assert.isTrue(ev.value.eq(expectedSellerDeposit)) + + return true + }, "Event Transfer was not emitted") }) - it("Should pause the contract", async () => { - // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if the locked seller deposit should be returned correctly - // Pauses contract as below tests are dependant to paused contract - - for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - remQty--; - } - - await contractCashier.pause(); - }) - - it("[NEGATIVE] should revert if not called from the seller", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Seller should be able to withdraw deposits for the remaining QTY in Token Supply", async () => { - let withdrawTx = await contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}); - const expectedSellerDeposit = new BN(helpers.seller_deposit).mul(new BN(remQty)) - truffleAssert.eventEmitted(withdrawTx, 'LogWithdrawal', (ev) => { - assert.equal(ev._payee, Seller.address, "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerDeposit)) - - return true - }, "Event LogWithdrawal was not emitted") - }); - - it("Escrow should have correct balance after burning the rest of the supply", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractCashier.getEscrowAmount(Seller.address); - - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }); - - it("Remaining QTY for Token Supply should be ZERO", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(TOKEN_SUPPLY_ID, Seller.address) - - assert.isTrue(remainingQtyInContract.eq(new BN(0)), "Escrow amount is incorrect") - }) - - it("[NEGATIVE] Buyer should not be able to commit to buy anything from the burnt supply", async () => { - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }); - - it("[NEGATIVE] Seller should not be able withdraw its deposit for the Token Supply twice", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) - }); - - + it("Escrow should have correct balance after burning the " + + "rest of the supply", + async () => { + const expectedBalance = + new BN(constants.seller_deposit) + .mul(new BN(voucherToBuyBeforeBurn)) + const escrowAmount = await contractBSNTokenDeposit + .balanceOf(users.seller.address) + + assert.isTrue( + escrowAmount.eq(expectedBalance), + "Escrow amount is incorrect") }) - describe("TKN_TKN", () => { - before(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - tokensToMintSeller = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_10)) - tokensToMintBuyer = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMintSeller); - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMintBuyer); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMintBuyer); - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) - - after(() => { - remQty = 10; - voucherToBuyBeforeBurn = 5 - }) - - it("[NEGATIVE] Should revert if called when contract is not paused", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should pause the contract", async () => { - // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if the locked seller deposit should be returned correctly - // Pauses contract as below tests are dependant to paused contract - - for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - remQty--; - } - - await contractCashier.pause(); - }) - - it("[NEGATIVE] should revert if not called from the seller", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) + it("Remaining QTY for Token Supply should be ZERO", + async () => { + let remainingQtyInContract = await contractVoucherKernel + .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) - it("Seller should be able to withdraw deposits for the remaining QTY in Token Supply", async () => { - let withdrawTx = await contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}); - const expectedSellerDeposit = new BN(helpers.seller_deposit).mul(new BN(remQty)) - const internalTx = (await truffleAssert.createTransactionResult(contractBSNTokenDeposit, withdrawTx.tx)) - - truffleAssert.eventEmitted(internalTx, 'Transfer', (ev) => { - assert.equal(ev.to, Seller.address, "Incorrect Payee") - assert.isTrue(ev.value.eq(expectedSellerDeposit)) - - return true - }, "Event Transfer was not emitted") - }); - - it("Escrow should have correct balance after burning the rest of the supply", async () => { - const expectedBalance = new BN(helpers.seller_deposit).mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractBSNTokenDeposit.balanceOf(Seller.address); - - assert.isTrue(escrowAmount.eq(expectedBalance), "Escrow amount is incorrect") - }); - - it("Remaining QTY for Token Supply should be ZERO", async () => { - let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply(TOKEN_SUPPLY_ID, Seller.address) - - assert.isTrue(remainingQtyInContract.eq(new BN(0)), "Escrow amount is incorrect") - }) + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + "Escrow amount is incorrect") + }) - it("[NEGATIVE] Buyer should not be able to commit to buy anything from the burnt supply", async () => { - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }); - - it("[NEGATIVE] Seller should not be able withdraw its deposit for the Token Supply twice", async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, {from: Seller.address}), - truffleAssert.ErrorType.REVERT - ) - }); - + it("[NEGATIVE] Buyer should not be able to commit to buy " + + "anything from the burnt supply", + async () => { + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) }) + it("[NEGATIVE] Seller should not be able withdraw its deposit " + + "for the Token Supply twice", + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, { + from: users.seller.address + }), + truffleAssert.ErrorType.REVERT + ) + }) }) + }) }) - }) - diff --git a/test/4_Boson_Token.js b/test/4_Boson_Token.js index 0c11475f..cb248f0e 100644 --- a/test/4_Boson_Token.js +++ b/test/4_Boson_Token.js @@ -1,343 +1,382 @@ -const chai = require('chai') +const truffleAssert = require('truffle-assertions') const ethers = require('ethers') -const assert = chai.assert -const truffleAssert = require('truffle-assertions'); +const { assert } = require('chai') +const { ecsign } = require('ethereumjs-util') -const { ecsign } = require('ethereumjs-util'); +const constants = require('../testHelpers/constants') +const Users = require('../testHelpers/users') +const { toWei, getApprovalDigest } = require('../testHelpers/permitUtils') -const BN = web3.utils.BN const BosonToken = artifacts.require("BosonTokenPrice") -const helpers = require('../testHelpers/constants') -const { - hexlify, - getAddress, - keccak256, - defaultAbiCoder, - toUtf8Bytes, - solidityPack -} = require('ethers').utils; - -const { - PERMIT_TYPEHASH, - toWei, - getApprovalDigest -} = require('../testHelpers/permitUtils'); - -const config = require('../testHelpers/config.json') - -contract('Boson token', accounts => { - - let BosonTokenContract, bosonContractAddress; - - let Deployer = config.accounts.deployer - let Seller = config.accounts.seller - let Buyer = config.accounts.buyer - let Attacker = config.accounts.attacker //0x56A32fFf5E5A8B40d6A21538579fB8922DF5258c - let RandomUser = config.accounts.randomUser - - beforeEach(async () => { - - BosonTokenContract = await BosonToken.new('BOSON TOKEN', 'BSNT') - bosonContractAddress = BosonTokenContract.address +contract('Boson token', addresses => { + const users = new Users(addresses) + + let BosonTokenContract, + bosonContractAddress + + beforeEach(async () => { + BosonTokenContract = await BosonToken.new('BOSON TOKEN', 'BSNT') + bosonContractAddress = BosonTokenContract.address + }) + + describe('Boson Token', async () => { + const ADMIN_ROLE = + ethers.utils.keccak256(ethers.utils.toUtf8Bytes("ADMIN_ROLE")) + const MINTER_ROLE = + ethers.utils.keccak256(ethers.utils.toUtf8Bytes("MINTER_ROLE")) + + it("Only Deployer Should have admin and minter rights initially ", + async () => { + const buyerIsAdmin = await BosonTokenContract + .hasRole(ADMIN_ROLE, users.buyer.address) + const buyerIsMinter = await BosonTokenContract + .hasRole(MINTER_ROLE, users.buyer.address) + const deployerIsAdmin = await BosonTokenContract + .hasRole(ADMIN_ROLE, users.deployer.address) + const deployerIsMinter = await BosonTokenContract + .hasRole(MINTER_ROLE, users.deployer.address) + + assert.isTrue(deployerIsAdmin) + assert.isTrue(deployerIsMinter) + + assert.isFalse(buyerIsAdmin) + assert.isFalse(buyerIsMinter) + }) + + it("should revert if unauthorized address tries to mint tokens ", + async () => { + await truffleAssert.reverts( + BosonTokenContract.mint( + users.seller.address, + 1000, { + from: users.attacker.address + })) + }) + + it("should grant minter role to address", + async () => { + await BosonTokenContract + .grantMinterRole(users.buyer.address) + + const buyerIsMinter = await BosonTokenContract + .hasRole(MINTER_ROLE, users.buyer.address) + + assert.isTrue(buyerIsMinter) + }) + + it("should mint tokens after minter role is granted", async () => { + const tokensToMint = 1000 + let addressBalance = await BosonTokenContract + .balanceOf(users.other2.address) + + assert.equal(addressBalance, 0, + 'address has more tokens than expected') + + await BosonTokenContract.mint(users.other2.address, 1000) + + addressBalance = await BosonTokenContract + .balanceOf(users.other2.address) + + assert.equal( + addressBalance, + tokensToMint, + "minted tokens do not correspond to address balance") }) - describe('Boson Token', async () => { - - const ADMIN_ROLE = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("ADMIN_ROLE")) - const MINTER_ROLE = ethers.utils.keccak256(ethers.utils.toUtf8Bytes("MINTER_ROLE")) - - it("Only Deployer Should have admin and minter rights initially ", async () => { - - const buyerIsAdmin = await BosonTokenContract.hasRole(ADMIN_ROLE, Buyer.address); - const buyerIsMinter = await BosonTokenContract.hasRole(MINTER_ROLE, Buyer.address); - const deployerIsAdmin = await BosonTokenContract.hasRole(ADMIN_ROLE, Deployer.address); - const deployerIsMinter = await BosonTokenContract.hasRole(MINTER_ROLE, Deployer.address); - - assert.isTrue(deployerIsAdmin) - assert.isTrue(deployerIsMinter) - - assert.isFalse(buyerIsAdmin) - assert.isFalse(buyerIsMinter) + describe("[PERMIT]", async () => { + it("Should approve successfully", async () => { + const balanceToApprove = 1200 + const nonce = await BosonTokenContract.nonces(users.buyer.address) + const deadline = toWei(1) + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + bosonContractAddress, + balanceToApprove, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await BosonTokenContract.permit( + users.buyer.address, + bosonContractAddress, + balanceToApprove, + deadline, + v, r, s, + { from: users.buyer.address } + ) + + const tokenAllowanceFromBuyer = await BosonTokenContract + .allowance(users.buyer.address, bosonContractAddress) + + assert.equal( + tokenAllowanceFromBuyer, + balanceToApprove, + "Allowance does not equal the amount provided!") + }) + + it("should revert if incorrect nonce is provided", async () => { + const balanceToApprove = 1200 + const nonce = 7000000 + const deadline = toWei(1) + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + bosonContractAddress, + balanceToApprove, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts(BosonTokenContract.permit( + users.buyer.address, + bosonContractAddress, + balanceToApprove, + deadline, + v, r, s, + { from: users.buyer.address } + ), truffleAssert.ErrorType.REVERT) + }) + + it("should revert if incorrect balance is provided", + async () => { + const balanceToApprove = 1200 + const incorrectBalance = 1500 + const nonce = await BosonTokenContract.nonces(users.buyer.address) + const deadline = toWei(1) + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + bosonContractAddress, + balanceToApprove, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts(BosonTokenContract.permit( + users.buyer.address, + bosonContractAddress, + incorrectBalance, + deadline, + v, r, s, + { from: users.buyer.address } + ), truffleAssert.ErrorType.REVERT) }) - it("should revert if unauthorized address tries to mint tokens ", async () => { - await truffleAssert.reverts(BosonTokenContract.mint(Seller.address, 1000, { from: Attacker.address} )) + it("should revert if incorrect recipient is provided", + async () => { + const incorrectAddress = addresses[6] + const balanceToApprove = 1200 + const nonce = await BosonTokenContract.nonces(users.buyer.address) + const deadline = toWei(1) + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + bosonContractAddress, + balanceToApprove, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts(BosonTokenContract.permit( + users.buyer.address, + incorrectAddress, + balanceToApprove, + deadline, + v, r, s, + { from: users.buyer.address } + ), truffleAssert.ErrorType.REVERT) }) - it("should grant minter role to address", async () => { - await BosonTokenContract.grantMinterRole(Buyer.address); - - const buyerIsMinter = await BosonTokenContract.hasRole(MINTER_ROLE, Buyer.address); - - assert.isTrue(buyerIsMinter) - }) - - it("should mint tokens after minter role is granted", async () => { - const tokensToMint = 1000; - const randomAddress = accounts[7]; - let addressBalance = await BosonTokenContract.balanceOf(randomAddress) - - assert.equal(addressBalance, 0, 'address has more tokens than expected') - - await BosonTokenContract.mint(randomAddress, 1000); - - addressBalance = await BosonTokenContract.balanceOf(randomAddress) - assert.equal(addressBalance, tokensToMint, "minted tokens do not correspond to address balance") - }) - - describe("[PERMIT]", async () => { - it("Should approve successfully", async () => { - const balanceToApprove = 1200; - const nonce = await BosonTokenContract.nonces(Buyer.address) - const deadline = toWei(1); - const digest = await getApprovalDigest( - BosonTokenContract, - Buyer.address, - bosonContractAddress, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await BosonTokenContract.permit( - Buyer.address, - bosonContractAddress, - balanceToApprove, - deadline, - v, r, s, - { from: Buyer.address } - ) - - const tokenAllowanceFromBuyer = await BosonTokenContract.allowance(Buyer.address, bosonContractAddress); - - assert.equal(tokenAllowanceFromBuyer, balanceToApprove, "Allowance does not equal the amount provided!") - - }) - - it("should revert if incorrect nonce is provided", async () => { - - const balanceToApprove = 1200; - const nonce = 7000000; - const deadline = toWei(1); - const digest = await getApprovalDigest( - BosonTokenContract, - Buyer.address, - bosonContractAddress, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await truffleAssert.reverts(BosonTokenContract.permit( - Buyer.address, - bosonContractAddress, - balanceToApprove, - deadline, - v, r, s, - { from: Buyer.address } - ), truffleAssert.ErrorType.REVERT) - }) - - it("should revert if incorrect balance is provided", async () => { - - const balanceToApprove = 1200; - const incorrectBalance = 1500; - const nonce = await BosonTokenContract.nonces(Buyer.address); - const deadline = toWei(1); - const digest = await getApprovalDigest( - BosonTokenContract, - Buyer.address, - bosonContractAddress, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await truffleAssert.reverts(BosonTokenContract.permit( - Buyer.address, - bosonContractAddress, - incorrectBalance, - deadline, - v, r, s, - { from: Buyer.address } - ), truffleAssert.ErrorType.REVERT) + it("should revert if owner is incorrect", async () => { + const incorrectSender = users.other1.address + const balanceToApprove = 1200 + const nonce = await BosonTokenContract.nonces(users.buyer.address) + const deadline = toWei(1) + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + bosonContractAddress, + balanceToApprove, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await truffleAssert.reverts(BosonTokenContract.permit( + incorrectSender, + bosonContractAddress, + balanceToApprove, + deadline, + v, r, s, + { from: users.buyer.address } + ), truffleAssert.ErrorType.REVERT) + }) + + it("Should transfer tokens on behalf of the buyer", + async () => { + // Buyer has 1000 preminted tokens + const tokensToMint = 1000 + await BosonTokenContract.mint( + users.buyer.address, + tokensToMint, { + from: users.deployer.address }) - - it("should revert if incorrect recipient is provided", async () => { - const incorrectAddress = accounts[6] - const balanceToApprove = 1200; - const nonce = await BosonTokenContract.nonces(Buyer.address); - const deadline = toWei(1); - const digest = await getApprovalDigest( - BosonTokenContract, - Buyer.address, - bosonContractAddress, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await truffleAssert.reverts(BosonTokenContract.permit( - Buyer.address, - incorrectAddress, - balanceToApprove, - deadline, - v, r, s, - { from: Buyer.address } - ), truffleAssert.ErrorType.REVERT) - }) - - it("should revert if owner is incorrect", async () => { - const incorrectSender = accounts[6] - const balanceToApprove = 1200; - const nonce = await BosonTokenContract.nonces(Buyer.address); - const deadline = toWei(1); - const digest = await getApprovalDigest( - BosonTokenContract, - Buyer.address, - bosonContractAddress, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await truffleAssert.reverts(BosonTokenContract.permit( - incorrectSender, - bosonContractAddress, - balanceToApprove, - deadline, - v, r, s, - { from: Buyer.address } - ), truffleAssert.ErrorType.REVERT) + const balanceToApprove = 200 + const tokensToSend = 200 + + const nonce = await BosonTokenContract.nonces(users.buyer.address) + const deadline = toWei(1) + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + users.deployer.address, + balanceToApprove, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await BosonTokenContract.permit( + users.buyer.address, + users.deployer.address, + balanceToApprove, + deadline, + v, r, s, + { from: users.buyer.address } + ) + + let sellerBalance = await BosonTokenContract + .balanceOf(users.seller.address) + assert.equal(sellerBalance.toString(), 0, + 'Seller has funds') + + await BosonTokenContract.transferFrom( + users.buyer.address, + users.seller.address, + tokensToSend, { + from: users.deployer.address }) - it("Should transfer tokens on behalf of the buyer", async() => { - //Buyer has 1000 preminted tokens - const tokensToMint = 1000 - await BosonTokenContract.mint(Buyer.address, tokensToMint, { from: Deployer.address }); - const balanceToApprove = 200; - const tokensToSend = 200; - - const nonce = await BosonTokenContract.nonces(Buyer.address) - const deadline = toWei(1); - const digest = await getApprovalDigest( - BosonTokenContract, - Buyer.address, - Deployer.address, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await BosonTokenContract.permit( - Buyer.address, - Deployer.address, - balanceToApprove, - deadline, - v, r, s, - { from: Buyer.address } - ) - - - let sellerBalance = await BosonTokenContract.balanceOf(Seller.address) - assert.equal(sellerBalance.toString(), 0, 'Seller has funds') - - await BosonTokenContract.transferFrom(Buyer.address, Seller.address, tokensToSend, { from: Deployer.address}); - - sellerBalance = await BosonTokenContract.balanceOf(Seller.address) - assert.equal(sellerBalance.toString(), tokensToSend, 'Seller has different amount of tokens') + sellerBalance = await BosonTokenContract + .balanceOf(users.seller.address) - }) - - it("Should revert if attacker tries to transfer", async () => { - //Buyer has 1000 preminted tokens - const tokensToMint = 1000 - await BosonTokenContract.mint(Buyer.address, tokensToMint, { from: Deployer.address }); - const balanceToApprove = 200; - const tokensToSend = 200; - - const nonce = await BosonTokenContract.nonces(Buyer.address) - const deadline = toWei(1); - const digest = await getApprovalDigest( - BosonTokenContract, - Buyer.address, - Deployer.address, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(Buyer.pk.slice(2), 'hex')); - - await BosonTokenContract.permit( - Buyer.address, - Deployer.address, - balanceToApprove, - deadline, - v, r, s, - { from: Buyer.address } - ) - - await truffleAssert.reverts(BosonTokenContract.transferFrom(Buyer.address, Seller.address, tokensToSend, { from: Attacker.address })); - - }) + assert.equal( + sellerBalance.toString(), + tokensToSend, + 'Seller has different amount of tokens') }) - - describe("[OWNERSHIP]", async () => { - it("Deployer should be owner initially", async () => { - const owner = await BosonTokenContract.owner() - assert.equal(owner, Deployer.address, "Deployer is not an owner") - }) - - it("Should transfer ownership", async () => { - await BosonTokenContract.transferOwnership(RandomUser.address) - const newOwner = await BosonTokenContract.owner() - - assert.equal(newOwner, RandomUser.address, "ownership has not been transferred") - }) - - it("Should renounce ownership", async () => { - const owner = await BosonTokenContract.owner() - - await BosonTokenContract.renounceOwnership({ from: owner}) - - const newOwner = await BosonTokenContract.owner() - - assert.equal(newOwner, helpers.ZERO_ADDRESS, "ownership has not been renounced") - }) + it("Should revert if attacker tries to transfer", async () => { + // Buyer has 1000 preminted tokens + const tokensToMint = 1000 + await BosonTokenContract.mint( + users.buyer.address, + tokensToMint, { + from: users.deployer.address + }) + const balanceToApprove = 200 + const tokensToSend = 200 + + const nonce = await BosonTokenContract.nonces(users.buyer.address) + const deadline = toWei(1) + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + users.deployer.address, + balanceToApprove, + nonce, + deadline + ) + + const { v, r, s } = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + + await BosonTokenContract.permit( + users.buyer.address, + users.deployer.address, + balanceToApprove, + deadline, + v, r, s, + { from: users.buyer.address } + ) + + await truffleAssert.reverts( + BosonTokenContract.transferFrom( + users.buyer.address, + users.seller.address, + tokensToSend, { + from: users.attacker.address + })) + }) + }) - it("[NEGATIVE] Should revert if calling a function which is allowed only from owner", async () => { - await truffleAssert.reverts(BosonTokenContract.grantMinterRole(Buyer.address, {from: Attacker.address})); - }) + describe("[OWNERSHIP]", async () => { + it("Deployer should be owner initially", async () => { + const owner = await BosonTokenContract.owner() + + assert.equal( + owner, + users.deployer.address, + "Deployer is not an owner") + }) + + it("Should transfer ownership", async () => { + await BosonTokenContract.transferOwnership(users.other1.address) + const newOwner = await BosonTokenContract.owner() + + assert.equal( + newOwner, + users.other1.address, + "ownership has not been transferred") + }) + + it("Should renounce ownership", async () => { + const owner = await BosonTokenContract.owner() + + await BosonTokenContract.renounceOwnership({ from: owner }) + + const newOwner = await BosonTokenContract.owner() + + assert.equal( + newOwner, + constants.ZERO_ADDRESS, + "ownership has not been renounced") + }) + + it("[NEGATIVE] Should revert if calling a function which is " + + "allowed only from owner", + async () => { + await truffleAssert.reverts( + BosonTokenContract.grantMinterRole( + users.buyer.address, { + from: users.attacker.address + })) }) }) - -}) \ No newline at end of file + }) +}) diff --git a/test/5_pausing_contracts.js b/test/5_pausing_contracts.js index 2ad19703..8df34b73 100644 --- a/test/5_pausing_contracts.js +++ b/test/5_pausing_contracts.js @@ -1,1176 +1,1672 @@ -const chai = require('chai') -const assert = chai.assert +const { assert } = require('chai') +const truffleAssert = require('truffle-assertions') -const BN = web3.utils.BN +const constants = require("../testHelpers/constants") +const timemachine = require('../testHelpers/timemachine') +const Users = require('../testHelpers/users') const UtilsBuilder = require('../testHelpers/utilsBuilder') const Utils = require('../testHelpers/utils') -let utils const ERC1155ERC721 = artifacts.require("ERC1155ERC721") const VoucherKernel = artifacts.require("VoucherKernel") const Cashier = artifacts.require("Cashier") const BosonTKN = artifacts.require("BosonTokenPrice") -const FundLimitsOracle = artifacts.require('FundLimitsOracle'); +const FundLimitsOracle = artifacts.require('FundLimitsOracle') -const helpers = require("../testHelpers/constants") -const timemachine = require('../testHelpers/timemachine') -const truffleAssert = require('truffle-assertions') -const config = require('../testHelpers/config.json') +const BN = web3.utils.BN +let utils let TOKEN_SUPPLY_ID let VOUCHER_ID -contract("Cashier && VK", async accounts => { +contract("Cashier && VK", async addresses => { + const users = new Users(addresses) + + let Attacker = users.attacker + + let contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit, + contractFundLimitsOracle + let tokensToMint + let timestamp + + async function deployContracts () { + const sixtySeconds = 60 + + contractFundLimitsOracle = await FundLimitsOracle.new() + contractERC1155ERC721 = await ERC1155ERC721.new() + contractVoucherKernel = await VoucherKernel.new( + contractERC1155ERC721.address) + contractCashier = await Cashier.new( + contractVoucherKernel.address, + contractERC1155ERC721.address, + contractFundLimitsOracle.address) + contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC') + contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP') + + await contractERC1155ERC721 + .setApprovalForAll(contractVoucherKernel.address, 'true') + await contractERC1155ERC721 + .setVoucherKernelAddress(contractVoucherKernel.address) + await contractVoucherKernel + .setCashierAddress(contractCashier.address) + + await contractVoucherKernel.setComplainPeriod(sixtySeconds) + await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds) + + await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenPrice.address, constants.TOKEN_LIMIT) + await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenDeposit.address, constants.TOKEN_LIMIT) + await contractFundLimitsOracle + .setETHLimit(constants.ETHER_LIMIT) + + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + timestamp = await Utils.getCurrTimestamp() + } + + describe('Pausing Scenarios', function () { + describe("CASHIER", () => { + describe("COMMON PAUSING", () => { + before(async () => { + await deployContracts() + }) - let Deployer = config.accounts.deployer - let Seller = config.accounts.seller - let Buyer = config.accounts.buyer - let Attacker = config.accounts.attacker + it("Should not be paused on deployment", async () => { + const isPaused = await contractCashier.paused() - let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit, contractFundLimitsOracle - let tokensToMint - let timestamp + assert.isFalse(isPaused) + }) - async function deployContracts() { + it("Owner should pause the contract", async () => { + await contractCashier.pause() - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new() - contractVoucherKernel = await VoucherKernel.new(contractERC1155ERC721.address) - contractCashier = await Cashier.new(contractVoucherKernel.address, contractERC1155ERC721.address, contractFundLimitsOracle.address) - contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC'); - contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP'); + const isPaused = await contractCashier.paused() - await contractERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true') - await contractERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address) - await contractVoucherKernel.setCashierAddress(contractCashier.address) + assert.isTrue(isPaused) + }) - await contractVoucherKernel.setComplainPeriod(60); //60 seconds - await contractVoucherKernel.setCancelFaultPeriod(60); //60 seconds + it("Owner should unpause the contract", async () => { + await contractCashier.pause() + await contractCashier.unpause() - await contractFundLimitsOracle.setTokenLimit(contractBSNTokenPrice.address, helpers.TOKEN_LIMIT) - await contractFundLimitsOracle.setTokenLimit(contractBSNTokenDeposit.address, helpers.TOKEN_LIMIT) - await contractFundLimitsOracle.setETHLimit(helpers.ETHER_LIMIT) + const isPaused = await contractCashier.paused() + assert.isFalse(isPaused) + }) - utils = UtilsBuilder - .NEW() + it("[NEGATIVE] Attacker should not be able to pause the contract", + async () => { + await truffleAssert.reverts( + contractCashier.pause({ from: Attacker.address }), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Attacker should not be able to unpause the contract", + async () => { + await contractCashier.pause() + + await truffleAssert.reverts( + contractCashier.unpause({ from: Attacker.address }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("ETH_ETH", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier) - timestamp = await Utils.getCurrTimestamp() - } - - describe('Pausing Scenarios', function () { - - describe("CASHIER", () => { - - describe("COMMON PAUSING", () => { - before(async () => { - await deployContracts(); - }) - - it("Should not be paused on deployment", async () => { - const isPaused = await contractCashier.paused(); - assert.isFalse(isPaused) - }); - - it("Owner should pause the contract", async () => { - await contractCashier.pause(); - - const isPaused = await contractCashier.paused(); - assert.isTrue(isPaused) - }); - - it("Owner should unpause the contract", async () => { - await contractCashier.pause(); - await contractCashier.unpause(); - - const isPaused = await contractCashier.paused(); - assert.isFalse(isPaused) - }); - - it("[NEGATIVE] Attacker should not be able to pause the contract", async () => { - await truffleAssert.reverts( - contractCashier.pause({ from: Attacker.address }), - truffleAssert.ErrorType.REVERT - ) - }); - - it("[NEGATIVE] Attacker should not be able to unpause the contract", async () => { - await contractCashier.pause(); - - await truffleAssert.reverts( - contractCashier.unpause({ from: Attacker.address }), - truffleAssert.ErrorType.REVERT - ) - }); + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + const timestamp = await Utils.getCurrTimestamp() + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) + + it("[NEGATIVE] Should not create voucher supply when " + + "contract is paused", + async () => { + await contractCashier.pause() + + await truffleAssert.reverts( + utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1), + truffleAssert.ErrorType.REVERT + ) + }) + + it("Should create voucher supply when contract is unpaused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + assert.isNotEmpty(TOKEN_SUPPLY_ID) + }) + + it("[NEGATIVE] Should not create voucherID from Buyer when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process withdrawals when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("withdrawWhenPaused - Buyer should be able to withdraw " + + "funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.buyer.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") + }) + + it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("withdrawWhenPaused - Seller should be able to withdraw " + + "funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.seller.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") + }) + + it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + + "able to withdraw funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("[WITH PERMIT]", () => { + describe("ETH_TKN", () => { + before(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMint = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMint) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) + + it("[NEGATIVE] Should not create voucher supply when " + + "contract is paused", + async () => { + await contractCashier.pause() + + await truffleAssert.reverts( + utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1), + truffleAssert.ErrorType.REVERT + ) + }) + + it("Should create voucher supply when contract is unpaused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + assert.isNotEmpty(TOKEN_SUPPLY_ID) + }) + + it("[NEGATIVE] Should not create voucherID from Buyer " + + "when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) }) - describe("ETH_ETH", () => { - - before(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); - - const timestamp = await Utils.getCurrTimestamp() - - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) - - }) - - it("[NEGATIVE] Should not create voucher supply when contract is paused", async () => { - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should create voucher supply when contract is unpaused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) - - it("[NEGATIVE] Should not create voucherID from Buyer when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process withdrawals when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdraw(voucherID, Deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Buyer should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Buyer.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Seller should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Seller.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - + it("[NEGATIVE] Should not process withdrawals when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ) }) - - describe("[WITH PERMIT]", () => { - - describe("ETH_TKN", () => { - - before(async () => { - - await deployContracts(); - - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMint); - - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) - }) - - it("[NEGATIVE] Should not create voucher supply when contract is paused", async () => { - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should create voucher supply when contract is unpaused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) - - it("[NEGATIVE] Should not create voucherID from Buyer when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process withdrawals when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdraw(voucherID, Deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Buyer should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Buyer.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Seller should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Seller.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKN_ETH", () => { - - before(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, '') - - const timestamp = await Utils.getCurrTimestamp() - - tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMint); - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) - - it("[NEGATIVE] Should not create voucher supply when contract is paused", async () => { - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should create voucher supply when contract is unpaused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) - - it("[NEGATIVE] Should not create voucherID from Buyer when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process withdrawals when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdraw(voucherID, Deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Buyer should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Buyer.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Seller should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Seller.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - - - }) - - describe("TKN_TKN", () => { - before(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - tokensToMint = new BN(helpers.seller_deposit).mul(new BN(helpers.QTY_10)) - tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMint); - }) - - - it("[NEGATIVE] Should not create voucher supply when contract is paused", async () => { - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should create voucher supply when contract is unpaused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) - - it("[NEGATIVE] Should not create voucherID from Buyer when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process withdrawals when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdraw(voucherID, Deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Buyer should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Buyer.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("withdrawWhenPaused - Seller should be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - const withdrawTx = await utils.withdrawWhenPaused(voucherID, Seller.address) - - truffleAssert.eventEmitted(withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be able to withdraw funds when not paused", async () => { - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_1) - - const voucherID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, Buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, Deployer.address) - - await truffleAssert.reverts( - utils.withdrawWhenPaused(voucherID, Attacker.address), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - + + it("withdrawWhenPaused - Buyer should be able to " + + "withdraw funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.buyer.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") + }) + + it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("withdrawWhenPaused - Seller should be able to " + + "withdraw funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.seller.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") + }) + + it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + + "able to withdraw funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] withdrawWhenPaused - Attacker should not " + + "be able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) }) - }) - - describe("VOUCHER KERNEL", () => { - - describe("COMMON PAUSING", () => { - before(async () => { - await deployContracts(); - }) - - it("Should not be paused on deployment", async () => { - const isPaused = await contractVoucherKernel.paused(); - assert.isFalse(isPaused) - }); - - it("Should be paused from cashier", async () => { - await contractCashier.pause(); - - const isPaused = await contractVoucherKernel.paused(); - assert.isTrue(isPaused) - }); - - it("Should be unpaused from cashier", async () => { - await contractCashier.pause(); - await contractCashier.unpause(); - - const isPaused = await contractVoucherKernel.paused(); - assert.isFalse(isPaused) - }); - - it("[NEGATIVE] Pause should not be called directly", async () => { - await truffleAssert.reverts( - contractVoucherKernel.pause(), - truffleAssert.ErrorType.REVERT - ) - }); - - it("[NEGATIVE] Pause should not be called directly", async () => { - await truffleAssert.reverts( - contractVoucherKernel.unpause(), - truffleAssert.ErrorType.REVERT - ) - }); + describe("TKN_ETH", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '') + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMint = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMint) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + it("[NEGATIVE] Should not create voucher supply when " + + "contract is paused", async () => { + await contractCashier.pause() + + await truffleAssert.reverts( + utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1), + truffleAssert.ErrorType.REVERT + ) + }) + + it("Should create voucher supply when contract is unpaused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + assert.isNotEmpty(TOKEN_SUPPLY_ID) + }) + + it("[NEGATIVE] Should not create voucherID from Buyer " + + "when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process withdrawals when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("withdrawWhenPaused - Buyer should be able to withdraw " + + "funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.buyer.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") }) - describe("ETH_ETH", () => { - before(async () => { - await deployContracts(); + it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - utils = UtilsBuilder - .NEW() - .ETH_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); + it("withdrawWhenPaused - Seller should be able to withdraw " + + "funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.seller.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") + }) - const timestamp = await Utils.getCurrTimestamp() + it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) - - }) - - it("[NEGATIVE] Should not process refund when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + + "able to withdraw funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) + }) - await contractCashier.pause(); + it("[NEGATIVE] withdrawWhenPaused - Attacker should not " + + "be able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + describe("TKN_TKN", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + tokensToMint = + new BN(constants.seller_deposit) + .mul(new BN(constants.QTY_10)) + tokensToMint = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMint) + }) + + it("[NEGATIVE] Should not create voucher supply when " + + "contract is paused", + async () => { + await contractCashier.pause() + + await truffleAssert.reverts( + utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1), + truffleAssert.ErrorType.REVERT + ) + }) - it("[NEGATIVE] Should not process complain when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + it("Should create voucher supply when contract is unpaused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + assert.isNotEmpty(TOKEN_SUPPLY_ID) + }) - await utils.refund(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); + it("[NEGATIVE] Should not create voucherID from Buyer when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ) + }) - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + it("[NEGATIVE] Should not process withdrawals when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ) + }) - it("[NEGATIVE] Should not process redeem when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + it("withdrawWhenPaused - Buyer should be able to withdraw " + + "funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.buyer.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") + }) - await contractCashier.pause(); + it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + it("withdrawWhenPaused - Seller should be able to withdraw " + + "funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + const withdrawTx = await utils + .withdrawWhenPaused(voucherID, users.seller.address) + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true + }, "Amounts not distributed successfully") + }) - it("[NEGATIVE] Should not process cancel when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.redeem(VOUCHER_ID, Buyer.address) + it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) - await contractCashier.pause(); + it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + + "able to withdraw funds when paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) + }) - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - + it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + + "able to withdraw funds when not paused", + async () => { + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1) + + const voucherID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.refund(voucherID, users.buyer.address) + + await timemachine.advanceTimeSeconds(60) + await utils.finalize(voucherID, users.deployer.address) + + await truffleAssert.reverts( + utils.withdrawWhenPaused(voucherID, Attacker.address), + truffleAssert.ErrorType.REVERT + ) }) - - describe("[WITH PERMIT]", () => { + }) + }) + }) - describe("ETH_TKN", () => { + describe("VOUCHER KERNEL", () => { + describe("COMMON PAUSING", () => { + before(async () => { + await deployContracts() + }) - before(async () => { - await deployContracts() - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .ETH_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) + it("Should not be paused on deployment", async () => { + const isPaused = await contractVoucherKernel.paused() + assert.isFalse(isPaused) + }) - const timestamp = await Utils.getCurrTimestamp() + it("Should be paused from cashier", async () => { + await contractCashier.pause() - tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) + const isPaused = await contractVoucherKernel.paused() + assert.isTrue(isPaused) + }) - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMint); + it("Should be unpaused from cashier", async () => { + await contractCashier.pause() + await contractCashier.unpause() - TOKEN_SUPPLY_ID = await utils.createOrder(Seller, timestamp, timestamp + helpers.SECONDS_IN_DAY, helpers.seller_deposit, helpers.QTY_10) + const isPaused = await contractVoucherKernel.paused() + assert.isFalse(isPaused) + }) - }) + it("[NEGATIVE] Pause should not be called directly", + async () => { + await truffleAssert.reverts( + contractVoucherKernel.pause(), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Pause should not be called directly", + async () => { + await truffleAssert.reverts( + contractVoucherKernel.unpause(), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("ETH_ETH", () => { + before(async () => { + await deployContracts() + + utils = UtilsBuilder.create() + .ETH_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier) + + const timestamp = await Utils.getCurrTimestamp() + + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) - it("[NEGATIVE] Should not process refund when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + it("[NEGATIVE] Should not process refund when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process complain when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await utils.refund(VOUCHER_ID, users.buyer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process redeem when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process cancel when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await utils.redeem(VOUCHER_ID, users.buyer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) + + describe("[WITH PERMIT]", () => { + describe("ETH_TKN", () => { + before(async () => { + await deployContracts() + await deployContracts() + utils = UtilsBuilder + .create() + .ERC20withPermit() + .ETH_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMint = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMint) + + TOKEN_SUPPLY_ID = await utils + .createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10) + }) + + it("[NEGATIVE] Should not process refund when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - await contractCashier.pause(); + it("[NEGATIVE] Should not process complain when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await utils.refund(VOUCHER_ID, users.buyer.address) - it("[NEGATIVE] Should not process complain when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + await contractCashier.pause() - await utils.refund(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + it("[NEGATIVE] Should not process redeem when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - it("[NEGATIVE] Should not process redeem when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + await contractCashier.pause() - await contractCashier.pause(); + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + it("[NEGATIVE] Should not process cancel when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(VOUCHER_ID, users.buyer.address) - it("[NEGATIVE] Should not process cancel when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.redeem(VOUCHER_ID, Buyer.address) + await contractCashier.pause() - await contractCashier.pause(); + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - + describe("TKN_ETH", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_ETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '') + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMint = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMint) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + it("[NEGATIVE] Should not process refund when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - }) + it("[NEGATIVE] Should not process complain when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - describe("TKN_ETH", () => { + await utils.refund(VOUCHER_ID, users.buyer.address) - before(async () => { - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_ETH() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, '') + await contractCashier.pause() - const timestamp = await Utils.getCurrTimestamp() + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) + it("[NEGATIVE] Should not process redeem when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMint); + await contractCashier.pause() - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - it("[NEGATIVE] Should not process refund when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + it("[NEGATIVE] Should not process cancel when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(VOUCHER_ID, users.buyer.address) - await contractCashier.pause(); + await contractCashier.pause() - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) + }) - it("[NEGATIVE] Should not process complain when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + describe("TKN_TKN", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMint = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMint) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + it("[NEGATIVE] Should not process refund when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) - await utils.refund(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); + it("[NEGATIVE] Should not process complain when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await utils.refund(VOUCHER_ID, users.buyer.address) - it("[NEGATIVE] Should not process redeem when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) + await contractCashier.pause() - await contractCashier.pause(); + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process redeem when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process cancel when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(VOUCHER_ID, users.buyer.address) - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process cancel when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.redeem(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("TKN_TKN", () => { - - before(async () => { - - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenDeposit', Seller.address, tokensToMint); - await utils.mintTokens('contractBSNTokenPrice', Buyer.address, tokensToMint); - await utils.mintTokens('contractBSNTokenDeposit', Buyer.address, tokensToMint); - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) - - it("[NEGATIVE] Should not process refund when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process complain when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - - await utils.refund(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process redeem when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process cancel when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.redeem(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - // Ignored due to deployment failure. - xdescribe("TKN_TKN_SAME", () => { - - before(async () => { - - await deployContracts(); - utils = UtilsBuilder - .NEW() - .ERC20withPermit() - .TKN_TKN_SAME() - .build(contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - tokensToMint = new BN(helpers.product_price).mul(new BN(helpers.QTY_10)) - - await utils.mintTokens('contractBSNTokenSAME', Seller.address, tokensToMint) - await utils.mintTokens('contractBSNTokenSAME', Buyer.address, tokensToMint) - - TOKEN_SUPPLY_ID = await utils.createOrder( - Seller, - timestamp, - timestamp + helpers.SECONDS_IN_DAY, - helpers.seller_deposit, - helpers.QTY_10 - ) - }) - - it("[NEGATIVE] Should not process refund when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process complain when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - - await utils.refund(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process redeem when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, Buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not process cancel when paused", async () => { - VOUCHER_ID = await utils.commitToBuy(Buyer, Seller, TOKEN_SUPPLY_ID); - await utils.redeem(VOUCHER_ID, Buyer.address) - - await contractCashier.pause(); - - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, Seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await contractCashier.pause() + + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) }) - }) - afterEach(async () => { - const isPaused = await contractCashier.paused(); - if (isPaused) { - await contractCashier.unpause(); - } + // Ignored due to deployment failure. + xdescribe("TKN_TKN_SAME", () => { + before(async () => { + await deployContracts() + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKN_TKN_SAME() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit) + + const timestamp = await Utils.getCurrTimestamp() + + tokensToMint = + new BN(constants.product_price) + .mul(new BN(constants.QTY_10)) + + await utils.mintTokens( + 'contractBSNTokenSAME', + users.seller.address, + tokensToMint) + await utils.mintTokens( + 'contractBSNTokenSAME', + users.buyer.address, + tokensToMint) + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ) + }) + + it("[NEGATIVE] Should not process refund when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process complain when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await utils.refund(VOUCHER_ID, users.buyer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process redeem when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ) + }) + + it("[NEGATIVE] Should not process cancel when paused", + async () => { + VOUCHER_ID = await utils + .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + await utils.redeem(VOUCHER_ID, users.buyer.address) + + await contractCashier.pause() + + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ) + }) }) + }) }) -}) + afterEach(async () => { + const isPaused = await contractCashier.paused() + if (isPaused) { + await contractCashier.unpause() + } + }) + }) +}) diff --git a/test/6_fundLimits.js b/test/6_fundLimits.js index 1c157833..20420ea4 100644 --- a/test/6_fundLimits.js +++ b/test/6_fundLimits.js @@ -1,121 +1,151 @@ -const helpers = require("../testHelpers/constants"); -const truffleAssert = require('truffle-assertions'); - -const ERC1155ERC721 = artifacts.require("ERC1155ERC721"); -const VoucherKernel = artifacts.require("VoucherKernel"); -const Cashier = artifacts.require("Cashier"); -const BosonToken = artifacts.require('BosonTokenPrice'); -const FundLimitsOracle = artifacts.require('FundLimitsOracle'); - -const BN = web3.utils.BN - -const UtilsBuilder = require('../testHelpers/utilsBuilder'); -const Utils = require('../testHelpers/utils'); -let utils; -const config = require('../testHelpers/config.json'); -const { assert } = require("chai"); - -contract("FundLimitsOracle", async accounts => { - let Deployer = config.accounts.deployer - let Attacker = config.accounts.attacker - - let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit, contractFundLimitsOracle; - let expectedLimit - const FIVE_ETHERS = (5 * 10 ** 18).toString() - const FIVE_TOKENS = (5 * 10 ** 16).toString() - - async function deployContracts() { - const timestamp = await Utils.getCurrTimestamp() - helpers.PROMISE_VALID_FROM = timestamp - helpers.PROMISE_VALID_TO = timestamp + 2 * helpers.SECONDS_IN_DAY; - - contractFundLimitsOracle = await FundLimitsOracle.new(); - - contractERC1155ERC721 = await ERC1155ERC721.new(); - contractVoucherKernel = await VoucherKernel.new(contractERC1155ERC721.address); - contractCashier = await Cashier.new(contractVoucherKernel.address, contractERC1155ERC721.address, contractFundLimitsOracle.address); - - contractBSNTokenPrice = await BosonToken.new("BosonTokenPrice", "BPRC"); - contractBSNTokenDeposit = await BosonToken.new("BosonTokenDeposit", "BDEP"); - - await contractERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true'); - await contractERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address); - await contractVoucherKernel.setCashierAddress(contractCashier.address); - } - - describe('FundLimitsOracle interaction', function() { - - before(async () => { - await deployContracts() - }) +const { assert } = require("chai") +const truffleAssert = require('truffle-assertions') - describe("ETH", () => { - it("Should have set ETH Limit initially to 1 ETH", async () => { - const ONE_ETH = (1 * 10 ** 18).toString() - - const ethLimit = await contractFundLimitsOracle.getETHLimit() - - assert.equal(ethLimit.toString(), ONE_ETH, "ETH Limit not set properly") - }) - - it("Owner should change ETH Limit", async () => { - - await contractFundLimitsOracle.setETHLimit(FIVE_ETHERS); - - expectedLimit = await contractFundLimitsOracle.getETHLimit() - - assert.equal(expectedLimit.toString(), FIVE_ETHERS, "ETH Limit not correctly set") - }) - - it("Should emit LogETHLimitChanged", async () => { - - setLimitTx = await contractFundLimitsOracle.setETHLimit(FIVE_ETHERS); - - truffleAssert.eventEmitted(setLimitTx, 'LogETHLimitChanged', (ev) => { - return ev._triggeredBy == Deployer.address - }, - "LogETHLimitChanged was not emitted" - ) - }) - - it("[NEGATIVE] Should revert if attacker tries to change ETH Limit", async () => { - await truffleAssert.reverts( - contractFundLimitsOracle.setETHLimit(FIVE_ETHERS, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) - }) +const constants = require("../testHelpers/constants") +const Users = require('../testHelpers/users') +const Utils = require('../testHelpers/utils') + +const ERC1155ERC721 = artifacts.require("ERC1155ERC721") +const VoucherKernel = artifacts.require("VoucherKernel") +const Cashier = artifacts.require("Cashier") +const BosonToken = artifacts.require('BosonTokenPrice') +const FundLimitsOracle = artifacts.require('FundLimitsOracle') + +contract("FundLimitsOracle", async addresses => { + const users = new Users(addresses) + + let contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit, + contractFundLimitsOracle + let expectedLimit + + const FIVE_ETHERS = (5 * 10 ** 18).toString() + const FIVE_TOKENS = (5 * 10 ** 16).toString() + + async function deployContracts () { + const timestamp = await Utils.getCurrTimestamp() + + constants.PROMISE_VALID_FROM = timestamp + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY + + contractFundLimitsOracle = await FundLimitsOracle.new() + + contractERC1155ERC721 = await ERC1155ERC721.new() + contractVoucherKernel = await VoucherKernel.new( + contractERC1155ERC721.address) + contractCashier = await Cashier.new( + contractVoucherKernel.address, + contractERC1155ERC721.address, + contractFundLimitsOracle.address) + + contractBSNTokenPrice = await BosonToken.new("BosonTokenPrice", "BPRC") + contractBSNTokenDeposit = await BosonToken.new("BosonTokenDeposit", "BDEP") + + await contractERC1155ERC721 + .setApprovalForAll(contractVoucherKernel.address, 'true') + await contractERC1155ERC721 + .setVoucherKernelAddress(contractVoucherKernel.address) + await contractVoucherKernel + .setCashierAddress(contractCashier.address) + } + + describe('FundLimitsOracle interaction', () => { + before(async () => { + await deployContracts() + }) + + describe("ETH", () => { + it("Should have set ETH Limit initially to 1 ETH", async () => { + const ONE_ETH = (10 ** 18).toString() - describe("Token", () => { - - it("Owner should set Token Limit", async () => { - - await contractFundLimitsOracle.setTokenLimit(contractBSNTokenPrice.address, FIVE_TOKENS); - - expectedLimit = await contractFundLimitsOracle.getTokenLimit(contractBSNTokenPrice.address) - - assert.equal(expectedLimit.toString(), FIVE_TOKENS, "ETH Limit not correctly set") - }) - - it("Should emit LogTokenLimitChanged", async () => { - - setLimitTx = await contractFundLimitsOracle.setTokenLimit(contractBSNTokenPrice.address, FIVE_TOKENS); - - truffleAssert.eventEmitted(setLimitTx, 'LogTokenLimitChanged', (ev) => { - return ev._triggeredBy == Deployer.address - }, - "LogETHLimitChanged was not emitted" - ) - }) - - it("[NEGATIVE] Should revert if attacker tries to change Token Limit", async () => { - await truffleAssert.reverts( - contractFundLimitsOracle.setTokenLimit(contractBSNTokenPrice.address, FIVE_TOKENS, {from: Attacker.address}), - truffleAssert.ErrorType.REVERT - ) - }) + const ethLimit = await contractFundLimitsOracle.getETHLimit() + + assert.equal( + ethLimit.toString(), + ONE_ETH, + "ETH Limit not set properly") + }) + + it("Owner should change ETH Limit", async () => { + await contractFundLimitsOracle.setETHLimit(FIVE_ETHERS) + + expectedLimit = await contractFundLimitsOracle.getETHLimit() + + assert.equal( + expectedLimit.toString(), + FIVE_ETHERS, + "ETH Limit not correctly set") + }) + + it("Should emit LogETHLimitChanged", async () => { + const setLimitTx = await contractFundLimitsOracle + .setETHLimit(FIVE_ETHERS) + + truffleAssert.eventEmitted( + setLimitTx, + 'LogETHLimitChanged', + (ev) => { + return ev._triggeredBy === users.deployer.address + }, + "LogETHLimitChanged was not emitted" + ) + }) + + it("[NEGATIVE] Should revert if attacker tries to change ETH Limit", + async () => { + await truffleAssert.reverts( + contractFundLimitsOracle.setETHLimit( + FIVE_ETHERS, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) }) - - }) + }) -}); \ No newline at end of file + describe("Token", () => { + it("Owner should set Token Limit", async () => { + await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenPrice.address, FIVE_TOKENS) + + expectedLimit = await contractFundLimitsOracle + .getTokenLimit(contractBSNTokenPrice.address) + + assert.equal( + expectedLimit.toString(), + FIVE_TOKENS, + "ETH Limit not correctly set") + }) + + it("Should emit LogTokenLimitChanged", async () => { + const setLimitTx = await contractFundLimitsOracle + .setTokenLimit(contractBSNTokenPrice.address, FIVE_TOKENS) + + truffleAssert.eventEmitted( + setLimitTx, + 'LogTokenLimitChanged', + ev => { + return ev._triggeredBy === users.deployer.address + }, + "LogETHLimitChanged was not emitted" + ) + }) + + it("[NEGATIVE] Should revert if attacker tries to change " + + "Token Limit", + async () => { + await truffleAssert.reverts( + contractFundLimitsOracle.setTokenLimit( + contractBSNTokenPrice.address, + FIVE_TOKENS, { + from: users.attacker.address + }), + truffleAssert.ErrorType.REVERT + ) + }) + }) + }) +}) \ No newline at end of file diff --git a/testHelpers/accounts.js b/testHelpers/accounts.js deleted file mode 100644 index d7801d23..00000000 --- a/testHelpers/accounts.js +++ /dev/null @@ -1,19 +0,0 @@ -class Accounts { - constructor(accountSet) { - this.accountSet = accountSet - } - - get seller() { - return this.accountSet[1] - } - - get buyer() { - return this.accountSet[2] - } - - get attacker() { - return this.accountSet[3] - } -} - -module.exports = Accounts diff --git a/testHelpers/config.json b/testHelpers/config.json deleted file mode 100644 index 6c098e21..00000000 --- a/testHelpers/config.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "defaultGasPrice": 50000000000, - "defaultGasLimit": 4700000, - "defaultChainId": 0, - "nodeUrl": "http://localhost:8545/", - "ganacheCliPort": 8545, - "accounts": { - "deployer": { - "address": "0xD9995BAE12FEe327256FFec1e3184d492bD94C31", - "pk": "0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8" - }, - "seller": { - "address": "0xd4Fa489Eacc52BA59438993f37Be9fcC20090E39", - "pk": "0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f" - }, - "buyer": { - "address": "0x760bf27cd45036a6C486802D30B5D90CfFBE31FE", - "pk": "0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2" - }, - "attacker": { - "address":"0x56A32fFf5E5A8B40d6A21538579fB8922DF5258c", - "pk": "0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a" - }, - "randomUser": { - "address": "0xf0508F89e26Bd6b00f66a9D467678C7ED16a3C5A", - "pk": "0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543" - }, - "randomUser2": { - "address": "0x8199de05654e9afa5C081BcE38F140082C9a7733", - "pk": "0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a" - } - } -} \ No newline at end of file diff --git a/testHelpers/users.js b/testHelpers/users.js new file mode 100644 index 00000000..dd214497 --- /dev/null +++ b/testHelpers/users.js @@ -0,0 +1,80 @@ +const fs = require('fs') + +const defaultPrivateKeys = { + "0xd9995bae12fee327256ffec1e3184d492bd94c31": + "0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8", + "0xd4fa489eacc52ba59438993f37be9fcc20090e39": + "0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f", + "0x760bf27cd45036a6c486802d30b5d90cffbe31fe": + "0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2", + "0x56a32fff5e5a8b40d6a21538579fb8922df5258c": + "0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a", + "0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a": + "0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543", + "0x8199de05654e9afa5c081bce38f140082c9a7733": + "0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a" +} + +const userIndices = { + deployer: 0, + seller: 1, + buyer: 2, + attacker: 3, + other1: 4, + other2: 5 +} + +const loadPrivateKeys = accountKeysFile => { + let privateKeys = defaultPrivateKeys + + if(accountKeysFile) { + const accountKeysRaw = fs.readFileSync(accountKeysFile) + const accountKeysJs = JSON.parse(accountKeysRaw) + + privateKeys = Object.fromEntries( + Object.entries(accountKeysJs["private_keys"]) + .map(entry => [entry[0], `0x${entry[1]}`])) + } + + return privateKeys +} + +class Users { + constructor(addresses) { + this.addresses = addresses + this.privateKeys = loadPrivateKeys(process.env.ACCOUNT_KEYS_FILE) + } + + getAccountAtIndex(index) { + const address = this.addresses[index] + const privateKey = this.privateKeys[address.toLowerCase()] + + return { address, privateKey } + } + + get deployer() { + return this.getAccountAtIndex(userIndices.deployer) + } + + get seller() { + return this.getAccountAtIndex(userIndices.seller) + } + + get buyer() { + return this.getAccountAtIndex(userIndices.buyer) + } + + get attacker() { + return this.getAccountAtIndex(userIndices.attacker) + } + + get other1() { + return this.getAccountAtIndex(userIndices.other1) + } + + get other2() { + return this.getAccountAtIndex(userIndices.other2) + } +} + +module.exports = Users diff --git a/testHelpers/utils.js b/testHelpers/utils.js index 02c56e91..ebea161a 100644 --- a/testHelpers/utils.js +++ b/testHelpers/utils.js @@ -68,7 +68,7 @@ class Utils { const { v, r, s } = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.pk.slice(2), 'hex')) + Buffer.from(seller.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier .requestCreateOrder_TKN_TKN_WithPermit( @@ -111,7 +111,7 @@ class Utils { const { v, r, s } = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.pk.slice(2), 'hex')) + Buffer.from(seller.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier .requestCreateOrder_TKN_TKN_WithPermit( @@ -153,7 +153,7 @@ class Utils { const { v, r, s } = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.pk.slice(2), 'hex')) + Buffer.from(seller.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier .requestCreateOrder_ETH_TKN_WithPermit( @@ -219,7 +219,7 @@ class Utils { let VRS_DEPOSIT = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex')) let vDeposit = VRS_DEPOSIT.v let rDeposit = VRS_DEPOSIT.r @@ -238,7 +238,7 @@ class Utils { let VRS_PRICE = ecsign( Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex')) let vPrice = VRS_PRICE.v let rPrice = VRS_PRICE.r @@ -281,7 +281,7 @@ class Utils { let VRS_TX_VALUE = ecsign( Buffer.from(digestTxValue.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex')) let v = VRS_TX_VALUE.v let r = VRS_TX_VALUE.r @@ -321,7 +321,7 @@ class Utils { let { v, r, s } = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier .requestVoucher_ETH_TKN_WithPermit( @@ -382,7 +382,7 @@ class Utils { let { v, r, s } = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.pk.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier .requestVoucher_TKN_ETH_WithPermit( diff --git a/testHelpers/utilsBuilder.js b/testHelpers/utilsBuilder.js index aff462b0..e9a528d7 100644 --- a/testHelpers/utilsBuilder.js +++ b/testHelpers/utilsBuilder.js @@ -6,7 +6,7 @@ class UtilsBuilder { this.utils = new Utils() } - static NEW () { + static create () { return new UtilsBuilder() }; From 4914071c4bc04055599d439353fbd3af60015962 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Wed, 20 Jan 2021 22:28:33 +0000 Subject: [PATCH 10/22] Fix coverage. --- .solcover.js | 2 +- package.json | 2 +- testHelpers/users.js | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.solcover.js b/.solcover.js index 65e7e0c6..1d1afa35 100644 --- a/.solcover.js +++ b/.solcover.js @@ -3,7 +3,7 @@ module.exports = { testCommand: 'mocha --timeout 5000', measureStatementCoverage: false, providerOptions: { - //Default Accounts with preminted 10ETH + // Default Accounts with preminted 10ETH accounts: [ { secretKey: '0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8', balance: "0x8ac7230489e80000" diff --git a/package.json b/package.json index 32ba2c36..afefce93 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "scripts": { "compile": "truffle compile --all", "test:integration": "truffle test --network test", - "coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage", + "test:coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage", "migrate-dev": "truffle migrate --network=rinkeby", "verify-dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby" }, diff --git a/testHelpers/users.js b/testHelpers/users.js index dd214497..f6614a32 100644 --- a/testHelpers/users.js +++ b/testHelpers/users.js @@ -9,10 +9,18 @@ const defaultPrivateKeys = { "0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2", "0x56a32fff5e5a8b40d6a21538579fb8922df5258c": "0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a", + "0xfec44e15328b7d1d8885a8226b0858964358f1d6": + "0x823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2", + "0xda8a06f1c910cab18ad187be1faa2b8606c2ec86": + "0xd6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3", + "0x8199de05654e9afa5c081bce38f140082c9a7733": + "0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a", + "0x28bf45680ca598708e5cdacc1414fcac04a3f1ed": + "0xf41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25", "0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a": "0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543", - "0x8199de05654e9afa5c081bce38f140082c9a7733": - "0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a" + "0x87e0ED760fb316eeb94Bd9cF23D1d2BE87aCe3d8": + "0xfac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186", } const userIndices = { From 02a2c9b4f884d29630b57af94589ee93a4d21be6 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Wed, 20 Jan 2021 22:40:50 +0000 Subject: [PATCH 11/22] Add rake task to run test coverage. --- Rakefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Rakefile b/Rakefile index 665e5924..5a1a5267 100644 --- a/Rakefile +++ b/Rakefile @@ -51,4 +51,10 @@ namespace :test do }, 'npm run test:integration') end end + + desc "Run test coverage for contract integration tests" + task :coverage do + puts "Running test coverage for contract integration tests..." + sh('npm run test:coverage') + end end From 5024da7c3767788a25d44aedecd1abe0557ad203 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Wed, 20 Jan 2021 23:49:17 +0000 Subject: [PATCH 12/22] Add solhint. Fix as many warnings as possible. --- .solhint.json | 15 + Rakefile | 40 +- contracts/BosonTokenDeposit.sol | 9 +- contracts/BosonTokenPrice.sol | 9 +- contracts/Cashier.sol | 112 +-- contracts/ERC20WithPermit.sol | 10 +- contracts/ICashier.sol | 18 +- contracts/IERC1155.sol | 2 +- contracts/IERC20WithPermit.sol | 4 +- contracts/IVoucherKernel.sol | 2 +- contracts/Migrations.sol | 10 +- .../{usingHelpers.sol => UsingHelpers.sol} | 32 +- contracts/VoucherKernel.sol | 54 +- doc_contracts.md | 8 +- package-lock.json | 941 +++++++++++++++++- package.json | 5 +- test/1_test_fullpath.js | 16 +- test/2_test_fullpath_with_permit.js | 200 ++-- test/3_withdrawals.js | 24 +- test/5_pausing_contracts.js | 38 +- testHelpers/utils.js | 40 +- testHelpers/utilsBuilder.js | 38 +- 22 files changed, 1292 insertions(+), 335 deletions(-) create mode 100644 .solhint.json rename contracts/{usingHelpers.sol => UsingHelpers.sol} (66%) diff --git a/.solhint.json b/.solhint.json new file mode 100644 index 00000000..5207f68c --- /dev/null +++ b/.solhint.json @@ -0,0 +1,15 @@ +{ + "extends": "solhint:recommended", + "rules": { + "compiler-version": [ + "error", + "^0.6.6" + ], + "reason-string": [ + "warn", + { + "maxLength": 64 + } + ] + } +} diff --git a/Rakefile b/Rakefile index 5a1a5267..a08824ef 100644 --- a/Rakefile +++ b/Rakefile @@ -1,38 +1,54 @@ require_relative 'lib/ganache' -task :default => :"contracts:compile" +task :default => [ + :"contracts:compile", + :"contracts:lint_fix", + :"test:integration" +] namespace :ganache do + desc "Start ganache on provided port, default 8545" task :start, [:port] do |_, args| - port = args.port + args.with_defaults(port: 8545) - puts "Starting ganache on port #{port}..." + puts "Starting ganache on port #{args.port}..." ganache = Ganache.builder - .on_port(port) + .on_port(args.port) .allowing_unlimited_contract_size .build ganache.start - puts "Started ganache on port #{port}" + puts "Started ganache on port #{args.port}" puts " - with pidfile at #{ganache.pidfile}" puts " - with account keys file at #{ganache.account_keys_file}" end + desc "Stop ganache on provided port, default 8545" task :stop, [:port] do |_, args| - port = args.port + args.with_defaults(port: 8545) - puts "Stopping ganache on port #{port}..." + puts "Stopping ganache on port #{args.port}..." ganache = Ganache.builder - .on_port(port) + .on_port(args.port) .build ganache.stop - puts "Stopped ganache on port #{port}" + puts "Stopped ganache on port #{args.port}" end end namespace :contracts do desc "Compile all contracts" task :compile do - sh('npm run compile') + sh('npm', 'run', 'contracts:compile') + end + + desc "Lint all contracts" + task :lint do + sh('npm', 'run', 'contracts:lint') + end + + desc "Lint & fix all contracts" + task :lint_fix do + sh('npm', 'run', 'contracts:lint-fix') end end @@ -48,13 +64,13 @@ namespace :test do "HOST" => "127.0.0.1", "PORT" => "#{ganache.port}", "ACCOUNT_KEYS_FILE" => "#{ganache.account_keys_file}" - }, 'npm run test:integration') + }, 'npm', 'run', 'test:integration') end end desc "Run test coverage for contract integration tests" task :coverage do puts "Running test coverage for contract integration tests..." - sh('npm run test:coverage') + sh(['npm', 'run', 'test:coverage']) end end diff --git a/contracts/BosonTokenDeposit.sol b/contracts/BosonTokenDeposit.sol index de4f15ae..f1906819 100644 --- a/contracts/BosonTokenDeposit.sol +++ b/contracts/BosonTokenDeposit.sol @@ -1,5 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity >=0.6.6 <0.7.0; + import "./ERC20WithPermit.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; @@ -10,14 +11,13 @@ so that we have 2 distinguished contracts concerning tokens for the price of the Will not be used while deploying on prod. */ contract BosonTokenDeposit is ERC20WithPermit, AccessControl, Ownable { - bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); constructor(string memory name, string memory symbol) - ERC20WithPermit(name, symbol) - public + public + ERC20WithPermit(name, symbol) { _setupRole(MINTER_ROLE, owner()); _setupRole(ADMIN_ROLE, owner()); @@ -29,7 +29,8 @@ contract BosonTokenDeposit is ERC20WithPermit, AccessControl, Ownable { } function mint(address to, uint256 amount) public { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint"); + require(hasRole(MINTER_ROLE, _msgSender()), + "ERC20PresetMinterPauser: must have minter role to mint"); _mint(to, amount); } } \ No newline at end of file diff --git a/contracts/BosonTokenPrice.sol b/contracts/BosonTokenPrice.sol index 102aff49..62bd7361 100644 --- a/contracts/BosonTokenPrice.sol +++ b/contracts/BosonTokenPrice.sol @@ -1,18 +1,18 @@ // SPDX-License-Identifier: LGPL-3.0-or-later pragma solidity >=0.6.6 <0.7.0; + import "./ERC20WithPermit.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; contract BosonTokenPrice is ERC20WithPermit, AccessControl, Ownable { - bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); constructor(string memory name, string memory symbol) - ERC20WithPermit(name, symbol) - public + public + ERC20WithPermit(name, symbol) { _setupRole(MINTER_ROLE, owner()); _setupRole(ADMIN_ROLE, owner()); @@ -24,7 +24,8 @@ contract BosonTokenPrice is ERC20WithPermit, AccessControl, Ownable { } function mint(address to, uint256 amount) public { - require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint"); + require(hasRole(MINTER_ROLE, _msgSender()), + "ERC20PresetMinterPauser: must have minter role to mint"); _mint(to, amount); } } \ No newline at end of file diff --git a/contracts/Cashier.sol b/contracts/Cashier.sol index 49ce67e2..e2221059 100644 --- a/contracts/Cashier.sol +++ b/contracts/Cashier.sol @@ -7,7 +7,7 @@ import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Pausable.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "./IVoucherKernel.sol"; -import "./usingHelpers.sol"; +import "./UsingHelpers.sol"; import "./IERC20WithPermit.sol"; import "./IFundLimitsOracle.sol"; import "./ICashier.sol"; @@ -17,7 +17,7 @@ import "./ICashier.sol"; * @dev Warning: the contract hasn't been audited yet! * Roughly following OpenZeppelin's Escrow at https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/payment/ */ -contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { +contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { using Address for address payable; using SafeMath for uint; @@ -136,7 +136,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 _depositBu = metadata[4]; uint256 _quantity = metadata[5]; */ - function requestCreateOrder_ETH_ETH(uint256[] calldata metadata) + function requestCreateOrderETHETH(uint256[] calldata metadata) external payable override @@ -149,7 +149,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, ETH_ETH, address(0), address(0)); + IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, ETHETH, address(0), address(0)); //checks //(i) this is for separate promise allocation, not in prototype @@ -161,10 +161,10 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { //record funds in escrow ... escrow[msg.sender] += msg.value; - emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], ETH_ETH); + emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], ETHETH); } - function requestCreateOrder_TKN_TKN_WithPermit( + function requestCreateOrderTKNTKNWithPermit( address _tokenPriceAddress, address _tokenDepositAddress, uint256 _tokensSent, @@ -174,9 +174,9 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { bytes32 s, uint256[] calldata metadata ) + external notZeroAddress(_tokenPriceAddress) notZeroAddress(_tokenDepositAddress) - external payable override whenNotPaused @@ -191,14 +191,14 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, TKN_TKN, _tokenPriceAddress, _tokenDepositAddress); + IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, TKNTKN, _tokenPriceAddress, _tokenDepositAddress); IERC20WithPermit(_tokenDepositAddress).transferFrom(msg.sender, address(this), _tokensSent); - emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], TKN_TKN); + emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], TKNTKN); } - function requestCreateOrder_ETH_TKN_WithPermit( + function requestCreateOrderETHTKNWithPermit( address _tokenDepositAddress, uint256 _tokensSent, uint256 deadline, @@ -207,8 +207,8 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { bytes32 s, uint256[] calldata metadata ) - notZeroAddress(_tokenDepositAddress) external + notZeroAddress(_tokenDepositAddress) payable override whenNotPaused @@ -223,19 +223,19 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, ETH_TKN, address(0), _tokenDepositAddress); + IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, ETHTKN, address(0), _tokenDepositAddress); IERC20WithPermit(_tokenDepositAddress).transferFrom(msg.sender, address(this), _tokensSent); - emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], ETH_TKN); + emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], ETHTKN); } - function requestCreateOrder_TKN_ETH( + function requestCreateOrderTKNETH( address _tokenPriceAddress, uint256[] calldata metadata ) - notZeroAddress(_tokenPriceAddress) external + notZeroAddress(_tokenPriceAddress) payable override whenNotPaused @@ -247,11 +247,11 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { require(metadata[3].mul(metadata[5]) == msg.value, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, TKN_ETH, _tokenPriceAddress, address(0)); + IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, TKNETH, _tokenPriceAddress, address(0)); escrow[msg.sender] += msg.value; - emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], TKN_ETH); + emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], TKNETH); } /** @@ -259,7 +259,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { * @param _tokenIdSupply ID of the supply token * @param _issuer Address of the issuer of the supply token */ - function requestVoucher_ETH_ETH(uint256 _tokenIdSupply, address _issuer) + function requestVoucherETHETH(uint256 _tokenIdSupply, address _issuer) external payable override @@ -269,7 +269,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 weiReceived = msg.value; //checks - (uint256 price, uint256 depositSe, uint256 depositBu) = IVoucherKernel(voucherKernel).getOrderCosts(_tokenIdSupply); + (uint256 price, , uint256 depositBu) = IVoucherKernel(voucherKernel).getOrderCosts(_tokenIdSupply); require(price.add(depositBu) == weiReceived, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) IVoucherKernel(voucherKernel).fillOrder(_tokenIdSupply, _issuer, msg.sender); @@ -278,7 +278,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { escrow[msg.sender] += weiReceived; } - function requestVoucher_TKN_TKN_WithPermit( + function requestVoucherTKNTKNWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, @@ -309,7 +309,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { IERC20WithPermit(tokenDepositAddress).transferFrom(msg.sender, address(this), depositBu); } - function requestVoucher_TKN_TKN_Same_WithPermit( + function requestVoucherTKNTKNSameWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, @@ -339,7 +339,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { IERC20WithPermit(tokenPriceAddress).transferFrom(msg.sender, address(this), _tokensSent); } - function requestVoucher_ETH_TKN_WithPermit( + function requestVoucherETHTKNWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensDeposit, @@ -369,7 +369,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { escrow[msg.sender] += msg.value; } - function requestVoucher_TKN_ETH_WithPermit( + function requestVoucherTKNETHWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensPrice, @@ -448,7 +448,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { //process the RELEASE OF DEPOSITS - only when vouchers are in the FINAL status if (!voucherDetails.currStatus.isDepositsReleased && - isStatus(voucherDetails.currStatus.status, idxFinal)) + isStatus(voucherDetails.currStatus.status, IDX_FINAL)) { releaseDeposits(voucherDetails); } @@ -516,7 +516,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { //process the RELEASE OF DEPOSITS - only when vouchers are in the FINAL status if (!voucherDetails.currStatus.isDepositsReleased && - isStatus(voucherDetails.currStatus.status, idxFinal)) + isStatus(voucherDetails.currStatus.status, IDX_FINAL)) { releaseDeposits(voucherDetails); } @@ -540,12 +540,12 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function releasePayments(VoucherDetails memory voucherDetails) internal { - if (isStatus(voucherDetails.currStatus.status, idxRedeem)) { + if (isStatus(voucherDetails.currStatus.status, IDX_REDEEM)) { releasePaymentToSeller(voucherDetails); - } else if (isStatus(voucherDetails.currStatus.status, idxRefund) - || isStatus(voucherDetails.currStatus.status, idxExpire) - || (isStatus(voucherDetails.currStatus.status, idxCancelFault) - && !isStatus(voucherDetails.currStatus.status, idxRedeem))) + } else if (isStatus(voucherDetails.currStatus.status, IDX_REFUND) + || isStatus(voucherDetails.currStatus.status, IDX_EXPIRE) + || (isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT) + && !isStatus(voucherDetails.currStatus.status, IDX_REDEEM))) { releasePaymentToBuyer(voucherDetails); } @@ -553,13 +553,13 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function releasePaymentToSeller(VoucherDetails memory voucherDetails) internal { - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == ETH_TKN) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == ETHTKN) { escrow[voucherDetails.holder] -= voucherDetails.price; voucherDetails.amount2issuer += voucherDetails.price; } // TODO Chris - Can we have the same approach as above, first collect all amounts in one variable and do the payout at the end? So we save gas from multiple transfers - if(voucherDetails.paymentMethod == TKN_ETH || voucherDetails.paymentMethod == TKN_TKN) { + if(voucherDetails.paymentMethod == TKNETH || voucherDetails.paymentMethod == TKNTKN) { address addressTokenPrice = IVoucherKernel(voucherKernel).getVoucherPriceToken(voucherDetails.tokenIdSupply); IERC20WithPermit(addressTokenPrice).transfer(voucherDetails.issuer, voucherDetails.price); } @@ -576,12 +576,12 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function releasePaymentToBuyer(VoucherDetails memory voucherDetails) internal { - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == ETH_TKN) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == ETHTKN) { escrow[voucherDetails.holder] -= voucherDetails.price; voucherDetails.amount2holder += voucherDetails.price; } - if(voucherDetails.paymentMethod == TKN_ETH || voucherDetails.paymentMethod == TKN_TKN) { + if(voucherDetails.paymentMethod == TKNETH || voucherDetails.paymentMethod == TKNTKN) { address addressTokenPrice = IVoucherKernel(voucherKernel).getVoucherPriceToken(voucherDetails.tokenIdSupply); IERC20WithPermit(addressTokenPrice).transfer(voucherDetails.holder, voucherDetails.price); @@ -600,11 +600,11 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function releaseDeposits(VoucherDetails memory voucherDetails) internal { //first, depositSe - if (isStatus(voucherDetails.currStatus.status, idxComplain)) { + if (isStatus(voucherDetails.currStatus.status, IDX_COMPLAIN)) { //slash depositSe distributeIssuerDepositOnHolderComplain(voucherDetails); } else { - if (isStatus(voucherDetails.currStatus.status, idxCancelFault)) { + if (isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT)) { //slash depositSe distributeIssuerDepositOnIssuerCancel(voucherDetails); } else { @@ -614,8 +614,8 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { } //second, depositBu - if (isStatus(voucherDetails.currStatus.status, idxRedeem) || - isStatus(voucherDetails.currStatus.status, idxCancelFault) + if (isStatus(voucherDetails.currStatus.status, IDX_REDEEM) || + isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT) ) { //release depositBu distributeFullHolderDeposit(voucherDetails); @@ -632,9 +632,9 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 tFraction; - if (isStatus(voucherDetails.currStatus.status, idxCancelFault)) { + if (isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT)) { //appease the conflict three-ways - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == TKN_ETH) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; tFraction = voucherDetails.depositSe.div(CANCELFAULT_SPLIT); voucherDetails.amount2holder += tFraction; //Bu gets, say, a half @@ -642,7 +642,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { voucherDetails.amount2pool += voucherDetails.depositSe - tFraction - tFraction.div(CANCELFAULT_SPLIT); //slashing the rest } - if(voucherDetails.paymentMethod == ETH_TKN || voucherDetails.paymentMethod == TKN_TKN) { + if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); tFraction = voucherDetails.depositSe.div(CANCELFAULT_SPLIT); @@ -660,7 +660,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { } else { //slash depositSe - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == TKN_ETH) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; voucherDetails.amount2pool += voucherDetails.depositSe; } else { @@ -674,13 +674,13 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function distributeIssuerDepositOnIssuerCancel(VoucherDetails memory voucherDetails) internal { - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == TKN_ETH) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; voucherDetails.amount2issuer += voucherDetails.depositSe.div(CANCELFAULT_SPLIT); voucherDetails.amount2holder += voucherDetails.depositSe - voucherDetails.depositSe.div(CANCELFAULT_SPLIT); } - if (voucherDetails.paymentMethod == ETH_TKN || voucherDetails.paymentMethod == TKN_TKN) { + if (voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.issuer, voucherDetails.depositSe.div(CANCELFAULT_SPLIT)); @@ -704,12 +704,12 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function distributeFullIssuerDeposit(VoucherDetails memory voucherDetails) internal { - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == TKN_ETH) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; voucherDetails.amount2issuer += voucherDetails.depositSe; } - if(voucherDetails.paymentMethod == ETH_TKN || voucherDetails.paymentMethod == TKN_TKN) { + if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.issuer, voucherDetails.depositSe); } @@ -724,12 +724,12 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function distributeFullHolderDeposit(VoucherDetails memory voucherDetails) internal { - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == TKN_ETH) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { escrow[voucherDetails.holder] -= voucherDetails.depositBu; voucherDetails.amount2holder += voucherDetails.depositBu; } - if(voucherDetails.paymentMethod == ETH_TKN || voucherDetails.paymentMethod == TKN_TKN) { + if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.holder, voucherDetails.depositBu); } @@ -744,12 +744,12 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { function distributeHolderDepositOnNotRedeemedNotCancelled(VoucherDetails memory voucherDetails) internal { - if(voucherDetails.paymentMethod == ETH_ETH || voucherDetails.paymentMethod == TKN_ETH) { + if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { escrow[voucherDetails.holder] -= voucherDetails.depositBu; voucherDetails.amount2pool += voucherDetails.depositBu; } - if(voucherDetails.paymentMethod == ETH_TKN || voucherDetails.paymentMethod == TKN_TKN) { + if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); IERC20WithPermit(addressTokenDeposits).transfer(owner(), voucherDetails.depositBu); } @@ -790,13 +790,13 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { require(paymentMethod > 0 && paymentMethod <= 4, "INVALID PAYMENT METHOD"); - if(paymentMethod == ETH_ETH || paymentMethod == TKN_ETH) + if(paymentMethod == ETHETH || paymentMethod == TKNETH) { escrow[msg.sender] = escrow[msg.sender].sub(depositAmount); _withdrawDeposits(seller, depositAmount); } - if(paymentMethod == ETH_TKN || paymentMethod == TKN_TKN) + if(paymentMethod == ETHTKN || paymentMethod == TKNTKN) { address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(_tokenIdSupply); IERC20WithPermit(addressTokenDeposits).transfer(seller, depositAmount); @@ -869,19 +869,19 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { (uint256 price, uint256 depositBu) = IVoucherKernel(voucherKernel).getBuyerOrderCosts(tokenSupplyId); - if(paymentType == ETH_ETH) + if(paymentType == ETHETH) { uint256 totalAmount = price.add(depositBu); escrow[_from] = escrow[_from].sub(totalAmount); escrow[_to] = escrow[_to].add(totalAmount); } - if(paymentType == ETH_TKN) { + if(paymentType == ETHTKN) { escrow[_from] = escrow[_from].sub(price); escrow[_to] = escrow[_to].add(price); } - if(paymentType == TKN_ETH) { + if(paymentType == TKNETH) { escrow[_from] = escrow[_from].sub(depositBu); escrow[_to] = escrow[_to].add(depositBu); } @@ -918,7 +918,7 @@ contract Cashier is ICashier, usingHelpers, ReentrancyGuard, Ownable, Pausable { { uint8 paymentType = IVoucherKernel(voucherKernel).getVoucherPaymentMethod(_tokenSupplyId); - if(paymentType == ETH_ETH || paymentType == TKN_ETH) { + if(paymentType == ETHETH || paymentType == TKNETH) { uint256 depositSe = IVoucherKernel(voucherKernel).getSellerDeposit(_tokenSupplyId); uint256 totalAmount = depositSe.mul(_value); diff --git a/contracts/ERC20WithPermit.sol b/contracts/ERC20WithPermit.sol index 3c3e9bf2..e3736398 100644 --- a/contracts/ERC20WithPermit.sol +++ b/contracts/ERC20WithPermit.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -pragma solidity >=0.6.6; +pragma solidity >=0.6.6 <0.7.0; import "./IERC20WithPermit.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; @@ -9,14 +9,18 @@ contract ERC20WithPermit is IERC20WithPermit { string public override name; string public override symbol; + // solhint-disable-next-line const-name-snakecase uint8 public constant override decimals = 18; uint256 public override totalSupply; mapping(address => uint256) public override balanceOf; mapping(address => mapping(address => uint256)) public override allowance; - bytes32 public override DOMAIN_SEPARATOR; //prevents collision of identical structures. Formed in the initialization of the contract - bytes32 public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; //representation of keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + // prevents collision of identical structures. Formed in the initialization of the contract + // solhint-disable-next-line var-name-mixedcase + bytes32 public override DOMAIN_SEPARATOR; + // representation of keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); + bytes32 public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint256) public override nonces; event Approval( diff --git a/contracts/ICashier.sol b/contracts/ICashier.sol index 9f6c4880..e7b8d3b2 100644 --- a/contracts/ICashier.sol +++ b/contracts/ICashier.sol @@ -32,11 +32,11 @@ interface ICashier { uint256 _depositBu = metadata[4]; uint256 _quantity = metadata[5]; */ - function requestCreateOrder_ETH_ETH(uint256[] calldata metadata) + function requestCreateOrderETHETH(uint256[] calldata metadata) external payable; - function requestCreateOrder_TKN_TKN_WithPermit( + function requestCreateOrderTKNTKNWithPermit( address _tokenPriceAddress, address _tokenDepositAddress, uint256 _tokensSent, @@ -49,7 +49,7 @@ interface ICashier { external payable; - function requestCreateOrder_ETH_TKN_WithPermit( + function requestCreateOrderETHTKNWithPermit( address _tokenDepositAddress, uint256 _tokensSent, uint256 deadline, @@ -61,7 +61,7 @@ interface ICashier { external payable; - function requestCreateOrder_TKN_ETH( + function requestCreateOrderTKNETH( address _tokenPriceAddress, uint256[] calldata metadata ) @@ -73,11 +73,11 @@ interface ICashier { * @param _tokenIdSupply ID of the supply token * @param _issuer Address of the issuer of the supply token */ - function requestVoucher_ETH_ETH(uint256 _tokenIdSupply, address _issuer) + function requestVoucherETHETH(uint256 _tokenIdSupply, address _issuer) external payable; - function requestVoucher_TKN_TKN_WithPermit( + function requestVoucherTKNTKNWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, @@ -88,7 +88,7 @@ interface ICashier { external payable; - function requestVoucher_TKN_TKN_Same_WithPermit( + function requestVoucherTKNTKNSameWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, @@ -98,7 +98,7 @@ interface ICashier { external; - function requestVoucher_ETH_TKN_WithPermit( + function requestVoucherETHTKNWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensDeposit, @@ -108,7 +108,7 @@ interface ICashier { external payable; - function requestVoucher_TKN_ETH_WithPermit( + function requestVoucherTKNETHWithPermit( uint256 _tokenIdSupply, address _issuer, uint256 _tokensPrice, diff --git a/contracts/IERC1155.sol b/contracts/IERC1155.sol index 2629dd4d..dc516d13 100644 --- a/contracts/IERC1155.sol +++ b/contracts/IERC1155.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -pragma solidity >=0.6.0 <0.7.0; +pragma solidity >=0.6.6 <0.7.0; /** @title ERC-1155 Multi Token Standard diff --git a/contracts/IERC20WithPermit.sol b/contracts/IERC20WithPermit.sol index 65fbe59d..0a36c599 100644 --- a/contracts/IERC20WithPermit.sol +++ b/contracts/IERC20WithPermit.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: LGPL-3.0-or-later -pragma solidity >=0.6.0 <0.7.0; +pragma solidity >=0.6.6 <0.7.0; interface IERC20WithPermit { event Approval( @@ -34,8 +34,10 @@ interface IERC20WithPermit { uint256 value ) external returns (bool); + // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); + // solhint-disable-next-line func-name-mixedcase function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); diff --git a/contracts/IVoucherKernel.sol b/contracts/IVoucherKernel.sol index cca1bb47..7c957e73 100644 --- a/contracts/IVoucherKernel.sol +++ b/contracts/IVoucherKernel.sol @@ -31,7 +31,7 @@ interface IVoucherKernel { /** * @notice Creates a Payment method struct recording the details on how the seller requires to receive Price and Deposits for a certain Voucher Set. * @param _tokenIdSupply _tokenIdSupply of the voucher set this is related to - * @param _paymentMethod might be ETH_ETH, ETH_TKN, TKN_ETH or TKN_TKN + * @param _paymentMethod might be ETHETH, ETHTKN, TKNETH or TKNTKN * @param _tokenPrice token address which will hold the funds for the price of the voucher * @param _tokenDeposits token address which will hold the funds for the deposits of the voucher */ diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol index 7e6dfe8c..2939c65f 100644 --- a/contracts/Migrations.sol +++ b/contracts/Migrations.sol @@ -4,7 +4,7 @@ pragma solidity >=0.6.6 <0.7.0; contract Migrations { address public owner; - uint public last_completed_migration; + uint public lastCompletedMigration; constructor() public { owner = msg.sender; @@ -15,11 +15,11 @@ contract Migrations { } function setCompleted(uint completed) public restricted { - last_completed_migration = completed; + lastCompletedMigration = completed; } - function upgrade(address new_address) public restricted { - Migrations upgraded = Migrations(new_address); - upgraded.setCompleted(last_completed_migration); + function upgrade(address newAddress) public restricted { + Migrations upgraded = Migrations(newAddress); + upgraded.setCompleted(lastCompletedMigration); } } diff --git a/contracts/usingHelpers.sol b/contracts/UsingHelpers.sol similarity index 66% rename from contracts/usingHelpers.sol rename to contracts/UsingHelpers.sol index 04f3619f..b2fac9e7 100644 --- a/contracts/usingHelpers.sol +++ b/contracts/UsingHelpers.sol @@ -5,15 +5,15 @@ pragma solidity >=0.6.6 <0.7.0; /** * @title Utility contract to enable access to common structures */ -contract usingHelpers { +contract UsingHelpers { uint8 internal constant ONE = 1; - uint8 internal constant idxCommit = 7; - uint8 internal constant idxRedeem = 6; - uint8 internal constant idxRefund = 5; - uint8 internal constant idxExpire = 4; - uint8 internal constant idxComplain = 3; - uint8 internal constant idxCancelFault = 2; - uint8 internal constant idxFinal = 1; + uint8 internal constant IDX_COMMIT = 7; + uint8 internal constant IDX_REDEEM = 6; + uint8 internal constant IDX_REFUND = 5; + uint8 internal constant IDX_EXPIRE = 4; + uint8 internal constant IDX_COMPLAIN = 3; + uint8 internal constant IDX_CANCEL_FAULT = 2; + uint8 internal constant IDX_FINAL = 1; /* Status of the voucher in 8 bits: [7:COMMITTED] [6:REDEEMED] [5:REFUNDED] [4:EXPIRED] [3:COMPLAINED] [2:CANCELORFAULT] [1:FINAL] [1:/] @@ -21,10 +21,10 @@ contract usingHelpers { // Those are the payment methods we are using throughout the system. // Depending on how to user choose to interact with it's funds we store the method, so we could distribute its tokens afterwise - uint8 internal constant ETH_ETH = 1; - uint8 internal constant ETH_TKN = 2; - uint8 internal constant TKN_ETH = 3; - uint8 internal constant TKN_TKN = 4; + uint8 internal constant ETHETH = 1; + uint8 internal constant ETHTKN = 2; + uint8 internal constant TKNETH = 3; + uint8 internal constant TKNTKN = 4; struct VoucherStatus { uint8 status; @@ -39,7 +39,7 @@ contract usingHelpers { internal pure returns (bool) { - return _status == setChange(0, idxCommit); + return _status == setChange(0, IDX_COMMIT); } @@ -47,7 +47,7 @@ contract usingHelpers { internal pure returns (bool) { - return _status == setChange(setChange(0, idxCommit), idxRedeem); + return _status == setChange(setChange(0, IDX_COMMIT), IDX_REDEEM); } @@ -55,7 +55,7 @@ contract usingHelpers { internal pure returns (bool) { - return _status == setChange(setChange(0, idxCommit), idxRefund); + return _status == setChange(setChange(0, IDX_COMMIT), IDX_REFUND); } @@ -63,7 +63,7 @@ contract usingHelpers { internal pure returns (bool) { - return _status == setChange(setChange(0, idxCommit), idxExpire); + return _status == setChange(setChange(0, IDX_COMMIT), IDX_EXPIRE); } diff --git a/contracts/VoucherKernel.sol b/contracts/VoucherKernel.sol index 536c58e9..7aa64996 100644 --- a/contracts/VoucherKernel.sol +++ b/contracts/VoucherKernel.sol @@ -12,7 +12,7 @@ import "./IERC721.sol"; import "./IERC1155ERC721.sol"; import "./IERC721TokenReceiver.sol"; import "./IVoucherKernel.sol"; -import "./usingHelpers.sol"; +import "./UsingHelpers.sol"; //preparing for ERC-1066, ERC-1444, EIP-838 @@ -24,7 +24,7 @@ import "./usingHelpers.sol"; * - The usage of block.timestamp is honored since vouchers are defined with day-precision and the demo app is not covering all edge cases. * See: https://ethereum.stackexchange.com/questions/5924/how-do-ethereum-mining-nodes-maintain-a-time-consistent-with-the-network/5931#5931 */ -contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { +contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { using Address for address; using SafeMath for uint; //using Counters for Counters.Counter; @@ -263,7 +263,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { /** * @notice Creates a Payment method struct recording the details on how the seller requires to receive Price and Deposits for a certain Voucher Set. * @param _tokenIdSupply _tokenIdSupply of the voucher set this is related to - * @param _paymentMethod might be ETH_ETH, ETH_TKN, TKN_ETH or TKN_TKN + * @param _paymentMethod might be ETHETH, ETHTKN, TKNETH or TKNTKN * @param _tokenPrice token address which will hold the funds for the price of the voucher * @param _tokenDeposits token address which will hold the funds for the deposits of the voucher */ @@ -382,7 +382,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { uint256 voucherTokenId = _tokenIdSupply | ++typeCounters[_tokenIdSupply]; //set status - vouchersStatus[voucherTokenId].status = setChange(vouchersStatus[voucherTokenId].status, idxCommit); + vouchersStatus[voucherTokenId].status = setChange(vouchersStatus[voucherTokenId].status, IDX_COMMIT); vouchersStatus[voucherTokenId].isPaymentReleased = false; vouchersStatus[voucherTokenId].isDepositsReleased = false; @@ -455,7 +455,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { //check collection code and/or assign collector vouchersStatus[_tokenIdVoucher].complainPeriodStart = block.timestamp; - vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, idxRedeem); + vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, IDX_REDEEM); emit LogVoucherRedeemed(_tokenIdVoucher, msg.sender, tPromise.promiseId); } @@ -481,7 +481,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { isInValidityPeriod(_tokenIdVoucher); vouchersStatus[_tokenIdVoucher].complainPeriodStart = block.timestamp; - vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, idxRefund); + vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, IDX_REFUND); emit LogVoucherRefunded(_tokenIdVoucher); } @@ -497,8 +497,8 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { whenNotPaused onlyVoucherOwner(_tokenIdVoucher) { - require(!isStatus(vouchersStatus[_tokenIdVoucher].status, idxComplain), "ALREADY_COMPLAINED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) - require(!isStatus(vouchersStatus[_tokenIdVoucher].status, idxFinal), "ALREADY_FINALIZED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) + require(!isStatus(vouchersStatus[_tokenIdVoucher].status, IDX_COMPLAIN), "ALREADY_COMPLAINED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) + require(!isStatus(vouchersStatus[_tokenIdVoucher].status, IDX_FINAL), "ALREADY_FINALIZED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) //check if still in the complain period Promise memory tPromise = promises[getPromiseIdFromVoucherId(_tokenIdVoucher)]; @@ -506,35 +506,35 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { //if redeemed or refunded if (isStateRedemptionSigned(vouchersStatus[_tokenIdVoucher].status) || isStateRefunded(vouchersStatus[_tokenIdVoucher].status)) { - if (!isStatus(vouchersStatus[_tokenIdVoucher].status, idxCancelFault)) { + if (!isStatus(vouchersStatus[_tokenIdVoucher].status, IDX_CANCEL_FAULT)) { require(block.timestamp <= vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod + cancelFaultPeriod, "COMPLAINPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) } else { require(block.timestamp <= vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod, "COMPLAINPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) } vouchersStatus[_tokenIdVoucher].cancelFaultPeriodStart = block.timestamp; - vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, idxComplain); + vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, IDX_COMPLAIN); emit LogVoucherComplain(_tokenIdVoucher); //if expired } else if (isStateExpired(vouchersStatus[_tokenIdVoucher].status)) { - if (!isStatus(vouchersStatus[_tokenIdVoucher].status, idxCancelFault)) { + if (!isStatus(vouchersStatus[_tokenIdVoucher].status, IDX_CANCEL_FAULT)) { require(block.timestamp <= tPromise.validTo + complainPeriod + cancelFaultPeriod, "COMPLAINPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) } else { require(block.timestamp <= tPromise.validTo + complainPeriod, "COMPLAINPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) } vouchersStatus[_tokenIdVoucher].cancelFaultPeriodStart = block.timestamp; - vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, idxComplain); + vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, IDX_COMPLAIN); emit LogVoucherComplain(_tokenIdVoucher); //if cancelOrFault - } else if (isStatus(vouchersStatus[_tokenIdVoucher].status, idxCancelFault)) { + } else if (isStatus(vouchersStatus[_tokenIdVoucher].status, IDX_CANCEL_FAULT)) { require(block.timestamp <= vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod, "COMPLAINPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired)); - vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, idxComplain); + vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, IDX_COMPLAIN); emit LogVoucherComplain(_tokenIdVoucher); @@ -559,14 +559,14 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { uint8 tStatus = vouchersStatus[_tokenIdVoucher].status; - require(!isStatus(tStatus, idxCancelFault), "ALREADY_CANCELFAULT"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) - require(!isStatus(tStatus, idxFinal), "ALREADY_FINALIZED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) + require(!isStatus(tStatus, IDX_CANCEL_FAULT), "ALREADY_CANCELFAULT"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) + require(!isStatus(tStatus, IDX_FINAL), "ALREADY_FINALIZED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) Promise memory tPromise = promises[getPromiseIdFromVoucherId(_tokenIdVoucher)]; - if (isStatus(tStatus, idxRedeem) || isStatus(tStatus, idxRefund)) { + if (isStatus(tStatus, IDX_REDEEM) || isStatus(tStatus, IDX_REFUND)) { //if redeemed or refunded - if (!isStatus(tStatus, idxComplain)) { + if (!isStatus(tStatus, IDX_COMPLAIN)) { require(block.timestamp <= vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod + cancelFaultPeriod, "COFPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) vouchersStatus[_tokenIdVoucher].complainPeriodStart = block.timestamp; //resetting the complain period @@ -574,9 +574,9 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { require(block.timestamp <= vouchersStatus[_tokenIdVoucher].cancelFaultPeriodStart + cancelFaultPeriod, "COFPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) } - } else if (isStatus(tStatus, idxExpire)) { + } else if (isStatus(tStatus, IDX_EXPIRE)) { //if expired - if (!isStatus(tStatus, idxComplain)) { + if (!isStatus(tStatus, IDX_COMPLAIN)) { require(block.timestamp <= tPromise.validTo + complainPeriod + cancelFaultPeriod, "COFPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) } else { require(block.timestamp <= vouchersStatus[_tokenIdVoucher].cancelFaultPeriodStart + cancelFaultPeriod, "COFPERIOD_EXPIRED"); //hex"46" FISSION.code(FISSION.Category.Availability, FISSION.Status.Expired) @@ -590,7 +590,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { revert("INAPPLICABLE_STATUS"); //hex"18" FISSION.code(FISSION.Category.Permission, FISSION.Status.NotApplicableToCurrentState) } - vouchersStatus[_tokenIdVoucher].status = setChange(tStatus, idxCancelFault); + vouchersStatus[_tokenIdVoucher].status = setChange(tStatus, IDX_CANCEL_FAULT); emit LogVoucherFaultCancel(_tokenIdVoucher); @@ -650,7 +650,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { if (tPromise.validTo < block.timestamp && isStateCommitted(vouchersStatus[_tokenIdVoucher].status) ) { - vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, idxExpire); + vouchersStatus[_tokenIdVoucher].status = setChange(vouchersStatus[_tokenIdVoucher].status, IDX_EXPIRE); emit LogExpirationTriggered(_tokenIdVoucher, msg.sender); } @@ -670,13 +670,13 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { uint8 tStatus = vouchersStatus[_tokenIdVoucher].status; - require(!isStatus(tStatus, idxFinal), "ALREADY_FINALIZED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) + require(!isStatus(tStatus, IDX_FINAL), "ALREADY_FINALIZED"); //hex"48" FISSION.code(FISSION.Category.Availability, FISSION.Status.AlreadyDone) bool mark; Promise memory tPromise = promises[getPromiseIdFromVoucherId(_tokenIdVoucher)]; - if (isStatus(tStatus, idxComplain)) { - if (isStatus(tStatus, idxCancelFault)) { + if (isStatus(tStatus, IDX_COMPLAIN)) { + if (isStatus(tStatus, IDX_CANCEL_FAULT)) { //if COMPLAIN && COF: then final mark = true; @@ -685,7 +685,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { mark = true; } - } else if (isStatus(tStatus, idxCancelFault) && + } else if (isStatus(tStatus, IDX_CANCEL_FAULT) && block.timestamp >= vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod ) { //if COF: then final after complain period @@ -706,7 +706,7 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, usingHelpers { } if (mark) { - vouchersStatus[_tokenIdVoucher].status = setChange(tStatus, idxFinal); + vouchersStatus[_tokenIdVoucher].status = setChange(tStatus, IDX_FINAL); emit LogFinalizeVoucher(_tokenIdVoucher, msg.sender); } // diff --git a/doc_contracts.md b/doc_contracts.md index b9a6a61a..3dacc014 100644 --- a/doc_contracts.md +++ b/doc_contracts.md @@ -10,12 +10,12 @@ Main contracts: * Cashier: funds-related functions * ERC1155ERC721: token factory * VoucherKernel: main business logic -* usingHelpers: common utils as structures +* UsingHelpers: common utils as structures Supported currencies are currently ETH and BSN tokens therefore functions -dealing with funds have appendices such as ETH_ETH or ETH_TKN to denote the +dealing with funds have appendices such as ETHETH or ETHTKN to denote the currencies used in that particular function (e.g. -`function requestCreateOrder_ETH_ETH(uint256[] calldata metadata)`). +`function requestCreateOrderETHETH(uint256[] calldata metadata)`). ## Transactions flow @@ -26,7 +26,7 @@ below. Voucher's status is defined in 7 bits that are set depending on the path in its lifecycle (defined in -[usingHelpers.sol](https://github.com/bosonprotocol/bsn-core-prototype/blob/master/contracts/usingHelpers.sol#L29)): +[UsingHelpers.sol](https://github.com/bosonprotocol/bsn-core-prototype/blob/master/contracts/UsingHelpers.sol#L29)): 7:COMMITTED 6:REDEEMED diff --git a/package-lock.json b/package-lock.json index 345f8853..b3a85f60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,14 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "requires": { + "@babel/highlight": "^7.10.4" + } + }, "@babel/helper-module-imports": { "version": "7.12.5", "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.12.5.tgz", @@ -22,6 +30,67 @@ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.12.11.tgz", "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==" }, + "@babel/highlight": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", + "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", + "requires": { + "@babel/helper-validator-identifier": "^7.10.4", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "@babel/plugin-transform-runtime": { "version": "7.12.10", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.12.10.tgz", @@ -1675,6 +1744,16 @@ "negotiator": "0.6.2" } }, + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==" + }, "address": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", @@ -1707,6 +1786,11 @@ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==" }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -1720,6 +1804,11 @@ "color-convert": "^2.0.1" } }, + "antlr4": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/antlr4/-/antlr4-4.7.1.tgz", + "integrity": "sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ==" + }, "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -1786,6 +1875,16 @@ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" }, + "ast-parents": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/ast-parents/-/ast-parents-0.0.1.tgz", + "integrity": "sha1-UI/Q8F0MSHddnszaLhdEIyYejdM=" + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, "async": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", @@ -2156,6 +2255,27 @@ } } }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=" + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -2188,6 +2308,11 @@ "supports-color": "^7.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" + }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -2263,6 +2388,14 @@ "resolved": "https://registry.npmjs.org/class-is/-/class-is-1.1.0.tgz", "integrity": "sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==" }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "requires": { + "restore-cursor": "^2.0.0" + } + }, "cli-logger": { "version": "0.5.40", "resolved": "https://registry.npmjs.org/cli-logger/-/cli-logger-0.5.40.tgz", @@ -2285,6 +2418,11 @@ "cli-regexp": "~0.1.0" } }, + "cli-width": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" + }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", @@ -2423,6 +2561,17 @@ "vary": "^1" } }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, "create-ecdh": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", @@ -2473,6 +2622,33 @@ } } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", @@ -2707,6 +2883,14 @@ "path-type": "^4.0.0" } }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "requires": { + "esutils": "^2.0.2" + } + }, "dom-walk": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz", @@ -2794,6 +2978,14 @@ "prr": "~1.0.1" } }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, "es5-ext": { "version": "0.10.53", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", @@ -2861,11 +3053,224 @@ } } }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, + "esquery": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==" + } + } + }, "estraverse": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", @@ -3406,6 +3811,16 @@ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -3424,6 +3839,11 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==" + }, "fast-glob": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", @@ -3476,19 +3896,42 @@ "node-fetch": "~1.7.1" } }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "requires": { + "escape-string-regexp": "^1.0.5" + }, + "dependencies": { + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + } + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "requires": { + "flat-cache": "^2.0.1" + } + }, + "file-type": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", + "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=" + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "requires": { "to-regex-range": "^5.0.1" @@ -3522,6 +3965,21 @@ "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, "follow-redirects": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", @@ -4409,6 +4867,11 @@ } } }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, "globby": { "version": "10.0.2", "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz", @@ -4619,6 +5082,20 @@ "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4638,6 +5115,90 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" }, + "inquirer": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", + "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.12", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "interpret": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", @@ -4648,6 +5209,11 @@ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, "is-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", @@ -4656,6 +5222,11 @@ "binary-extensions": "^2.0.0" } }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=" + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -4753,6 +5324,11 @@ "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.5.7.tgz", "integrity": "sha1-DU/9gALVMzqrr0oj7tL2N0yfKOc=" }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, "js-yaml": { "version": "3.14.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", @@ -4772,6 +5348,11 @@ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=" }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==" + }, "json-rpc-engine": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-5.4.0.tgz", @@ -4804,6 +5385,11 @@ "jsonify": "~0.0.0" } }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -5183,6 +5769,11 @@ "mime-db": "1.44.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" + }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", @@ -5344,6 +5935,11 @@ } } }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + }, "nan": { "version": "2.14.2", "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", @@ -5359,6 +5955,11 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==" }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -5374,6 +5975,11 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=" }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==" + }, "node-addon-api": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", @@ -5474,6 +6080,14 @@ "wrappy": "1" } }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "requires": { + "mimic-fn": "^1.0.0" + } + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -5492,6 +6106,11 @@ "resolved": "https://registry.npmjs.org/original-require/-/original-require-1.0.1.tgz", "integrity": "sha1-DxMEcVhM0zURxew4yNWSE/msXiA=" }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, "p-cancelable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", @@ -5531,6 +6150,21 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "requires": { + "callsites": "^3.0.0" + }, + "dependencies": { + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + } + } + }, "parse-asn1": { "version": "5.1.6", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", @@ -5548,6 +6182,15 @@ "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.3.tgz", "integrity": "sha512-QhhZ+DCCit2Coi2vmAKbq5RGTRcQUOE2+REgv8vdyu7MnYx2eZztegqtTx99TZ86GTIwqiy3+4nQTWZ2tgmdCA==" }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -5563,6 +6206,16 @@ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -5638,6 +6291,12 @@ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "optional": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -5648,6 +6307,11 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, "promise-to-callback": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/promise-to-callback/-/promise-to-callback-1.0.0.tgz", @@ -5811,6 +6475,11 @@ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -5860,6 +6529,11 @@ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=" }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=" + }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -5868,11 +6542,28 @@ "lowercase-keys": "^1.0.0" } }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -5890,6 +6581,11 @@ "bn.js": "^4.11.1" } }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" + }, "run-parallel": { "version": "1.1.10", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.10.tgz", @@ -5900,6 +6596,14 @@ "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==" }, + "rxjs": { + "version": "6.6.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz", + "integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==", + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -6117,6 +6821,19 @@ "safe-buffer": "^5.0.1" } }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, "shelljs": { "version": "0.8.4", "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz", @@ -6127,6 +6844,11 @@ "rechoir": "^0.6.2" } }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, "simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -6147,6 +6869,127 @@ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + } + } + }, + "solhint": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/solhint/-/solhint-3.3.2.tgz", + "integrity": "sha512-8tHCkIAk1axLLG6Qu2WIH3GgNABonj9eAWejJbov3o3ujkZQRNHeHU1cC4/Dmjsh3Om7UzFFeADUHu2i7ZJeiw==", + "requires": { + "@solidity-parser/parser": "^0.8.2", + "ajv": "^6.6.1", + "antlr4": "4.7.1", + "ast-parents": "0.0.1", + "chalk": "^2.4.2", + "commander": "2.18.0", + "cosmiconfig": "^5.0.7", + "eslint": "^5.6.0", + "fast-diff": "^1.1.2", + "glob": "^7.1.3", + "ignore": "^4.0.6", + "js-yaml": "^3.12.0", + "lodash": "^4.17.11", + "prettier": "^1.14.3", + "semver": "^6.3.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "commander": { + "version": "2.18.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", + "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "solidity-coverage": { "version": "0.7.13", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.13.tgz", @@ -6443,6 +7286,42 @@ } } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "tar": { "version": "4.4.13", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", @@ -6481,6 +7360,11 @@ "xtend": "^4.0.0" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -6491,6 +7375,14 @@ "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=" }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", @@ -6671,6 +7563,11 @@ } } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", @@ -7302,6 +8199,24 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "requires": { + "mkdirp": "^0.5.1" + }, + "dependencies": { + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + } + } + }, "ws": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz", diff --git a/package.json b/package.json index afefce93..70176fbc 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,9 @@ "test": "test" }, "scripts": { - "compile": "truffle compile --all", + "contracts:compile": "truffle compile --all", + "contracts:lint": "solhint contracts/**/*.sol -w 27", + "contracts:lint-fix": "solhint contracts/**/*.sol -w 27 --fix", "test:integration": "truffle test --network test", "test:coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage", "migrate-dev": "truffle migrate --network=rinkeby", @@ -32,6 +34,7 @@ "ethereumjs-util": "^7.0.7", "ethers": "5.0.4", "mocha": "^8.2.1", + "solhint": "^3.3.2", "solidity-coverage": "^0.7.12", "truffle": "5.1.10", "truffle-assertions": "^0.9.2", diff --git a/test/1_test_fullpath.js b/test/1_test_fullpath.js index a2631f64..a663044e 100644 --- a/test/1_test_fullpath.js +++ b/test/1_test_fullpath.js @@ -74,7 +74,7 @@ contract("Voucher tests", async addresses => { describe('Orders (aka supply tokens - ERC1155)', () => { it("adding one new order / promise", async () => { const txOrder = await contractCashier - .requestCreateOrder_ETH_ETH([ + .requestCreateOrderETHETH([ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE1, @@ -112,7 +112,7 @@ contract("Voucher tests", async addresses => { it("adding second order", async () => { const txOrder = await contractCashier - .requestCreateOrder_ETH_ETH([ + .requestCreateOrderETHETH([ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE2, @@ -136,7 +136,7 @@ contract("Voucher tests", async addresses => { it("fill one order (aka buy a voucher)", async () => { const txFillOrder = await contractCashier - .requestVoucher_ETH_ETH( + .requestVoucherETHETH( tokenSupplyKey1, users.buyer.address, { from: users.buyer.address, @@ -161,7 +161,7 @@ contract("Voucher tests", async addresses => { it("fill second order (aka buy a voucher)", async () => { const txFillOrder = await contractCashier - .requestVoucher_ETH_ETH( + .requestVoucherETHETH( tokenSupplyKey2, users.buyer.address, { from: users.buyer.address, @@ -183,7 +183,7 @@ contract("Voucher tests", async addresses => { it("must fail: adding new order with incorrect value sent", async () => { await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_ETH([ + contractCashier.requestCreateOrderETHETH([ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE1, @@ -201,7 +201,7 @@ contract("Voucher tests", async addresses => { it("must fail: fill an order with incorrect value", async () => { await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_ETH( + contractCashier.requestVoucherETHETH( tokenSupplyKey1, users.buyer.address, { from: users.buyer.address, @@ -341,7 +341,7 @@ contract("Voucher tests - UNHAPPY PATH", async addresses => { contractCashier.address) const txOrder = await contractCashier - .requestCreateOrder_ETH_ETH([ + .requestCreateOrderETHETH([ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE1, @@ -363,7 +363,7 @@ contract("Voucher tests - UNHAPPY PATH", async addresses => { }, "order1 not created successfully") const txFillOrder = await contractCashier - .requestVoucher_ETH_ETH( + .requestVoucherETHETH( tokenSupplyKey1, users.seller.address, { diff --git a/test/2_test_fullpath_with_permit.js b/test/2_test_fullpath_with_permit.js index 9ef65bdc..62e01c6f 100644 --- a/test/2_test_fullpath_with_permit.js +++ b/test/2_test_fullpath_with_permit.js @@ -92,22 +92,22 @@ contract("Cashier && VK", async addresses => { let vouchersToBuy = 5 const paymentMethods = { - ETH_ETH: 1, - ETH_TKN: 2, - TKN_ETH: 3, - TKN_TKN: 4 + ETHETH: 1, + ETHTKN: 2, + TKNETH: 3, + TKNTKN: 4 } afterEach(() => { remQty = constants.QTY_10 }) - describe("ETH_ETH", () => { + describe("ETHETH", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -156,7 +156,7 @@ contract("Cashier && VK", async addresses => { } }) - it("Should create payment method ETH_ETH", async () => { + it("Should create payment method ETHETH", async () => { timestamp = await Utils.getCurrTimestamp() let tokenSupplyKey = await utils @@ -172,16 +172,16 @@ contract("Cashier && VK", async addresses => { assert.equal( paymentDetails.paymentMethod.toString(), - paymentMethods.ETH_ETH, - "Payment Method ETH_ETH not set correctly") + paymentMethods.ETHETH, + "Payment Method ETHETH not set correctly") assert.equal( paymentDetails.addressTokenPrice.toString(), constants.ZERO_ADDRESS, - "ETH_ETH Method Price Token Address mismatch") + "ETHETH Method Price Token Address mismatch") assert.equal( paymentDetails.addressTokenDeposits.toString(), constants.ZERO_ADDRESS, - "ETH_ETH Method Deposit Token Address mismatch") + "ETHETH Method Deposit Token Address mismatch") }) it("[NEGATIVE] Should fail if additional token address is provided", @@ -192,7 +192,7 @@ contract("Cashier && VK", async addresses => { timestamp = await Utils.getCurrTimestamp() await truffleAssert.fails( - contractCashier.requestCreateOrder_ETH_ETH( + contractCashier.requestCreateOrderETHETH( contractBSNTokenDeposit.address, [ timestamp, @@ -215,7 +215,7 @@ contract("Cashier && VK", async addresses => { new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_ETH( + contractCashier.requestCreateOrderETHETH( [ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, @@ -238,7 +238,7 @@ contract("Cashier && VK", async addresses => { new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_ETH( + contractCashier.requestCreateOrderETHETH( [ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, @@ -261,7 +261,7 @@ contract("Cashier && VK", async addresses => { new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_ETH( + contractCashier.requestCreateOrderETHETH( [ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, @@ -280,13 +280,13 @@ contract("Cashier && VK", async addresses => { }) describe("[WITH PERMIT]", () => { - describe("ETH_TKN", () => { + describe("ETHTKN", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -349,7 +349,7 @@ contract("Cashier && VK", async addresses => { } }) - it("Should create payment method ETH_TKN", async () => { + it("Should create payment method ETHTKN", async () => { tokenSupplyKey = await utils.createOrder( users.seller, timestamp, @@ -363,16 +363,16 @@ contract("Cashier && VK", async addresses => { assert.equal( paymentDetails.paymentMethod.toString(), - paymentMethods.ETH_TKN, - "Payment Method ETH_TKN not set correctly") + paymentMethods.ETHTKN, + "Payment Method ETHTKN not set correctly") assert.equal( paymentDetails.addressTokenPrice.toString(), constants.ZERO_ADDRESS, - "ETH_TKN Method Price Token Address mismatch") + "ETHTKN Method Price Token Address mismatch") assert.equal( paymentDetails.addressTokenDeposits.toString(), contractBSNTokenDeposit.address, - "ETH_TKN Method Deposit Token Address mismatch") + "ETHTKN Method Deposit Token Address mismatch") }) it("[NEGATIVE] Should fail if token deposit contract address is not provided", @@ -396,7 +396,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.fails( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractCashier.requestCreateOrderETHTKNWithPermit( '', txValue, deadline, @@ -436,7 +436,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractCashier.requestCreateOrderETHTKNWithPermit( constants.ZERO_ADDRESS, txValue, deadline, @@ -478,7 +478,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractCashier.requestCreateOrderETHTKNWithPermit( contractBSNTokenDeposit.address, txValue, deadline, @@ -520,7 +520,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractCashier.requestCreateOrderETHTKNWithPermit( contractBSNTokenDeposit.address, txValue, deadline, @@ -562,7 +562,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_ETH_TKN_WithPermit( + contractCashier.requestCreateOrderETHTKNWithPermit( contractBSNTokenDeposit.address, txValue, deadline, @@ -583,14 +583,14 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_ETH", () => { + describe("TKNETH", () => { before(async () => { await deployContracts() utils = UtilsBuilder .create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -648,7 +648,7 @@ contract("Cashier && VK", async addresses => { } }) - it("Should create payment method TKN_ETH", async () => { + it("Should create payment method TKNETH", async () => { tokenSupplyKey = await utils.createOrder( users.seller, timestamp, @@ -662,16 +662,16 @@ contract("Cashier && VK", async addresses => { assert.equal( paymentDetails.paymentMethod.toString(), - paymentMethods.TKN_ETH, - "Payment Method TKN_ETH not set correctly") + paymentMethods.TKNETH, + "Payment Method TKNETH not set correctly") assert.equal( paymentDetails.addressTokenPrice.toString(), contractBSNTokenPrice.address, - "TKN_ETH Method Price Token Address mismatch") + "TKNETH Method Price Token Address mismatch") assert.equal( paymentDetails.addressTokenDeposits.toString(), constants.ZERO_ADDRESS, - "TKN_ETH Method Deposit Token Address mismatch") + "TKNETH Method Deposit Token Address mismatch") }) it("[NEGATIVE] Should fail if price token contract address is not provided", @@ -680,7 +680,7 @@ contract("Cashier && VK", async addresses => { new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) await truffleAssert.fails( - contractCashier.requestCreateOrder_TKN_ETH( + contractCashier.requestCreateOrderTKNETH( '', [ constants.PROMISE_VALID_FROM, @@ -701,7 +701,7 @@ contract("Cashier && VK", async addresses => { async () => { await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( + contractCashier.requestCreateOrderTKNETH( constants.ZERO_ADDRESS, [ constants.PROMISE_VALID_FROM, @@ -724,7 +724,7 @@ contract("Cashier && VK", async addresses => { new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( + contractCashier.requestCreateOrderTKNETH( contractBSNTokenPrice.address, [ constants.PROMISE_VALID_FROM, @@ -747,7 +747,7 @@ contract("Cashier && VK", async addresses => { new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( + contractCashier.requestCreateOrderTKNETH( contractBSNTokenPrice.address, [ constants.PROMISE_VALID_FROM, @@ -771,7 +771,7 @@ contract("Cashier && VK", async addresses => { new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_ETH( + contractCashier.requestCreateOrderTKNETH( contractBSNTokenPrice.address, [ constants.PROMISE_VALID_FROM, @@ -790,13 +790,13 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_TKN", () => { + describe("TKNTKN", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -863,7 +863,7 @@ contract("Cashier && VK", async addresses => { } }) - it("Should create payment method TKN_TKN", async () => { + it("Should create payment method TKNTKN", async () => { tokenSupplyKey = await utils.createOrder( users.seller, timestamp, @@ -877,16 +877,16 @@ contract("Cashier && VK", async addresses => { assert.equal( paymentDetails.paymentMethod.toString(), - paymentMethods.TKN_TKN, - "Payment Method TKN_TKN not set correctly") + paymentMethods.TKNTKN, + "Payment Method TKNTKN not set correctly") assert.equal( paymentDetails.addressTokenPrice.toString(), contractBSNTokenPrice.address, - "TKN_TKN Method Price Token Address mismatch") + "TKNTKN Method Price Token Address mismatch") assert.equal( paymentDetails.addressTokenDeposits.toString(), contractBSNTokenDeposit.address, - "TKN_TKN Method Deposit Token Address mismatch") + "TKNTKN Method Deposit Token Address mismatch") }) it("[NEGATIVE] Should fail if token price contract address is not provided", @@ -910,7 +910,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.fails( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractCashier.requestCreateOrderTKNTKNWithPermit( '', contractBSNTokenDeposit.address, txValue, @@ -952,7 +952,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.fails( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractCashier.requestCreateOrderTKNTKNWithPermit( contractBSNTokenPrice.address, '', txValue, @@ -994,7 +994,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractCashier.requestCreateOrderTKNTKNWithPermit( constants.ZERO_ADDRESS, contractBSNTokenDeposit.address, txValue, @@ -1038,7 +1038,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractCashier.requestCreateOrderTKNTKNWithPermit( contractBSNTokenPrice.address, constants.ZERO_ADDRESS, txValue, @@ -1081,7 +1081,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractCashier.requestCreateOrderTKNTKNWithPermit( contractBSNTokenPrice.address, contractBSNTokenDeposit.address, txValue, @@ -1123,7 +1123,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractCashier.requestCreateOrderTKNTKNWithPermit( contractBSNTokenPrice.address, contractBSNTokenDeposit.address, txValue, @@ -1165,7 +1165,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.seller.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestCreateOrder_TKN_TKN_WithPermit( + contractCashier.requestCreateOrderTKNTKNWithPermit( contractBSNTokenPrice.address, contractBSNTokenDeposit.address, txValue, @@ -1197,10 +1197,10 @@ contract("Cashier && VK", async addresses => { await deployContracts() }) - describe("ETH_ETH", async () => { + describe("ETHETH", async () => { before(async () => { utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1218,7 +1218,7 @@ contract("Cashier && VK", async addresses => { const txValue = new BN(constants.buyer_deposit).add(new BN(constants.product_price)) let txFillOrder = await contractCashier - .requestVoucher_ETH_ETH( + .requestVoucherETHETH( TOKEN_SUPPLY_ID, users.seller.address, { @@ -1245,7 +1245,7 @@ contract("Cashier && VK", async addresses => { .add(new BN(constants.incorrect_product_price)) await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_ETH( + contractCashier.requestVoucherETHETH( TOKEN_SUPPLY_ID, users.seller.address, { @@ -1263,7 +1263,7 @@ contract("Cashier && VK", async addresses => { .add(new BN(constants.product_price)) await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_ETH( + contractCashier.requestVoucherETHETH( TOKEN_SUPPLY_ID, users.seller.address, { @@ -1276,11 +1276,11 @@ contract("Cashier && VK", async addresses => { }) describe("[WITH PERMIT]", () => { - describe("ETH_TKN", async () => { + describe("ETHTKN", async () => { before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1324,7 +1324,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.buyer.privateKey.slice(2), 'hex')) const txFillOrder = await contractCashier - .requestVoucher_ETH_TKN_WithPermit( + .requestVoucherETHTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, constants.buyer_deposit, @@ -1366,7 +1366,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.buyer.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_TKN_WithPermit( + contractCashier.requestVoucherETHTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, constants.buyer_deposit, @@ -1399,7 +1399,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.buyer.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestVoucher_ETH_TKN_WithPermit( + contractCashier.requestVoucherETHTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, constants.buyer_incorrect_deposit, @@ -1415,11 +1415,11 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_TKN", () => { + describe("TKNTKN", () => { before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1492,7 +1492,7 @@ contract("Cashier && VK", async addresses => { let sPrice = VRS_PRICE.s let txFillOrder = await contractCashier - .requestVoucher_TKN_TKN_WithPermit( + .requestVoucherTKNTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, tokensToSend, @@ -1561,7 +1561,7 @@ contract("Cashier && VK", async addresses => { let sPrice = VRS_PRICE.s await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_WithPermit( + contractCashier.requestVoucherTKNTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, tokensToSend, @@ -1621,7 +1621,7 @@ contract("Cashier && VK", async addresses => { let sPrice = VRS_PRICE.s await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_WithPermit( + contractCashier.requestVoucherTKNTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, tokensToSend, @@ -1638,7 +1638,7 @@ contract("Cashier && VK", async addresses => { }) // Ignored due to deployment failure. - xdescribe("TKN_TKN_SAME", () => { + xdescribe("TKNTKNSAME", () => { const tokensToMintSeller = new BN(constants.seller_deposit) .mul(new BN(ORDER_QTY)) @@ -1649,7 +1649,7 @@ contract("Cashier && VK", async addresses => { before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN_SAME() + .TKNTKNSAME() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1696,7 +1696,7 @@ contract("Cashier && VK", async addresses => { let s = VRS_TOKENS.s let txFillOrder = await contractCashier - .requestVoucher_TKN_TKN_Same_WithPermit( + .requestVoucherTKNTKNSameWithPermit( TOKEN_SUPPLY_ID, users.seller.address, tokensToSend, @@ -1743,7 +1743,7 @@ contract("Cashier && VK", async addresses => { let s = VRS_TOKENS.s await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( + contractCashier.requestVoucherTKNTKNSameWithPermit( TOKEN_SUPPLY_ID, users.seller.address, incorrectTokensToSign, @@ -1781,7 +1781,7 @@ contract("Cashier && VK", async addresses => { let s = VRS_TOKENS.s await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( + contractCashier.requestVoucherTKNTKNSameWithPermit( TOKEN_SUPPLY_ID, users.seller.address, incorrectTokensToSign, @@ -1796,9 +1796,9 @@ contract("Cashier && VK", async addresses => { it("[NEGATIVE] Should revert if Price Token and Deposit Token are diff contracts", async () => { - let utilsTKN_TKN = UtilsBuilder.create() + let utilsTKNTKN = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1813,7 +1813,7 @@ contract("Cashier && VK", async addresses => { await contractBSNTokenPrice .mint(users.buyer.address, tokensToMintBuyer) - TOKEN_SUPPLY_ID = await utilsTKN_TKN.createOrder( + TOKEN_SUPPLY_ID = await utilsTKNTKN.createOrder( users.seller, constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, @@ -1845,7 +1845,7 @@ contract("Cashier && VK", async addresses => { let s = VRS_TOKENS.s await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_TKN_Same_WithPermit( + contractCashier.requestVoucherTKNTKNSameWithPermit( TOKEN_SUPPLY_ID, users.seller.address, tokensToSend, @@ -1860,11 +1860,11 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_ETH", () => { + describe("TKNETH", () => { before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1905,7 +1905,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.buyer.privateKey.slice(2), 'hex')) let txFillOrder = await contractCashier - .requestVoucher_TKN_ETH_WithPermit( + .requestVoucherTKNETHWithPermit( TOKEN_SUPPLY_ID, users.seller.address, constants.product_price, @@ -1948,7 +1948,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.buyer.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_ETH_WithPermit( + contractCashier.requestVoucherTKNETHWithPermit( TOKEN_SUPPLY_ID, users.seller.address, constants.product_price, @@ -1982,7 +1982,7 @@ contract("Cashier && VK", async addresses => { Buffer.from(users.buyer.privateKey.slice(2), 'hex')) await truffleAssert.reverts( - contractCashier.requestVoucher_TKN_ETH_WithPermit( + contractCashier.requestVoucherTKNETHWithPermit( TOKEN_SUPPLY_ID, users.seller.address, constants.incorrect_product_price, @@ -2018,7 +2018,7 @@ contract("Cashier && VK", async addresses => { beforeEach(async () => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -2140,12 +2140,12 @@ contract("Cashier && VK", async addresses => { }) }) - describe("ETH_ETH", () => { + describe("ETHETH", () => { beforeEach(async () => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -2290,7 +2290,7 @@ contract("Cashier && VK", async addresses => { }) describe("[WITH PERMIT]", () => { - describe("ETH_TKN", () => { + describe("ETHTKN", () => { let balanceBuyerFromDeposits = new BN(0) let balanceSellerFromDeposits = new BN(0) @@ -2305,7 +2305,7 @@ contract("Cashier && VK", async addresses => { utils = UtilsBuilder.create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -2461,7 +2461,7 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_TKN", () => { + describe("TKNTKN", () => { let balanceBuyerFromPayment = new BN(0) let balanceBuyerFromDeposits = new BN(0) @@ -2479,7 +2479,7 @@ contract("Cashier && VK", async addresses => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -2649,7 +2649,7 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_ETH", () => { + describe("TKNETH", () => { let balanceBuyerFromPayment = new BN(0) let balanceSellerFromPayment = new BN(0) let escrowBalanceFromPayment = new BN(0) @@ -2663,7 +2663,7 @@ contract("Cashier && VK", async addresses => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -2887,7 +2887,7 @@ contract("Cashier && VK", async addresses => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -2928,12 +2928,12 @@ contract("Cashier && VK", async addresses => { }) }) - describe("ETH_ETH", async () => { + describe("ETHETH", async () => { beforeEach(async () => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -3082,7 +3082,7 @@ contract("Cashier && VK", async addresses => { }) describe("[WITH PERMIT]", () => { - describe("ETH_TKN", () => { + describe("ETHTKN", () => { let balanceBuyerFromDeposits = new BN(0) let balanceSellerFromDeposits = new BN(0) let escrowBalanceFromDeposits = new BN(0) @@ -3106,7 +3106,7 @@ contract("Cashier && VK", async addresses => { utils = UtilsBuilder.create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -3325,7 +3325,7 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_TKN", () => { + describe("TKNTKN", () => { let balanceBuyerFromPayment = new BN(0) let balanceBuyerFromDeposits = new BN(0) @@ -3365,7 +3365,7 @@ contract("Cashier && VK", async addresses => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -3518,7 +3518,7 @@ contract("Cashier && VK", async addresses => { }) - describe("TKN_ETH", () => { + describe("TKNETH", () => { let balanceBuyerFromPayment = new BN(0) let balanceSellerFromPayment = new BN(0) let escrowBalanceFromPayment = new BN(0) @@ -3531,7 +3531,7 @@ contract("Cashier && VK", async addresses => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, diff --git a/test/3_withdrawals.js b/test/3_withdrawals.js index f6a3eeb2..dc4d77d3 100644 --- a/test/3_withdrawals.js +++ b/test/3_withdrawals.js @@ -161,7 +161,7 @@ contract("Cashier withdrawals ", async addresses => { async () => { before(async () => { utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -625,7 +625,7 @@ contract("Cashier withdrawals ", async addresses => { beforeEach(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1321,7 +1321,7 @@ contract("Cashier withdrawals ", async addresses => { beforeEach(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN_SAME() + .TKNTKNSAME() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1896,7 +1896,7 @@ contract("Cashier withdrawals ", async addresses => { beforeEach(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -2601,7 +2601,7 @@ contract("Cashier withdrawals ", async addresses => { beforeEach(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -3386,7 +3386,7 @@ contract("Cashier withdrawals ", async addresses => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -3516,12 +3516,12 @@ contract("Cashier withdrawals ", async addresses => { }) describe("[WITH PERMIT]", () => { - describe("ETH_TKN", () => { + describe("ETHTKN", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -3670,12 +3670,12 @@ contract("Cashier withdrawals ", async addresses => { }) - describe("TKN_ETH", () => { + describe("TKNETH", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -3820,12 +3820,12 @@ contract("Cashier withdrawals ", async addresses => { }) - describe("TKN_TKN", () => { + describe("TKNTKN", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, diff --git a/test/5_pausing_contracts.js b/test/5_pausing_contracts.js index 8df34b73..7cf91e26 100644 --- a/test/5_pausing_contracts.js +++ b/test/5_pausing_contracts.js @@ -65,7 +65,7 @@ contract("Cashier && VK", async addresses => { .setETHLimit(constants.ETHER_LIMIT) utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -123,11 +123,11 @@ contract("Cashier && VK", async addresses => { }) }) - describe("ETH_ETH", () => { + describe("ETHETH", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -368,13 +368,13 @@ contract("Cashier && VK", async addresses => { }) describe("[WITH PERMIT]", () => { - describe("ETH_TKN", () => { + describe("ETHTKN", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -632,12 +632,12 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_ETH", () => { + describe("TKNETH", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -895,12 +895,12 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_TKN", () => { + describe("TKNTKN", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1205,12 +1205,12 @@ contract("Cashier && VK", async addresses => { }) }) - describe("ETH_ETH", () => { + describe("ETHETH", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() - .ETH_ETH() + .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1285,14 +1285,14 @@ contract("Cashier && VK", async addresses => { }) describe("[WITH PERMIT]", () => { - describe("ETH_TKN", () => { + describe("ETHTKN", () => { before(async () => { await deployContracts() await deployContracts() utils = UtilsBuilder .create() .ERC20withPermit() - .ETH_TKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1380,12 +1380,12 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_ETH", () => { + describe("TKNETH", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_ETH() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1469,12 +1469,12 @@ contract("Cashier && VK", async addresses => { }) }) - describe("TKN_TKN", () => { + describe("TKNTKN", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, @@ -1567,12 +1567,12 @@ contract("Cashier && VK", async addresses => { }) // Ignored due to deployment failure. - xdescribe("TKN_TKN_SAME", () => { + xdescribe("TKNTKNSAME", () => { before(async () => { await deployContracts() utils = UtilsBuilder.create() .ERC20withPermit() - .TKN_TKN_SAME() + .TKNTKNSAME() .build( contractERC1155ERC721, contractVoucherKernel, diff --git a/testHelpers/utils.js b/testHelpers/utils.js index ebea161a..3857bce7 100644 --- a/testHelpers/utils.js +++ b/testHelpers/utils.js @@ -27,12 +27,12 @@ class Utils { this.contractBSNTokenSAME = bsnTokenPrice } - async requestCreateOrder_ETH_ETH ( + async requestCreateOrderETHETH ( seller, from, to, sellerDeposit, qty, returnTx = false ) { const txValue = new BN(sellerDeposit).mul(new BN(qty)) - let txOrder = await this.contractCashier.requestCreateOrder_ETH_ETH( + let txOrder = await this.contractCashier.requestCreateOrderETHETH( [ from, to, helpers.product_price, @@ -50,7 +50,7 @@ class Utils { (txOrder.logs[0].args._tokenIdSupply).toString() } - async requestCreateOrder_TKN_TKN_Same_WithPermit ( + async requestCreateOrderETHTKNSameWithPermit ( seller, from, to, sellerDeposit, qty ) { const txValue = new BN(sellerDeposit).mul(new BN(qty)) @@ -71,7 +71,7 @@ class Utils { Buffer.from(seller.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier - .requestCreateOrder_TKN_TKN_WithPermit( + .requestCreateOrderTKNTKNWithPermit( this.contractBSNTokenSAME.address, this.contractBSNTokenSAME.address, txValue, @@ -93,7 +93,7 @@ class Utils { return (txOrder.logs[0].args._tokenIdSupply).toString() } - async requestCreateOrder_TKN_TKN_WithPermit ( + async requestCreateOrderTKNTKNWithPermit ( seller, from, to, sellerDeposit, qty ) { const txValue = new BN(sellerDeposit).mul(new BN(qty)) @@ -114,7 +114,7 @@ class Utils { Buffer.from(seller.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier - .requestCreateOrder_TKN_TKN_WithPermit( + .requestCreateOrderTKNTKNWithPermit( this.contractBSNTokenPrice.address, this.contractBSNTokenDeposit.address, txValue, @@ -136,7 +136,7 @@ class Utils { return (txOrder.logs[0].args._tokenIdSupply).toString() } - async requestCreateOrder_ETH_TKN_WithPermit ( + async requestCreateOrderETHTKNWithPermit ( seller, from, to, sellerDeposit, qty, returnTx = false ) { const txValue = new BN(sellerDeposit).mul(new BN(qty)) @@ -156,7 +156,7 @@ class Utils { Buffer.from(seller.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier - .requestCreateOrder_ETH_TKN_WithPermit( + .requestCreateOrderETHTKNWithPermit( this.contractBSNTokenDeposit.address, txValue, this.deadline, @@ -179,12 +179,12 @@ class Utils { (txOrder.logs[0].args._tokenIdSupply).toString() } - async requestCreateOrder_TKN_ETH ( + async requestCreateOrderTKNETH ( seller, from, to, sellerDeposit, qty ) { const txValue = new BN(sellerDeposit).mul(new BN(qty)) - let txOrder = await this.contractCashier.requestCreateOrder_TKN_ETH( + let txOrder = await this.contractCashier.requestCreateOrderTKNETH( this.contractBSNTokenPrice.address, [ from, @@ -203,7 +203,7 @@ class Utils { return (txOrder.logs[0].args._tokenIdSupply).toString() } - async commitToBuy_TKN_TKN_WithPermit (buyer, seller, tokenSupplyId) { + async commitToBuyTKNTKNWithPermit (buyer, seller, tokenSupplyId) { const txValue = new BN(helpers.buyer_deposit) .add(new BN(helpers.product_price)) const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address) @@ -245,7 +245,7 @@ class Utils { let sPrice = VRS_PRICE.s let CommitTx = await this.contractCashier - .requestVoucher_TKN_TKN_WithPermit( + .requestVoucherTKNTKNWithPermit( tokenSupplyId, seller.address, txValue, @@ -265,7 +265,7 @@ class Utils { return filtered.returnValues['_tokenIdVoucher'] } - async commitToBuy_TKN_TKN_Same_WithPermit (buyer, seller, tokenSupplyId) { + async commitToBuyETHTKNSameWithPermit (buyer, seller, tokenSupplyId) { const txValue = new BN(helpers.buyer_deposit) .add(new BN(helpers.product_price)) const nonce = await this.contractBSNTokenSAME.nonces(buyer.address) @@ -288,7 +288,7 @@ class Utils { let s = VRS_TX_VALUE.s let CommitTx = await this.contractCashier - .requestVoucher_TKN_TKN_Same_WithPermit( + .requestVoucherETHTKNSameWithPermit( tokenSupplyId, seller.address, txValue, @@ -307,7 +307,7 @@ class Utils { return filtered.returnValues['_tokenIdVoucher'] } - async commitToBuy_ETH_TKN_WithPermit (buyer, seller, tokenSupplyId) { + async commitToBuyETHTKNWithPermit (buyer, seller, tokenSupplyId) { const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address) const digestDeposit = await getApprovalDigest( @@ -324,7 +324,7 @@ class Utils { Buffer.from(buyer.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier - .requestVoucher_ETH_TKN_WithPermit( + .requestVoucherETHTKNWithPermit( tokenSupplyId, seller.address, helpers.buyer_deposit, @@ -344,12 +344,12 @@ class Utils { return filtered.returnValues['_tokenIdVoucher'] } - async commitToBuy_ETH_ETH (buyer, seller, tokenSupplyId) { + async commitToBuyETHETH (buyer, seller, tokenSupplyId) { const txValue = new BN(helpers.buyer_deposit) .add(new BN(helpers.product_price)) let CommitTx = await this.contractCashier - .requestVoucher_ETH_ETH( + .requestVoucherETHETH( tokenSupplyId, seller.address, { @@ -368,7 +368,7 @@ class Utils { return filtered.returnValues['_tokenIdVoucher'] } - async commitToBuy_TKN_ETH_WithPermit (buyer, seller, tokenSupplyId) { + async commitToBuyTKNETHWithPermit (buyer, seller, tokenSupplyId) { const nonce1 = await this.contractBSNTokenPrice.nonces(buyer.address) const digestDeposit = await getApprovalDigest( @@ -385,7 +385,7 @@ class Utils { Buffer.from(buyer.privateKey.slice(2), 'hex')) let txOrder = await this.contractCashier - .requestVoucher_TKN_ETH_WithPermit( + .requestVoucherTKNETHWithPermit( tokenSupplyId, seller.address, helpers.product_price, diff --git a/testHelpers/utilsBuilder.js b/testHelpers/utilsBuilder.js index e9a528d7..60fa77f5 100644 --- a/testHelpers/utilsBuilder.js +++ b/testHelpers/utilsBuilder.js @@ -10,20 +10,20 @@ class UtilsBuilder { return new UtilsBuilder() }; - ETH_ETH () { + ETHETH () { this.utils.createOrder = - this.utils.requestCreateOrder_ETH_ETH + this.utils.requestCreateOrderETHETH this.utils.commitToBuy = - this.utils.commitToBuy_ETH_ETH + this.utils.commitToBuyETHETH return this } ERC20withPermit () { - this.ETH_TKN = this.ETH_TKN_WithPermit - this.TKN_TKN = this.TKN_TKN_WithPermit - this.TKN_ETH = this.TKN_ETH_WithPermit - this.TKN_TKN_SAME = this.TKN_TKN_SameWithPermit + this.ETHTKN = this.ETHTKNWithPermit + this.TKNTKN = this.TKNTKNWithPermit + this.TKNETH = this.TKNETHWithPermit + this.TKNTKNSAME = this.TKNTKNSameWithPermit return this } @@ -41,38 +41,38 @@ class UtilsBuilder { return this.utils } - ETH_TKN_WithPermit () { + ETHTKNWithPermit () { this.utils.createOrder = - this.utils.requestCreateOrder_ETH_TKN_WithPermit + this.utils.requestCreateOrderETHTKNWithPermit this.utils.commitToBuy = - this.utils.commitToBuy_ETH_TKN_WithPermit + this.utils.commitToBuyETHTKNWithPermit return this } - TKN_TKN_WithPermit () { + TKNTKNWithPermit () { this.utils.createOrder = - this.utils.requestCreateOrder_TKN_TKN_WithPermit + this.utils.requestCreateOrderTKNTKNWithPermit this.utils.commitToBuy = - this.utils.commitToBuy_TKN_TKN_WithPermit + this.utils.commitToBuyTKNTKNWithPermit return this } - TKN_TKN_SameWithPermit () { + TKNTKNSameWithPermit () { this.utils.createOrder = - this.utils.requestCreateOrder_TKN_TKN_Same_WithPermit + this.utils.requestCreateOrderETHTKNSameWithPermit this.utils.commitToBuy = - this.utils.commitToBuy_TKN_TKN_Same_WithPermit + this.utils.commitToBuyETHTKNSameWithPermit return this } - TKN_ETH_WithPermit () { + TKNETHWithPermit () { this.utils.createOrder = - this.utils.requestCreateOrder_TKN_ETH + this.utils.requestCreateOrderTKNETH this.utils.commitToBuy = - this.utils.commitToBuy_TKN_ETH_WithPermit + this.utils.commitToBuyTKNETHWithPermit return this } From 7b6eb1a2f9c5d7b38ac202cd74975dfc8bb50111 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 21 Jan 2021 00:11:13 +0000 Subject: [PATCH 13/22] Add prettier and prettier-solidity. --- .prettierrc | 25 + Rakefile | 30 +- contracts/BosonTokenDeposit.sol | 20 +- contracts/BosonTokenPrice.sol | 12 +- contracts/Cashier.sol | 1211 ++- contracts/ERC1155ERC721.sol | 625 +- contracts/ERC20WithPermit.sol | 32 +- contracts/FundLimitsOracle.sol | 33 +- contracts/ICashier.sol | 143 +- contracts/IERC1155.sol | 58 +- contracts/IERC1155ERC721.sol | 19 +- contracts/IERC1155TokenReceiver.sol | 18 +- contracts/IERC20WithPermit.sol | 5 +- contracts/IERC721.sol | 55 +- contracts/IERC721TokenReceiver.sol | 9 +- contracts/IFundLimitsOracle.sol | 13 +- contracts/IVoucherKernel.sol | 321 +- contracts/Migrations.sol | 30 +- contracts/UsingHelpers.sol | 64 +- contracts/VoucherKernel.sol | 930 ++- package-lock.json | 93 +- package.json | 12 +- test/1_test_fullpath.js | 847 +- test/2_test_fullpath_with_permit.js | 6230 ++++++++------- test/3_withdrawals.js | 7047 +++++++++-------- test/4_Boson_Token.js | 569 +- test/5_pausing_contracts.js | 2328 +++--- test/6_fundLimits.js | 198 +- testHelpers/constants.js | 78 +- testHelpers/permitUtils.js | 100 +- testHelpers/timemachine.js | 94 +- testHelpers/users.js | 93 +- testHelpers/utils.js | 693 +- testHelpers/utilsBuilder.js | 85 +- testUserInteractions/buyer_complain.js | 71 +- testUserInteractions/buyer_redeem.js | 73 +- testUserInteractions/buyer_refund.js | 68 +- testUserInteractions/buyer_requestVoucher.js | 86 +- testUserInteractions/config.js | 34 +- testUserInteractions/deploy.js | 69 +- testUserInteractions/finalize.js | 117 +- testUserInteractions/fundWallets.js | 48 +- testUserInteractions/seller_cancelOrFault.js | 65 +- .../seller_requestCreateOrder.js | 97 +- testUserInteractions/withdraw.js | 114 +- 45 files changed, 12708 insertions(+), 10254 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..6b8acc94 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,25 @@ +{ + "overrides": [ + { + "files": "*.sol", + "options": { + "printWidth": 80, + "tabWidth": 4, + "useTabs": false, + "singleQuote": false, + "bracketSpacing": false, + "explicitTypes": "always" + } + }, + { + "files": "*.js", + "options": { + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "singleQuote": true, + "bracketSpacing": false + } + } + ] +} \ No newline at end of file diff --git a/Rakefile b/Rakefile index a08824ef..a23fe334 100644 --- a/Rakefile +++ b/Rakefile @@ -3,7 +3,9 @@ require_relative 'lib/ganache' task :default => [ :"contracts:compile", :"contracts:lint_fix", - :"test:integration" + :"contracts:format_fix", + :"tests:format_fix", + :"tests:integration" ] namespace :ganache do @@ -50,9 +52,29 @@ namespace :contracts do task :lint_fix do sh('npm', 'run', 'contracts:lint-fix') end + + desc "Format all contracts" + task :format do + sh('npm', 'run', 'contracts:format') + end + + desc "Format & fix all contracts" + task :format_fix do + sh('npm', 'run', 'contracts:format-fix') + end end -namespace :test do +namespace :tests do + desc "Format all test files" + task :format do + sh('npm', 'run', 'tests:format') + end + + desc "Format & fix all test files" + task :format_fix do + sh('npm', 'run', 'tests:format-fix') + end + desc "Run all contract integration tests" task :integration do Ganache.on_available_port( @@ -64,13 +86,13 @@ namespace :test do "HOST" => "127.0.0.1", "PORT" => "#{ganache.port}", "ACCOUNT_KEYS_FILE" => "#{ganache.account_keys_file}" - }, 'npm', 'run', 'test:integration') + }, 'npm', 'run', 'tests:integration') end end desc "Run test coverage for contract integration tests" task :coverage do puts "Running test coverage for contract integration tests..." - sh(['npm', 'run', 'test:coverage']) + sh(['npm', 'run', 'tests:coverage']) end end diff --git a/contracts/BosonTokenDeposit.sol b/contracts/BosonTokenDeposit.sol index f1906819..bb8109ab 100644 --- a/contracts/BosonTokenDeposit.sol +++ b/contracts/BosonTokenDeposit.sol @@ -6,18 +6,18 @@ import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; /** -* @notice This contract is only used for, while deploying on rinkeby with verifying contracts, -so that we have 2 distinguished contracts concerning tokens for the price of the products, and for the deposits. -Will not be used while deploying on prod. -*/ + * @notice This contract is only used for, while deploying on rinkeby with verifying contracts, + * so that we have 2 distinguished contracts concerning tokens for the price of the products, and for the deposits. + * Will not be used while deploying on prod. + */ contract BosonTokenDeposit is ERC20WithPermit, AccessControl, Ownable { bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); constructor(string memory name, string memory symbol) - public - ERC20WithPermit(name, symbol) + public + ERC20WithPermit(name, symbol) { _setupRole(MINTER_ROLE, owner()); _setupRole(ADMIN_ROLE, owner()); @@ -29,8 +29,10 @@ contract BosonTokenDeposit is ERC20WithPermit, AccessControl, Ownable { } function mint(address to, uint256 amount) public { - require(hasRole(MINTER_ROLE, _msgSender()), - "ERC20PresetMinterPauser: must have minter role to mint"); + require( + hasRole(MINTER_ROLE, _msgSender()), + "ERC20PresetMinterPauser: must have minter role to mint" + ); _mint(to, amount); } -} \ No newline at end of file +} diff --git a/contracts/BosonTokenPrice.sol b/contracts/BosonTokenPrice.sol index 62bd7361..d0db8279 100644 --- a/contracts/BosonTokenPrice.sol +++ b/contracts/BosonTokenPrice.sol @@ -11,8 +11,8 @@ contract BosonTokenPrice is ERC20WithPermit, AccessControl, Ownable { bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); constructor(string memory name, string memory symbol) - public - ERC20WithPermit(name, symbol) + public + ERC20WithPermit(name, symbol) { _setupRole(MINTER_ROLE, owner()); _setupRole(ADMIN_ROLE, owner()); @@ -24,8 +24,10 @@ contract BosonTokenPrice is ERC20WithPermit, AccessControl, Ownable { } function mint(address to, uint256 amount) public { - require(hasRole(MINTER_ROLE, _msgSender()), - "ERC20PresetMinterPauser: must have minter role to mint"); + require( + hasRole(MINTER_ROLE, _msgSender()), + "ERC20PresetMinterPauser: must have minter role to mint" + ); _mint(to, amount); } -} \ No newline at end of file +} diff --git a/contracts/Cashier.sol b/contracts/Cashier.sol index e2221059..3248c412 100644 --- a/contracts/Cashier.sol +++ b/contracts/Cashier.sol @@ -15,21 +15,21 @@ import "./ICashier.sol"; /** * @title Contract for managing funds * @dev Warning: the contract hasn't been audited yet! - * Roughly following OpenZeppelin's Escrow at https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/payment/ + * Roughly following OpenZeppelin's Escrow at https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/payment/ */ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { using Address for address payable; - using SafeMath for uint; - + using SafeMath for uint256; + address public fundLimitsOracle; address public voucherKernel; address public tokensContractAddress; - enum PaymentType { PAYMENT, DEPOSIT_SELLER, DEPOSIT_BUYER } - - mapping(address => uint256) public escrow; //both types of deposits AND payments >> can be released token-by-token if checks pass + enum PaymentType {PAYMENT, DEPOSIT_SELLER, DEPOSIT_BUYER} + + mapping(address => uint256) public escrow; //both types of deposits AND payments >> can be released token-by-token if checks pass //slashedDepositPool can be obtained through getEscrowAmount(poolAddress) - + uint256 internal constant CANCELFAULT_SPLIT = 2; //for POC purposes, this is hardcoded; e.g. each party gets depositSe / 2 struct VoucherDetails { @@ -43,7 +43,7 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 amount2pool; uint256 amount2issuer; uint256 amount2holder; - uint8 paymentMethod; + uint8 paymentMethod; VoucherStatus currStatus; } @@ -53,36 +53,41 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 _quantity, uint8 _paymentType ); - - event LogWithdrawal( - address _caller, - address _payee, - uint256 _payment - ); - event LogAmountDistribution ( + event LogWithdrawal(address _caller, address _payee, uint256 _payment); + + event LogAmountDistribution( uint256 indexed _tokenIdVoucher, - address _to, + address _to, uint256 _payment, PaymentType _type ); - event LogTokenContractSet( - address _newTokenContract, - address _triggeredBy - ); + event LogTokenContractSet(address _newTokenContract, address _triggeredBy); modifier notZeroAddress(address tokenAddress) { require(tokenAddress != address(0), "INVALID_TOKEN_ADDRESS"); _; } - function notAboveETHLimit(uint256 value) internal view{ - require(value <= IFundLimitsOracle(fundLimitsOracle).getETHLimit(), "VALUE_ABOVE_ETH_LIMIT"); + function notAboveETHLimit(uint256 value) internal view { + require( + value <= IFundLimitsOracle(fundLimitsOracle).getETHLimit(), + "VALUE_ABOVE_ETH_LIMIT" + ); } - function notAboveTokenLimit(address _tokenAddress, uint256 value) internal view{ - require(value <= IFundLimitsOracle(fundLimitsOracle).getTokenLimit(_tokenAddress), "VALUE_ABOVE_TKN_LIMIT"); + function notAboveTokenLimit(address _tokenAddress, uint256 value) + internal + view + { + require( + value <= + IFundLimitsOracle(fundLimitsOracle).getTokenLimit( + _tokenAddress + ), + "VALUE_ABOVE_TKN_LIMIT" + ); } modifier onlyTokensContract() { @@ -94,33 +99,30 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { address _voucherKernel, address _tokensContractAddress, address _fundLimitsOracle - ) - public - { + ) public { voucherKernel = _voucherKernel; tokensContractAddress = _tokensContractAddress; fundLimitsOracle = _fundLimitsOracle; } - /** - * @notice Pause the Cashier && the Voucher Kernel contracts in case of emergency. - * All functions related to creating new batch, requestVoucher or withdraw will be paused, hence cannot be executed. - * There is special function for withdrawing funds if contract is paused. - */ + * @notice Pause the Cashier && the Voucher Kernel contracts in case of emergency. + * All functions related to creating new batch, requestVoucher or withdraw will be paused, hence cannot be executed. + * There is special function for withdrawing funds if contract is paused. + */ function pause() external override onlyOwner { _pause(); IVoucherKernel(voucherKernel).pause(); } /** - * @notice Unpause the Cashier && the Voucher Kernel contracts. - * All functions related to creating new batch, requestVoucher or withdraw will be unpaused. - */ + * @notice Unpause the Cashier && the Voucher Kernel contracts. + * All functions related to creating new batch, requestVoucher or withdraw will be unpaused. + */ function unpause() external override onlyOwner { _unpause(); IVoucherKernel(voucherKernel).unpause(); - } + } /** * @notice Issuer/Seller offers promises as supply tokens and needs to escrow the deposit @@ -142,25 +144,38 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { override whenNotPaused { - notAboveETHLimit(metadata[2].mul(metadata[5])); + notAboveETHLimit(metadata[2].mul(metadata[5])); notAboveETHLimit(metadata[3].mul(metadata[5])); notAboveETHLimit(metadata[4].mul(metadata[5])); - require(metadata[3].mul(metadata[5]) == msg.value, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - - uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, ETHETH, address(0), address(0)); + require(metadata[3].mul(metadata[5]) == msg.value, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + + uint256 tokenIdSupply = + IVoucherKernel(voucherKernel).createTokenSupplyID( + msg.sender, + metadata[0], + metadata[1], + metadata[2], + metadata[3], + metadata[4], + metadata[5] + ); + + IVoucherKernel(voucherKernel).createPaymentMethod( + tokenIdSupply, + ETHETH, + address(0), + address(0) + ); //checks //(i) this is for separate promise allocation, not in prototype //uint256 depositSe = IVoucherKernel(voucherKernel).getPromiseDepositSe(promiseId); //require(depositSe * _quantity == weiReceived, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) //(ii) prototype check - - + //record funds in escrow ... escrow[msg.sender] += msg.value; - + emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], ETHETH); } @@ -173,28 +188,54 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { bytes32 r, bytes32 s, uint256[] calldata metadata - ) + ) external - notZeroAddress(_tokenPriceAddress) - notZeroAddress(_tokenDepositAddress) payable override + notZeroAddress(_tokenPriceAddress) + notZeroAddress(_tokenDepositAddress) whenNotPaused { notAboveTokenLimit(_tokenPriceAddress, metadata[2].mul(metadata[5])); notAboveTokenLimit(_tokenDepositAddress, metadata[3].mul(metadata[5])); notAboveTokenLimit(_tokenDepositAddress, metadata[4].mul(metadata[5])); - require(metadata[3].mul(metadata[5]) == _tokensSent, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - - IERC20WithPermit(_tokenDepositAddress).permit(msg.sender, address(this), _tokensSent, deadline, v, r, s); - - uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, TKNTKN, _tokenPriceAddress, _tokenDepositAddress); + require(metadata[3].mul(metadata[5]) == _tokensSent, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + + IERC20WithPermit(_tokenDepositAddress).permit( + msg.sender, + address(this), + _tokensSent, + deadline, + v, + r, + s + ); + + uint256 tokenIdSupply = + IVoucherKernel(voucherKernel).createTokenSupplyID( + msg.sender, + metadata[0], + metadata[1], + metadata[2], + metadata[3], + metadata[4], + metadata[5] + ); + + IVoucherKernel(voucherKernel).createPaymentMethod( + tokenIdSupply, + TKNTKN, + _tokenPriceAddress, + _tokenDepositAddress + ); + + IERC20WithPermit(_tokenDepositAddress).transferFrom( + msg.sender, + address(this), + _tokensSent + ); - IERC20WithPermit(_tokenDepositAddress).transferFrom(msg.sender, address(this), _tokensSent); - emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], TKNTKN); } @@ -206,54 +247,94 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { bytes32 r, bytes32 s, uint256[] calldata metadata - ) + ) external - notZeroAddress(_tokenDepositAddress) payable override + notZeroAddress(_tokenDepositAddress) whenNotPaused { - notAboveETHLimit(metadata[2]); + notAboveETHLimit(metadata[2]); notAboveTokenLimit(_tokenDepositAddress, metadata[3].mul(metadata[5])); notAboveTokenLimit(_tokenDepositAddress, metadata[4].mul(metadata[5])); - require(metadata[3].mul(metadata[5]) == _tokensSent, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - - IERC20WithPermit(_tokenDepositAddress).permit(msg.sender, address(this), _tokensSent, deadline, v, r, s); - - uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, ETHTKN, address(0), _tokenDepositAddress); + require(metadata[3].mul(metadata[5]) == _tokensSent, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + + IERC20WithPermit(_tokenDepositAddress).permit( + msg.sender, + address(this), + _tokensSent, + deadline, + v, + r, + s + ); + + uint256 tokenIdSupply = + IVoucherKernel(voucherKernel).createTokenSupplyID( + msg.sender, + metadata[0], + metadata[1], + metadata[2], + metadata[3], + metadata[4], + metadata[5] + ); + + IVoucherKernel(voucherKernel).createPaymentMethod( + tokenIdSupply, + ETHTKN, + address(0), + _tokenDepositAddress + ); + + IERC20WithPermit(_tokenDepositAddress).transferFrom( + msg.sender, + address(this), + _tokensSent + ); - IERC20WithPermit(_tokenDepositAddress).transferFrom(msg.sender, address(this), _tokensSent); - emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], ETHTKN); } function requestCreateOrderTKNETH( address _tokenPriceAddress, uint256[] calldata metadata - ) + ) external - notZeroAddress(_tokenPriceAddress) payable override + notZeroAddress(_tokenPriceAddress) whenNotPaused { notAboveTokenLimit(_tokenPriceAddress, metadata[2].mul(metadata[5])); notAboveETHLimit(metadata[3].mul(metadata[5])); notAboveETHLimit(metadata[4].mul(metadata[5])); - require(metadata[3].mul(metadata[5]) == msg.value, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - - uint256 tokenIdSupply = IVoucherKernel(voucherKernel).createTokenSupplyID(msg.sender, metadata[0], metadata[1], metadata[2], metadata[3], metadata[4], metadata[5]); - IVoucherKernel(voucherKernel).createPaymentMethod(tokenIdSupply, TKNETH, _tokenPriceAddress, address(0)); + require(metadata[3].mul(metadata[5]) == msg.value, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + + uint256 tokenIdSupply = + IVoucherKernel(voucherKernel).createTokenSupplyID( + msg.sender, + metadata[0], + metadata[1], + metadata[2], + metadata[3], + metadata[4], + metadata[5] + ); + IVoucherKernel(voucherKernel).createPaymentMethod( + tokenIdSupply, + TKNETH, + _tokenPriceAddress, + address(0) + ); escrow[msg.sender] += msg.value; emit LogOrderCreated(tokenIdSupply, msg.sender, metadata[5], TKNETH); } - + /** * @notice Consumer requests/buys a voucher by filling an order and receiving a Voucher Token in return * @param _tokenIdSupply ID of the supply token @@ -269,137 +350,217 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { uint256 weiReceived = msg.value; //checks - (uint256 price, , uint256 depositBu) = IVoucherKernel(voucherKernel).getOrderCosts(_tokenIdSupply); - require(price.add(depositBu) == weiReceived, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - - IVoucherKernel(voucherKernel).fillOrder(_tokenIdSupply, _issuer, msg.sender); + (uint256 price, , uint256 depositBu) = + IVoucherKernel(voucherKernel).getOrderCosts(_tokenIdSupply); + require(price.add(depositBu) == weiReceived, "INCORRECT_FUNDS"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + + IVoucherKernel(voucherKernel).fillOrder( + _tokenIdSupply, + _issuer, + msg.sender + ); //record funds in escrow ... escrow[msg.sender] += weiReceived; } - + function requestVoucherTKNTKNWithPermit( - uint256 _tokenIdSupply, + uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, uint256 deadline, - uint8 vPrice, bytes32 rPrice, bytes32 sPrice, // tokenPrice - uint8 vDeposit, bytes32 rDeposit, bytes32 sDeposit // tokenDeposits - ) - external - payable - override - nonReentrant - whenNotPaused - { - + uint8 vPrice, + bytes32 rPrice, + bytes32 sPrice, // tokenPrice + uint8 vDeposit, + bytes32 rDeposit, + bytes32 sDeposit // tokenDeposits + ) external payable override nonReentrant whenNotPaused { //checks - (uint256 price, uint256 depositBu) = IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); + (uint256 price, uint256 depositBu) = + IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); require(_tokensSent.sub(depositBu) == price, "INCORRECT_FUNDS"); - address tokenPriceAddress = IVoucherKernel(voucherKernel).getVoucherPriceToken(_tokenIdSupply); - address tokenDepositAddress = IVoucherKernel(voucherKernel).getVoucherDepositToken(_tokenIdSupply); - - IERC20WithPermit(tokenPriceAddress).permit(msg.sender, address(this), price, deadline, vPrice, rPrice, sPrice); - IERC20WithPermit(tokenDepositAddress).permit(msg.sender, address(this), depositBu, deadline, vDeposit, rDeposit, sDeposit); + address tokenPriceAddress = + IVoucherKernel(voucherKernel).getVoucherPriceToken(_tokenIdSupply); + address tokenDepositAddress = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + _tokenIdSupply + ); + + IERC20WithPermit(tokenPriceAddress).permit( + msg.sender, + address(this), + price, + deadline, + vPrice, + rPrice, + sPrice + ); + IERC20WithPermit(tokenDepositAddress).permit( + msg.sender, + address(this), + depositBu, + deadline, + vDeposit, + rDeposit, + sDeposit + ); - IVoucherKernel(voucherKernel).fillOrder(_tokenIdSupply, _issuer, msg.sender); + IVoucherKernel(voucherKernel).fillOrder( + _tokenIdSupply, + _issuer, + msg.sender + ); - IERC20WithPermit(tokenPriceAddress).transferFrom(msg.sender, address(this), price); - IERC20WithPermit(tokenDepositAddress).transferFrom(msg.sender, address(this), depositBu); + IERC20WithPermit(tokenPriceAddress).transferFrom( + msg.sender, + address(this), + price + ); + IERC20WithPermit(tokenDepositAddress).transferFrom( + msg.sender, + address(this), + depositBu + ); } - function requestVoucherTKNTKNSameWithPermit( - uint256 _tokenIdSupply, + function requestVoucherTKNTKNSameWithPermit( + uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, uint256 deadline, - uint8 v, bytes32 r, bytes32 s - ) - external - override - nonReentrant - whenNotPaused - { + uint8 v, + bytes32 r, + bytes32 s + ) external override nonReentrant whenNotPaused { //checks - (uint256 price, uint256 depositBu) = IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); + (uint256 price, uint256 depositBu) = + IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); require(_tokensSent.sub(depositBu) == price, "INCORRECT_FUNDS"); - address tokenPriceAddress = IVoucherKernel(voucherKernel).getVoucherPriceToken(_tokenIdSupply); - address tokenDepositAddress = IVoucherKernel(voucherKernel).getVoucherDepositToken(_tokenIdSupply); + address tokenPriceAddress = + IVoucherKernel(voucherKernel).getVoucherPriceToken(_tokenIdSupply); + address tokenDepositAddress = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + _tokenIdSupply + ); require(tokenPriceAddress == tokenDepositAddress, "INVALID_CALL"); - // If tokenPriceAddress && tokenPriceAddress are the same + // If tokenPriceAddress && tokenPriceAddress are the same // practically it's not of importance to each we are sending the funds - IERC20WithPermit(tokenPriceAddress).permit(msg.sender, address(this), _tokensSent, deadline, v, r, s); + IERC20WithPermit(tokenPriceAddress).permit( + msg.sender, + address(this), + _tokensSent, + deadline, + v, + r, + s + ); - IVoucherKernel(voucherKernel).fillOrder(_tokenIdSupply, _issuer, msg.sender); + IVoucherKernel(voucherKernel).fillOrder( + _tokenIdSupply, + _issuer, + msg.sender + ); - IERC20WithPermit(tokenPriceAddress).transferFrom(msg.sender, address(this), _tokensSent); + IERC20WithPermit(tokenPriceAddress).transferFrom( + msg.sender, + address(this), + _tokensSent + ); } function requestVoucherETHTKNWithPermit( - uint256 _tokenIdSupply, + uint256 _tokenIdSupply, address _issuer, uint256 _tokensDeposit, uint256 deadline, - uint8 v, bytes32 r, bytes32 s - ) - external - payable - override - nonReentrant - whenNotPaused - { - + uint8 v, + bytes32 r, + bytes32 s + ) external payable override nonReentrant whenNotPaused { //checks - (uint256 price, uint256 depositBu) = IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); - require(price == msg.value, "INCORRECT_PRICE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - require(depositBu == _tokensDeposit, "INCORRECT_DE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - - address tokenDepositAddress = IVoucherKernel(voucherKernel).getVoucherDepositToken(_tokenIdSupply); - IERC20WithPermit(tokenDepositAddress).permit(msg.sender, address(this), _tokensDeposit, deadline, v, r, s); + (uint256 price, uint256 depositBu) = + IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); + require(price == msg.value, "INCORRECT_PRICE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + require(depositBu == _tokensDeposit, "INCORRECT_DE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + + address tokenDepositAddress = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + _tokenIdSupply + ); + IERC20WithPermit(tokenDepositAddress).permit( + msg.sender, + address(this), + _tokensDeposit, + deadline, + v, + r, + s + ); - IVoucherKernel(voucherKernel).fillOrder(_tokenIdSupply, _issuer, msg.sender); + IVoucherKernel(voucherKernel).fillOrder( + _tokenIdSupply, + _issuer, + msg.sender + ); - IERC20WithPermit(tokenDepositAddress).transferFrom(msg.sender, address(this), _tokensDeposit); + IERC20WithPermit(tokenDepositAddress).transferFrom( + msg.sender, + address(this), + _tokensDeposit + ); - //record funds in escrow ... + //record funds in escrow ... escrow[msg.sender] += msg.value; } function requestVoucherTKNETHWithPermit( - uint256 _tokenIdSupply, + uint256 _tokenIdSupply, address _issuer, uint256 _tokensPrice, uint256 deadline, - uint8 v, bytes32 r, bytes32 s - ) - external - payable - override - nonReentrant - whenNotPaused - { - + uint8 v, + bytes32 r, + bytes32 s + ) external payable override nonReentrant whenNotPaused { //checks - (uint256 price, uint256 depositBu) = IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); - require(price == _tokensPrice, "INCORRECT_PRICE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - require(depositBu == msg.value, "INCORRECT_DE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) - - address tokenPriceAddress = IVoucherKernel(voucherKernel).getVoucherPriceToken(_tokenIdSupply); - IERC20WithPermit(tokenPriceAddress).permit(msg.sender, address(this), price, deadline, v, r, s); + (uint256 price, uint256 depositBu) = + IVoucherKernel(voucherKernel).getBuyerOrderCosts(_tokenIdSupply); + require(price == _tokensPrice, "INCORRECT_PRICE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + require(depositBu == msg.value, "INCORRECT_DE"); //hex"54" FISSION.code(FISSION.Category.Finance, FISSION.Status.InsufficientFunds) + + address tokenPriceAddress = + IVoucherKernel(voucherKernel).getVoucherPriceToken(_tokenIdSupply); + IERC20WithPermit(tokenPriceAddress).permit( + msg.sender, + address(this), + price, + deadline, + v, + r, + s + ); - IVoucherKernel(voucherKernel).fillOrder(_tokenIdSupply, _issuer, msg.sender); + IVoucherKernel(voucherKernel).fillOrder( + _tokenIdSupply, + _issuer, + msg.sender + ); - IERC20WithPermit(tokenPriceAddress).transferFrom(msg.sender, address(this), price); + IERC20WithPermit(tokenPriceAddress).transferFrom( + msg.sender, + address(this), + price + ); - //record funds in escrow ... + //record funds in escrow ... escrow[msg.sender] += msg.value; } - /** * @notice Trigger withdrawals of what funds are releasable * The caller of this function triggers transfers to all involved entities (pool, issuer, token holder), also paying for gas. @@ -416,48 +577,71 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { //TODO: check to pass 2 diff holders and how the amounts will be distributed VoucherDetails memory voucherDetails; - + //in the future might want to (i) check the gasleft() (but UNGAS proposal might make it impossible), and/or (ii) set upper loop limit to sth like .length < 2**15 - require(_tokenIdVoucher != 0, "UNSPECIFIED_ID"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - - voucherDetails.tokenIdVoucher = _tokenIdVoucher; - voucherDetails.tokenIdSupply = IVoucherKernel(voucherKernel).getIdSupplyFromVoucher(voucherDetails.tokenIdVoucher); - voucherDetails.paymentMethod = IVoucherKernel(voucherKernel).getVoucherPaymentMethod(voucherDetails.tokenIdSupply); + require(_tokenIdVoucher != 0, "UNSPECIFIED_ID"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(voucherDetails.paymentMethod > 0 && voucherDetails.paymentMethod <= 4, "INVALID PAYMENT METHOD"); + voucherDetails.tokenIdVoucher = _tokenIdVoucher; + voucherDetails.tokenIdSupply = IVoucherKernel(voucherKernel) + .getIdSupplyFromVoucher(voucherDetails.tokenIdVoucher); + voucherDetails.paymentMethod = IVoucherKernel(voucherKernel) + .getVoucherPaymentMethod(voucherDetails.tokenIdSupply); + + require( + voucherDetails.paymentMethod > 0 && + voucherDetails.paymentMethod <= 4, + "INVALID PAYMENT METHOD" + ); - (voucherDetails.currStatus.status, + ( + voucherDetails.currStatus.status, voucherDetails.currStatus.isPaymentReleased, voucherDetails.currStatus.isDepositsReleased - ) = IVoucherKernel(voucherKernel).getVoucherStatus(voucherDetails.tokenIdVoucher); - - (voucherDetails.price, - voucherDetails.depositSe, + ) = IVoucherKernel(voucherKernel).getVoucherStatus( + voucherDetails.tokenIdVoucher + ); + + ( + voucherDetails.price, + voucherDetails.depositSe, voucherDetails.depositBu - ) = IVoucherKernel(voucherKernel).getOrderCosts(voucherDetails.tokenIdSupply); - - voucherDetails.issuer = address(uint160(IVoucherKernel(voucherKernel).getSupplyHolder(voucherDetails.tokenIdSupply))); - voucherDetails.holder = address(uint160(IVoucherKernel(voucherKernel).getVoucherHolder(voucherDetails.tokenIdVoucher))); - - + ) = IVoucherKernel(voucherKernel).getOrderCosts( + voucherDetails.tokenIdSupply + ); + + voucherDetails.issuer = address( + uint160( + IVoucherKernel(voucherKernel).getSupplyHolder( + voucherDetails.tokenIdSupply + ) + ) + ); + voucherDetails.holder = address( + uint160( + IVoucherKernel(voucherKernel).getVoucherHolder( + voucherDetails.tokenIdVoucher + ) + ) + ); + //process the RELEASE OF PAYMENTS - only depends on the redeemed/not-redeemed, a voucher need not be in the final status - if (!voucherDetails.currStatus.isPaymentReleased) - { + if (!voucherDetails.currStatus.isPaymentReleased) { releasePayments(voucherDetails); } - //process the RELEASE OF DEPOSITS - only when vouchers are in the FINAL status - if (!voucherDetails.currStatus.isDepositsReleased && - isStatus(voucherDetails.currStatus.status, IDX_FINAL)) - { + //process the RELEASE OF DEPOSITS - only when vouchers are in the FINAL status + if ( + !voucherDetails.currStatus.isDepositsReleased && + isStatus(voucherDetails.currStatus.status, IDX_FINAL) + ) { releaseDeposits(voucherDetails); } - + if (voucherDetails.amount2pool > 0) { address payable poolAddress = address(uint160(owner())); //this is required as we could not implicitly cast the owner address to payable _withdraw(poolAddress, voucherDetails.amount2pool); } - + if (voucherDetails.amount2issuer > 0) { _withdraw(voucherDetails.issuer, voucherDetails.amount2issuer); } @@ -467,7 +651,6 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { } delete voucherDetails; - } /** @@ -483,49 +666,77 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { whenPaused { VoucherDetails memory voucherDetails; - + //in the future might want to (i) check the gasleft() (but UNGAS proposal might make it impossible), and/or (ii) set upper loop limit to sth like .length < 2**15 - require(_tokenIdVoucher != 0, "UNSPECIFIED_ID"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - - voucherDetails.tokenIdVoucher = _tokenIdVoucher; - voucherDetails.tokenIdSupply = IVoucherKernel(voucherKernel).getIdSupplyFromVoucher(voucherDetails.tokenIdVoucher); - voucherDetails.paymentMethod = IVoucherKernel(voucherKernel).getVoucherPaymentMethod(voucherDetails.tokenIdSupply); + require(_tokenIdVoucher != 0, "UNSPECIFIED_ID"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(voucherDetails.paymentMethod > 0 && voucherDetails.paymentMethod <= 4, "INVALID PAYMENT METHOD"); + voucherDetails.tokenIdVoucher = _tokenIdVoucher; + voucherDetails.tokenIdSupply = IVoucherKernel(voucherKernel) + .getIdSupplyFromVoucher(voucherDetails.tokenIdVoucher); + voucherDetails.paymentMethod = IVoucherKernel(voucherKernel) + .getVoucherPaymentMethod(voucherDetails.tokenIdSupply); + + require( + voucherDetails.paymentMethod > 0 && + voucherDetails.paymentMethod <= 4, + "INVALID PAYMENT METHOD" + ); - (voucherDetails.currStatus.status, + ( + voucherDetails.currStatus.status, voucherDetails.currStatus.isPaymentReleased, voucherDetails.currStatus.isDepositsReleased - ) = IVoucherKernel(voucherKernel).getVoucherStatus(voucherDetails.tokenIdVoucher); - - (voucherDetails.price, - voucherDetails.depositSe, + ) = IVoucherKernel(voucherKernel).getVoucherStatus( + voucherDetails.tokenIdVoucher + ); + + ( + voucherDetails.price, + voucherDetails.depositSe, voucherDetails.depositBu - ) = IVoucherKernel(voucherKernel).getOrderCosts(voucherDetails.tokenIdSupply); - - voucherDetails.issuer = address(uint160(IVoucherKernel(voucherKernel).getSupplyHolder(voucherDetails.tokenIdSupply))); - voucherDetails.holder = address(uint160(IVoucherKernel(voucherKernel).getVoucherHolder(voucherDetails.tokenIdVoucher))); - - require(msg.sender == voucherDetails.issuer || msg.sender == voucherDetails.holder, "INVALID CALLER"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - + ) = IVoucherKernel(voucherKernel).getOrderCosts( + voucherDetails.tokenIdSupply + ); + + voucherDetails.issuer = address( + uint160( + IVoucherKernel(voucherKernel).getSupplyHolder( + voucherDetails.tokenIdSupply + ) + ) + ); + voucherDetails.holder = address( + uint160( + IVoucherKernel(voucherKernel).getVoucherHolder( + voucherDetails.tokenIdVoucher + ) + ) + ); + + require( + msg.sender == voucherDetails.issuer || + msg.sender == voucherDetails.holder, + "INVALID CALLER" + ); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + //process the RELEASE OF PAYMENTS - only depends on the redeemed/not-redeemed, a voucher need not be in the final status - if (!voucherDetails.currStatus.isPaymentReleased) - { + if (!voucherDetails.currStatus.isPaymentReleased) { releasePayments(voucherDetails); } - //process the RELEASE OF DEPOSITS - only when vouchers are in the FINAL status - if (!voucherDetails.currStatus.isDepositsReleased && - isStatus(voucherDetails.currStatus.status, IDX_FINAL)) - { + //process the RELEASE OF DEPOSITS - only when vouchers are in the FINAL status + if ( + !voucherDetails.currStatus.isDepositsReleased && + isStatus(voucherDetails.currStatus.status, IDX_FINAL) + ) { releaseDeposits(voucherDetails); } - + if (voucherDetails.amount2pool > 0) { address payable poolAddress = address(uint160(owner())); _withdraw(poolAddress, voucherDetails.amount2pool); } - + if (voucherDetails.amount2issuer > 0) { _withdraw(voucherDetails.issuer, voucherDetails.amount2issuer); } @@ -535,70 +746,97 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { } delete voucherDetails; - } function releasePayments(VoucherDetails memory voucherDetails) internal { - if (isStatus(voucherDetails.currStatus.status, IDX_REDEEM)) { releasePaymentToSeller(voucherDetails); - } else if (isStatus(voucherDetails.currStatus.status, IDX_REFUND) - || isStatus(voucherDetails.currStatus.status, IDX_EXPIRE) - || (isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT) - && !isStatus(voucherDetails.currStatus.status, IDX_REDEEM))) - { - releasePaymentToBuyer(voucherDetails); + } else if ( + isStatus(voucherDetails.currStatus.status, IDX_REFUND) || + isStatus(voucherDetails.currStatus.status, IDX_EXPIRE) || + (isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT) && + !isStatus(voucherDetails.currStatus.status, IDX_REDEEM)) + ) { + releasePaymentToBuyer(voucherDetails); } } - function releasePaymentToSeller(VoucherDetails memory voucherDetails) internal { - - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == ETHTKN) { + function releasePaymentToSeller(VoucherDetails memory voucherDetails) + internal + { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == ETHTKN + ) { escrow[voucherDetails.holder] -= voucherDetails.price; voucherDetails.amount2issuer += voucherDetails.price; } // TODO Chris - Can we have the same approach as above, first collect all amounts in one variable and do the payout at the end? So we save gas from multiple transfers - if(voucherDetails.paymentMethod == TKNETH || voucherDetails.paymentMethod == TKNTKN) { - address addressTokenPrice = IVoucherKernel(voucherKernel).getVoucherPriceToken(voucherDetails.tokenIdSupply); - IERC20WithPermit(addressTokenPrice).transfer(voucherDetails.issuer, voucherDetails.price); + if ( + voucherDetails.paymentMethod == TKNETH || + voucherDetails.paymentMethod == TKNTKN + ) { + address addressTokenPrice = + IVoucherKernel(voucherKernel).getVoucherPriceToken( + voucherDetails.tokenIdSupply + ); + IERC20WithPermit(addressTokenPrice).transfer( + voucherDetails.issuer, + voucherDetails.price + ); } - IVoucherKernel(voucherKernel).setPaymentReleased(voucherDetails.tokenIdVoucher); + IVoucherKernel(voucherKernel).setPaymentReleased( + voucherDetails.tokenIdVoucher + ); LogAmountDistribution( - voucherDetails.tokenIdVoucher, - voucherDetails.issuer, - voucherDetails.price, + voucherDetails.tokenIdVoucher, + voucherDetails.issuer, + voucherDetails.price, PaymentType.PAYMENT ); } - function releasePaymentToBuyer(VoucherDetails memory voucherDetails) internal { - - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == ETHTKN) { + function releasePaymentToBuyer(VoucherDetails memory voucherDetails) + internal + { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == ETHTKN + ) { escrow[voucherDetails.holder] -= voucherDetails.price; voucherDetails.amount2holder += voucherDetails.price; } - if(voucherDetails.paymentMethod == TKNETH || voucherDetails.paymentMethod == TKNTKN) { - address addressTokenPrice = IVoucherKernel(voucherKernel).getVoucherPriceToken(voucherDetails.tokenIdSupply); - IERC20WithPermit(addressTokenPrice).transfer(voucherDetails.holder, voucherDetails.price); - + if ( + voucherDetails.paymentMethod == TKNETH || + voucherDetails.paymentMethod == TKNTKN + ) { + address addressTokenPrice = + IVoucherKernel(voucherKernel).getVoucherPriceToken( + voucherDetails.tokenIdSupply + ); + IERC20WithPermit(addressTokenPrice).transfer( + voucherDetails.holder, + voucherDetails.price + ); } - IVoucherKernel(voucherKernel).setPaymentReleased(voucherDetails.tokenIdVoucher); + IVoucherKernel(voucherKernel).setPaymentReleased( + voucherDetails.tokenIdVoucher + ); LogAmountDistribution( - voucherDetails.tokenIdVoucher, - voucherDetails.holder, - voucherDetails.price, + voucherDetails.tokenIdVoucher, + voucherDetails.holder, + voucherDetails.price, PaymentType.PAYMENT ); } function releaseDeposits(VoucherDetails memory voucherDetails) internal { - //first, depositSe if (isStatus(voucherDetails.currStatus.status, IDX_COMPLAIN)) { //slash depositSe @@ -609,233 +847,370 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { distributeIssuerDepositOnIssuerCancel(voucherDetails); } else { //release depositSe - distributeFullIssuerDeposit(voucherDetails); + distributeFullIssuerDeposit(voucherDetails); } } - - //second, depositBu - if (isStatus(voucherDetails.currStatus.status, IDX_REDEEM) || + + //second, depositBu + if ( + isStatus(voucherDetails.currStatus.status, IDX_REDEEM) || isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT) - ) { + ) { //release depositBu distributeFullHolderDeposit(voucherDetails); } else { //slash depositBu distributeHolderDepositOnNotRedeemedNotCancelled(voucherDetails); - } - IVoucherKernel(voucherKernel).setDepositsReleased(voucherDetails.tokenIdVoucher); + IVoucherKernel(voucherKernel).setDepositsReleased( + voucherDetails.tokenIdVoucher + ); } - function distributeIssuerDepositOnHolderComplain(VoucherDetails memory voucherDetails) internal { - + function distributeIssuerDepositOnHolderComplain( + VoucherDetails memory voucherDetails + ) internal { uint256 tFraction; if (isStatus(voucherDetails.currStatus.status, IDX_CANCEL_FAULT)) { //appease the conflict three-ways - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == TKNETH + ) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; tFraction = voucherDetails.depositSe.div(CANCELFAULT_SPLIT); voucherDetails.amount2holder += tFraction; //Bu gets, say, a half - voucherDetails.amount2issuer += tFraction.div(CANCELFAULT_SPLIT); //Se gets, say, a quarter - voucherDetails.amount2pool += voucherDetails.depositSe - tFraction - tFraction.div(CANCELFAULT_SPLIT); //slashing the rest + voucherDetails.amount2issuer += tFraction.div( + CANCELFAULT_SPLIT + ); //Se gets, say, a quarter + voucherDetails.amount2pool += + voucherDetails.depositSe - + tFraction - + tFraction.div(CANCELFAULT_SPLIT); //slashing the rest } - if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { - address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); - + if ( + voucherDetails.paymentMethod == ETHTKN || + voucherDetails.paymentMethod == TKNTKN + ) { + address addressTokenDeposits = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + voucherDetails.tokenIdSupply + ); + tFraction = voucherDetails.depositSe.div(CANCELFAULT_SPLIT); - IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.holder, tFraction); - IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.issuer, tFraction.div(CANCELFAULT_SPLIT)); - IERC20WithPermit(addressTokenDeposits).transfer(owner(), voucherDetails.depositSe - tFraction - tFraction.div(CANCELFAULT_SPLIT)); + IERC20WithPermit(addressTokenDeposits).transfer( + voucherDetails.holder, + tFraction + ); + IERC20WithPermit(addressTokenDeposits).transfer( + voucherDetails.issuer, + tFraction.div(CANCELFAULT_SPLIT) + ); + IERC20WithPermit(addressTokenDeposits).transfer( + owner(), + voucherDetails.depositSe - + tFraction - + tFraction.div(CANCELFAULT_SPLIT) + ); } - LogAmountDistribution(voucherDetails.tokenIdVoucher, voucherDetails.holder, tFraction, PaymentType.DEPOSIT_SELLER); - LogAmountDistribution(voucherDetails.tokenIdVoucher, voucherDetails.issuer, tFraction.div(CANCELFAULT_SPLIT), PaymentType.DEPOSIT_SELLER); - LogAmountDistribution(voucherDetails.tokenIdVoucher, owner(), voucherDetails.depositSe - tFraction - tFraction.div(CANCELFAULT_SPLIT), PaymentType.DEPOSIT_SELLER); - - tFraction = 0; + LogAmountDistribution( + voucherDetails.tokenIdVoucher, + voucherDetails.holder, + tFraction, + PaymentType.DEPOSIT_SELLER + ); + LogAmountDistribution( + voucherDetails.tokenIdVoucher, + voucherDetails.issuer, + tFraction.div(CANCELFAULT_SPLIT), + PaymentType.DEPOSIT_SELLER + ); + LogAmountDistribution( + voucherDetails.tokenIdVoucher, + owner(), + voucherDetails.depositSe - + tFraction - + tFraction.div(CANCELFAULT_SPLIT), + PaymentType.DEPOSIT_SELLER + ); + tFraction = 0; } else { //slash depositSe - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == TKNETH + ) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; voucherDetails.amount2pool += voucherDetails.depositSe; } else { - address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); - IERC20WithPermit(addressTokenDeposits).transfer(owner(), voucherDetails.depositSe); + address addressTokenDeposits = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + voucherDetails.tokenIdSupply + ); + IERC20WithPermit(addressTokenDeposits).transfer( + owner(), + voucherDetails.depositSe + ); } - LogAmountDistribution(voucherDetails.tokenIdVoucher, owner(), voucherDetails.depositSe, PaymentType.DEPOSIT_SELLER); + LogAmountDistribution( + voucherDetails.tokenIdVoucher, + owner(), + voucherDetails.depositSe, + PaymentType.DEPOSIT_SELLER + ); } } - function distributeIssuerDepositOnIssuerCancel(VoucherDetails memory voucherDetails) internal { - - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { + function distributeIssuerDepositOnIssuerCancel( + VoucherDetails memory voucherDetails + ) internal { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == TKNETH + ) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; - voucherDetails.amount2issuer += voucherDetails.depositSe.div(CANCELFAULT_SPLIT); - voucherDetails.amount2holder += voucherDetails.depositSe - voucherDetails.depositSe.div(CANCELFAULT_SPLIT); + voucherDetails.amount2issuer += voucherDetails.depositSe.div( + CANCELFAULT_SPLIT + ); + voucherDetails.amount2holder += + voucherDetails.depositSe - + voucherDetails.depositSe.div(CANCELFAULT_SPLIT); } - if (voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { - address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); - - IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.issuer, voucherDetails.depositSe.div(CANCELFAULT_SPLIT)); - IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.holder, voucherDetails.depositSe - voucherDetails.depositSe.div(CANCELFAULT_SPLIT)); + if ( + voucherDetails.paymentMethod == ETHTKN || + voucherDetails.paymentMethod == TKNTKN + ) { + address addressTokenDeposits = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + voucherDetails.tokenIdSupply + ); + + IERC20WithPermit(addressTokenDeposits).transfer( + voucherDetails.issuer, + voucherDetails.depositSe.div(CANCELFAULT_SPLIT) + ); + IERC20WithPermit(addressTokenDeposits).transfer( + voucherDetails.holder, + voucherDetails.depositSe - + voucherDetails.depositSe.div(CANCELFAULT_SPLIT) + ); } LogAmountDistribution( - voucherDetails.tokenIdVoucher, - voucherDetails.issuer, - voucherDetails.depositSe.div(CANCELFAULT_SPLIT), + voucherDetails.tokenIdVoucher, + voucherDetails.issuer, + voucherDetails.depositSe.div(CANCELFAULT_SPLIT), PaymentType.DEPOSIT_SELLER ); LogAmountDistribution( - voucherDetails.tokenIdVoucher, - voucherDetails.holder, - voucherDetails.depositSe - voucherDetails.depositSe.div(CANCELFAULT_SPLIT), + voucherDetails.tokenIdVoucher, + voucherDetails.holder, + voucherDetails.depositSe - + voucherDetails.depositSe.div(CANCELFAULT_SPLIT), PaymentType.DEPOSIT_SELLER ); } - function distributeFullIssuerDeposit(VoucherDetails memory voucherDetails) internal { - - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { + function distributeFullIssuerDeposit(VoucherDetails memory voucherDetails) + internal + { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == TKNETH + ) { escrow[voucherDetails.issuer] -= voucherDetails.depositSe; voucherDetails.amount2issuer += voucherDetails.depositSe; } - if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { - address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); - IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.issuer, voucherDetails.depositSe); + if ( + voucherDetails.paymentMethod == ETHTKN || + voucherDetails.paymentMethod == TKNTKN + ) { + address addressTokenDeposits = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + voucherDetails.tokenIdSupply + ); + IERC20WithPermit(addressTokenDeposits).transfer( + voucherDetails.issuer, + voucherDetails.depositSe + ); } LogAmountDistribution( - voucherDetails.tokenIdVoucher, - voucherDetails.issuer, - voucherDetails.depositSe, + voucherDetails.tokenIdVoucher, + voucherDetails.issuer, + voucherDetails.depositSe, PaymentType.DEPOSIT_SELLER - ); + ); } - function distributeFullHolderDeposit(VoucherDetails memory voucherDetails) internal { - - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { + function distributeFullHolderDeposit(VoucherDetails memory voucherDetails) + internal + { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == TKNETH + ) { escrow[voucherDetails.holder] -= voucherDetails.depositBu; voucherDetails.amount2holder += voucherDetails.depositBu; } - if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { - address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); - IERC20WithPermit(addressTokenDeposits).transfer(voucherDetails.holder, voucherDetails.depositBu); + if ( + voucherDetails.paymentMethod == ETHTKN || + voucherDetails.paymentMethod == TKNTKN + ) { + address addressTokenDeposits = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + voucherDetails.tokenIdSupply + ); + IERC20WithPermit(addressTokenDeposits).transfer( + voucherDetails.holder, + voucherDetails.depositBu + ); } LogAmountDistribution( - voucherDetails.tokenIdVoucher, - voucherDetails.holder, - voucherDetails.depositBu, + voucherDetails.tokenIdVoucher, + voucherDetails.holder, + voucherDetails.depositBu, PaymentType.DEPOSIT_BUYER - ); + ); } - function distributeHolderDepositOnNotRedeemedNotCancelled(VoucherDetails memory voucherDetails) internal { - - if(voucherDetails.paymentMethod == ETHETH || voucherDetails.paymentMethod == TKNETH) { + function distributeHolderDepositOnNotRedeemedNotCancelled( + VoucherDetails memory voucherDetails + ) internal { + if ( + voucherDetails.paymentMethod == ETHETH || + voucherDetails.paymentMethod == TKNETH + ) { escrow[voucherDetails.holder] -= voucherDetails.depositBu; - voucherDetails.amount2pool += voucherDetails.depositBu; + voucherDetails.amount2pool += voucherDetails.depositBu; } - if(voucherDetails.paymentMethod == ETHTKN || voucherDetails.paymentMethod == TKNTKN) { - address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(voucherDetails.tokenIdSupply); - IERC20WithPermit(addressTokenDeposits).transfer(owner(), voucherDetails.depositBu); + if ( + voucherDetails.paymentMethod == ETHTKN || + voucherDetails.paymentMethod == TKNTKN + ) { + address addressTokenDeposits = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + voucherDetails.tokenIdSupply + ); + IERC20WithPermit(addressTokenDeposits).transfer( + owner(), + voucherDetails.depositBu + ); } LogAmountDistribution( - voucherDetails.tokenIdVoucher, - owner(), - voucherDetails.depositBu, + voucherDetails.tokenIdVoucher, + owner(), + voucherDetails.depositBu, PaymentType.DEPOSIT_BUYER - ); + ); } /** - * @notice Seller triggers withdrawals of remaining deposits for a given supply, in case the contracts are paused. - * @param _tokenIdSupply an ID of a supply token (ERC-1155) which will be burned and deposits will be returned for - */ + * @notice Seller triggers withdrawals of remaining deposits for a given supply, in case the contracts are paused. + * @param _tokenIdSupply an ID of a supply token (ERC-1155) which will be burned and deposits will be returned for + */ function withdrawDeposits(uint256 _tokenIdSupply) external override nonReentrant whenPaused { - address payable seller = address(uint160(IVoucherKernel(voucherKernel).getSupplyHolder(_tokenIdSupply))); - + address payable seller = + address( + uint160( + IVoucherKernel(voucherKernel).getSupplyHolder( + _tokenIdSupply + ) + ) + ); + require(msg.sender == seller, "UNAUTHORIZED_SE"); - uint256 deposit = IVoucherKernel(voucherKernel).getSellerDeposit(_tokenIdSupply); - uint256 remQty = IVoucherKernel(voucherKernel).getRemQtyForSupply(_tokenIdSupply, seller); - + uint256 deposit = + IVoucherKernel(voucherKernel).getSellerDeposit(_tokenIdSupply); + uint256 remQty = + IVoucherKernel(voucherKernel).getRemQtyForSupply( + _tokenIdSupply, + seller + ); + require(remQty > 0, "OFFER_EMPTY"); uint256 depositAmount = deposit.mul(remQty); - IVoucherKernel(voucherKernel).burnSupplyOnPause(seller, _tokenIdSupply, remQty); - - uint8 paymentMethod = IVoucherKernel(voucherKernel).getVoucherPaymentMethod(_tokenIdSupply); + IVoucherKernel(voucherKernel).burnSupplyOnPause( + seller, + _tokenIdSupply, + remQty + ); - require(paymentMethod > 0 && paymentMethod <= 4, "INVALID PAYMENT METHOD"); + uint8 paymentMethod = + IVoucherKernel(voucherKernel).getVoucherPaymentMethod( + _tokenIdSupply + ); + require( + paymentMethod > 0 && paymentMethod <= 4, + "INVALID PAYMENT METHOD" + ); - if(paymentMethod == ETHETH || paymentMethod == TKNETH) - { + if (paymentMethod == ETHETH || paymentMethod == TKNETH) { escrow[msg.sender] = escrow[msg.sender].sub(depositAmount); _withdrawDeposits(seller, depositAmount); } - if(paymentMethod == ETHTKN || paymentMethod == TKNTKN) - { - address addressTokenDeposits = IVoucherKernel(voucherKernel).getVoucherDepositToken(_tokenIdSupply); - IERC20WithPermit(addressTokenDeposits).transfer(seller, depositAmount); + if (paymentMethod == ETHTKN || paymentMethod == TKNTKN) { + address addressTokenDeposits = + IVoucherKernel(voucherKernel).getVoucherDepositToken( + _tokenIdSupply + ); + IERC20WithPermit(addressTokenDeposits).transfer( + seller, + depositAmount + ); } } /** * @notice Trigger withdrawals of pooled funds - */ - function withdrawPool() - external - override - onlyOwner - nonReentrant - { + */ + function withdrawPool() external override onlyOwner nonReentrant { //TODO: more requires needed? - + if (escrow[owner()] > 0) { address payable poolAddress = address(uint160(owner())); //this is required as we could not implicitly cast the owner address to payable uint256 amount = escrow[poolAddress]; escrow[poolAddress] = 0; - _withdraw(poolAddress,amount); + _withdraw(poolAddress, amount); } - } - + } + /** * @notice Internal function for withdrawing. * As unbelievable as it is, neither .send() nor .transfer() are now secure to use due to EIP-1884 * So now transferring funds via the last remaining option: .call() - * See https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/ + * See https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/ * @param _recipient address of the account receiving funds from the escrow * @param _amount amount to be released from escrow */ - function _withdraw(address payable _recipient, uint256 _amount) - internal - { - require(_recipient != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + function _withdraw(address payable _recipient, uint256 _amount) internal { + require(_recipient != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) require(_amount > 0, ""); - + _recipient.sendValue(_amount); emit LogWithdrawal(msg.sender, _recipient, _amount); @@ -844,95 +1219,110 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { function _withdrawDeposits(address payable _recipient, uint256 _amount) internal { - require(_recipient != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require(_recipient != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) require(_amount > 0, ""); - + _recipient.sendValue(_amount); emit LogWithdrawal(msg.sender, _recipient, _amount); } - /** - * @notice Hook which will be triggered when a _tokenIdVoucher will be transferred. Escrow funds should be allocated to the new owner. - * @param _from prev owner of the _tokenIdVoucher - * @param _to next owner of the _tokenIdVoucher - * @param _tokenIdVoucher _tokenIdVoucher that has been transferred - */ - function _onERC721Transfer(address _from, address _to, uint256 _tokenIdVoucher) - external - override - onlyTokensContract - { - uint256 tokenSupplyId = IVoucherKernel(voucherKernel).getIdSupplyFromVoucher(_tokenIdVoucher); - uint8 paymentType = IVoucherKernel(voucherKernel).getVoucherPaymentMethod(tokenSupplyId); - - (uint256 price, uint256 depositBu) = IVoucherKernel(voucherKernel).getBuyerOrderCosts(tokenSupplyId); - - if(paymentType == ETHETH) - { + * @notice Hook which will be triggered when a _tokenIdVoucher will be transferred. Escrow funds should be allocated to the new owner. + * @param _from prev owner of the _tokenIdVoucher + * @param _to next owner of the _tokenIdVoucher + * @param _tokenIdVoucher _tokenIdVoucher that has been transferred + */ + function _onERC721Transfer( + address _from, + address _to, + uint256 _tokenIdVoucher + ) external override onlyTokensContract { + uint256 tokenSupplyId = + IVoucherKernel(voucherKernel).getIdSupplyFromVoucher( + _tokenIdVoucher + ); + uint8 paymentType = + IVoucherKernel(voucherKernel).getVoucherPaymentMethod( + tokenSupplyId + ); + + (uint256 price, uint256 depositBu) = + IVoucherKernel(voucherKernel).getBuyerOrderCosts(tokenSupplyId); + + if (paymentType == ETHETH) { uint256 totalAmount = price.add(depositBu); escrow[_from] = escrow[_from].sub(totalAmount); escrow[_to] = escrow[_to].add(totalAmount); } - if(paymentType == ETHTKN) { + if (paymentType == ETHTKN) { escrow[_from] = escrow[_from].sub(price); escrow[_to] = escrow[_to].add(price); } - if(paymentType == TKNETH) { + if (paymentType == TKNETH) { escrow[_from] = escrow[_from].sub(depositBu); escrow[_to] = escrow[_to].add(depositBu); } } - /** - * @notice Pre-validation when a transfer from the the Tokens contract is triggered. Only the whole supply is allowed for transfer, otherwise reverts. - * @param _from owner of the _tokenSupplyId - * @param _tokenSupplyId _tokenSupplyId which will be validated - * @param _value qty which is desired to be transferred - */ - function _beforeERC1155Transfer(address _from, uint256 _tokenSupplyId, uint256 _value) - external - view - override - onlyTokensContract - { - uint256 _tokenSupplyQty = IVoucherKernel(voucherKernel).getRemQtyForSupply(_tokenSupplyId, _from); + * @notice Pre-validation when a transfer from the the Tokens contract is triggered. Only the whole supply is allowed for transfer, otherwise reverts. + * @param _from owner of the _tokenSupplyId + * @param _tokenSupplyId _tokenSupplyId which will be validated + * @param _value qty which is desired to be transferred + */ + function _beforeERC1155Transfer( + address _from, + uint256 _tokenSupplyId, + uint256 _value + ) external view override onlyTokensContract { + uint256 _tokenSupplyQty = + IVoucherKernel(voucherKernel).getRemQtyForSupply( + _tokenSupplyId, + _from + ); require(_tokenSupplyQty == _value, "INVALID_QTY"); } /** - * @notice After the transfer happens the _tokenSupplyId should be updated in the promise. Escrow funds for the seller's deposits (If in ETH) should be allocated to the new owner as well. - * @param _from prev owner of the _tokenSupplyId - * @param _to nex owner of the _tokenSupplyId - * @param _tokenSupplyId _tokenSupplyId for transfer - * @param _value qty which has been transferred - */ - function _onERC1155Transfer(address _from, address _to, uint256 _tokenSupplyId, uint256 _value) - external - override - onlyTokensContract - { - uint8 paymentType = IVoucherKernel(voucherKernel).getVoucherPaymentMethod(_tokenSupplyId); - - if(paymentType == ETHETH || paymentType == TKNETH) { - uint256 depositSe = IVoucherKernel(voucherKernel).getSellerDeposit(_tokenSupplyId); + * @notice After the transfer happens the _tokenSupplyId should be updated in the promise. Escrow funds for the seller's deposits (If in ETH) should be allocated to the new owner as well. + * @param _from prev owner of the _tokenSupplyId + * @param _to nex owner of the _tokenSupplyId + * @param _tokenSupplyId _tokenSupplyId for transfer + * @param _value qty which has been transferred + */ + function _onERC1155Transfer( + address _from, + address _to, + uint256 _tokenSupplyId, + uint256 _value + ) external override onlyTokensContract { + uint8 paymentType = + IVoucherKernel(voucherKernel).getVoucherPaymentMethod( + _tokenSupplyId + ); + + if (paymentType == ETHETH || paymentType == TKNETH) { + uint256 depositSe = + IVoucherKernel(voucherKernel).getSellerDeposit(_tokenSupplyId); uint256 totalAmount = depositSe.mul(_value); escrow[_from] = escrow[_from].sub(totalAmount); escrow[_to] = escrow[_to].add(totalAmount); } - IVoucherKernel(voucherKernel).setSupplyHolderOnTransfer(_tokenSupplyId, _to); + IVoucherKernel(voucherKernel).setSupplyHolderOnTransfer( + _tokenSupplyId, + _to + ); } // // // // // // // // - // UTILS - // // // // // // // // - + // UTILS + // // // // // // // // + /** * @notice Set the address of the ERC1155ERC721 contract * @param _tokensContractAddress The address of the ERC1155ERC721 contract @@ -946,21 +1336,22 @@ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { tokensContractAddress = _tokensContractAddress; emit LogTokenContractSet(_tokensContractAddress, msg.sender); } - + // // // // // // // // - // GETTERS - // // // // // // // // - + // GETTERS + // // // // // // // // + /** * @notice Get the amount in escrow of an address * @param _account The address of an account to query * @return The balance in escrow */ - function getEscrowAmount(address _account) - public view override + function getEscrowAmount(address _account) + public + view + override returns (uint256) { return escrow[_account]; } - } diff --git a/contracts/ERC1155ERC721.sol b/contracts/ERC1155ERC721.sol index bc89400b..8d93b4cf 100644 --- a/contracts/ERC1155ERC721.sol +++ b/contracts/ERC1155ERC721.sol @@ -15,63 +15,57 @@ import "./IERC1155ERC721.sol"; //preparing for ERC-1066, ERC-1444, EIP-838 /** - * @title Multi-token contract, implementing ERC-1155 and ERC-721 hybrid + * @title Multi-token contract, implementing ERC-1155 and ERC-721 hybrid * Inspired by: https://github.com/pixowl/sandbox-smart-contracts */ -contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { +contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { using SafeMath for uint256; using Address for address; - + //min security - address public owner; //contract owner - address public voucherKernelAddress; //address of the VoucherKernel contract - address public cashier; //Cashier contract - + address public owner; //contract owner + address public voucherKernelAddress; //address of the VoucherKernel contract + address public cashier; //Cashier contract + //standard reqs //ERC-1155 - mapping (uint256 => mapping(address => uint256)) private balances; //balance of token ids of an account - + mapping(uint256 => mapping(address => uint256)) private balances; //balance of token ids of an account + //ERC-721 mapping(address => uint256) private balance721; mapping(uint256 => address) private owners721; mapping(uint256 => address) private operator721; - + //shared storage: ERC-1155 & ERC-721 - mapping (address => mapping(address => bool)) private operatorApprovals; //approval of accounts of an operator + mapping(address => mapping(address => bool)) private operatorApprovals; //approval of accounts of an operator //metadata is shared, too (but ERC-1155 and ERC-721 have different metadata extension reqs) string internal metadataBase; - + //ERC-1155 metadata event: URIs are defined in RFC 3986. The URI MUST point to a JSON file that conforms to the ERC-1155 Metadata URI JSON Schema. //not used ATM //event URI(string _value, uint256 indexed _id); - event LogVoucherKernelSet( - address _newVoucherKernel, - address _triggeredBy - ); + event LogVoucherKernelSet(address _newVoucherKernel, address _triggeredBy); + + event LogCashierSet(address _newCashier, address _triggeredBy); - event LogCashierSet( - address _newCashier, - address _triggeredBy - ); - modifier onlyOwner() { - require(msg.sender == owner, "UNAUTHORIZED_O"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + require(msg.sender == owner, "UNAUTHORIZED_O"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) _; } - + modifier onlyFromVoucherKernel() { - require(voucherKernelAddress != address(0), "UNSPECIFIED_VOUCHERKERNEL"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(msg.sender == voucherKernelAddress, "UNAUTHORIZED_VK"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + require( + voucherKernelAddress != address(0), + "UNSPECIFIED_VOUCHERKERNEL" + ); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require(msg.sender == voucherKernelAddress, "UNAUTHORIZED_VK"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) _; - } + } - constructor() - public - { + constructor() public { owner = msg.sender; } - /** * @notice Transfers amount of _tokenId from-to addresses with safety call. @@ -82,20 +76,20 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenId ID of the token * @param _value Transfer amount * @param _data Additional data forwarded to onERC1155Received if _to is a contract - */ + */ function safeTransferFrom( address _from, address _to, uint256 _tokenId, uint256 _value, bytes calldata _data - ) - external - override - { + ) external override { require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(_from == msg.sender || operatorApprovals[_from][msg.sender] == true, "UNAUTHORIZED_ST"); //hex"10"FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) - + require( + _from == msg.sender || operatorApprovals[_from][msg.sender] == true, + "UNAUTHORIZED_ST" + ); //hex"10"FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + ICashier(cashier)._beforeERC1155Transfer(_from, _tokenId, _value); // SafeMath throws with insufficient funds or if _id is not valid (balance will be 0) @@ -107,10 +101,16 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { emit TransferSingle(msg.sender, _from, _to, _tokenId, _value); //make sure the tx was accepted - in case of a revert below, the event above is reverted, too - _doSafeTransferAcceptanceCheck(msg.sender, _from, _to, _tokenId, _value, _data); - } - - + _doSafeTransferAcceptanceCheck( + msg.sender, + _from, + _to, + _tokenId, + _value, + _data + ); + } + /** * @notice Safely transfers the ownership of a given token ID to another address * If the target address is a contract, it must implement `onERC721Received`, @@ -123,10 +123,11 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _to address to receive the ownership of the given token ID * @param _tokenId uint256 ID of the token to be transferred */ - function safeTransferFrom(address _from, address _to, uint256 _tokenId) - public - override - { + function safeTransferFrom( + address _from, + address _to, + uint256 _tokenId + ) public override { safeTransferFrom(_from, _to, _tokenId, ""); } @@ -140,18 +141,27 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenId uint256 ID of the token to be transferred * @param _data bytes data to send along with a safe transfer check */ - function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory _data) - public - override - { + function safeTransferFrom( + address _from, + address _to, + uint256 _tokenId, + bytes memory _data + ) public override { transferFrom(_from, _to, _tokenId); - + if (_to.isContract()) { - require(ERC721TokenReceiver(_to).onERC721Received(_from, _to, _tokenId, _data) == ERC721TokenReceiver(_to).onERC721Received.selector, "UNSUPPORTED_ERC721_RECEIVED"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) - } - } - - + require( + ERC721TokenReceiver(_to).onERC721Received( + _from, + _to, + _tokenId, + _data + ) == ERC721TokenReceiver(_to).onERC721Received.selector, + "UNSUPPORTED_ERC721_RECEIVED" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + } + } + /** * @notice Transfers the ownership of a given token ID to another address. * Usage of this method is discouraged, use `safeTransferFrom` whenever possible. @@ -161,16 +171,20 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _to address to receive the ownership of the given token ID * @param _tokenId uint256 ID of the token to be transferred */ - function transferFrom(address _from, address _to, uint256 _tokenId) - public - override - { - require(operator721[_tokenId] == msg.sender || ownerOf(_tokenId) == msg.sender, "NOT_OWNER_NOR_APPROVED"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + function transferFrom( + address _from, + address _to, + uint256 _tokenId + ) public override { + require( + operator721[_tokenId] == msg.sender || + ownerOf(_tokenId) == msg.sender, + "NOT_OWNER_NOR_APPROVED" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) _transferFrom(_from, _to, _tokenId); - } - - + } + /** * @notice Internal function to transfer ownership of a given token ID to another address. * As opposed to transferFrom, this imposes no restrictions on msg.sender. @@ -179,25 +193,26 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _to address to receive the ownership of the given token ID * @param _tokenId uint256 ID of the token to be transferred */ - function _transferFrom(address _from, address _to, uint256 _tokenId) - internal - { - require(ownerOf(_tokenId) == _from, "UNAUTHORIZED_T"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) - require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + function _transferFrom( + address _from, + address _to, + uint256 _tokenId + ) internal { + require(ownerOf(_tokenId) == _from, "UNAUTHORIZED_T"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) operator721[_tokenId] = address(0); balance721[_from]--; balance721[_to]++; - + owners721[_tokenId] = _to; ICashier(cashier)._onERC721Transfer(_from, _to, _tokenId); emit Transfer(_from, _to, _tokenId); - } - - + } + /** * @notice Approves another address to transfer the given token ID * The zero address indicates there is no approved address. @@ -207,22 +222,21 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _to address to be approved for the given token ID * @param _tokenId uint256 ID of the token to be approved */ - function approve(address _to, uint256 _tokenId) - public - override - { + function approve(address _to, uint256 _tokenId) public override { address tokenOwner = ownerOf(_tokenId); require(_to != tokenOwner, "REDUNDANT_CALL"); //hex"18" FISSION.code(FISSION.Category.Permission, FISSION.Status.NotApplicatableToCurrentState) - require(msg.sender == tokenOwner || operatorApprovals[tokenOwner][msg.sender],// isApprovedForAll(owner, msg.sender), - "UNAUTHORIZED_A"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) - //"ERC721: approve caller is not owner nor approved for all" + require( + msg.sender == tokenOwner || + operatorApprovals[tokenOwner][msg.sender], // isApprovedForAll(owner, msg.sender), + "UNAUTHORIZED_A" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + //"ERC721: approve caller is not owner nor approved for all" operator721[_tokenId] = _to; emit Approval(tokenOwner, _to, _tokenId); - } - - + } + /** * @notice Gets the approved address for a token ID, or zero if no address set * Reverts if the token ID does not exist. @@ -230,18 +244,20 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenId uint256 ID of the token to query the approval of * @return address currently approved for the given token ID */ - function getApproved(uint256 _tokenId) - public + function getApproved(uint256 _tokenId) + public view override - returns (address) + returns (address) { - require(owners721[_tokenId] != address(0), "ERC721: approved query for nonexistent token"); + require( + owners721[_tokenId] != address(0), + "ERC721: approved query for nonexistent token" + ); return operator721[_tokenId]; - } - - + } + /** @notice Transfers amount of _tokenId from-to addresses with safety call. If _to is a smart contract, will call onERC1155BatchReceived @@ -258,35 +274,40 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { uint256[] calldata _tokenIds, uint256[] calldata _values, bytes calldata _data - ) - external - override - { - require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(_tokenIds.length == _values.length, "MISMATCHED_ARRAY_LENGTHS"); //hex"28" FISSION.code(FISSION.Category.Find, FISSION.Status.Duplicate_Conflict_Collision) - require(_from == msg.sender || operatorApprovals[_from][msg.sender] == true, "UNAUTHORIZED_SB"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + ) external override { + require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require(_tokenIds.length == _values.length, "MISMATCHED_ARRAY_LENGTHS"); //hex"28" FISSION.code(FISSION.Category.Find, FISSION.Status.Duplicate_Conflict_Collision) + require( + _from == msg.sender || operatorApprovals[_from][msg.sender] == true, + "UNAUTHORIZED_SB" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) for (uint256 i = 0; i < _tokenIds.length; ++i) { uint256 tokenId = _tokenIds[i]; uint256 value = _values[i]; ICashier(cashier)._beforeERC1155Transfer(_from, tokenId, value); - + // SafeMath throws with insufficient funds or if _id is not valid (balance will be 0) balances[tokenId][_from] = balances[tokenId][_from].sub(value); - balances[tokenId][_to] = value.add(balances[tokenId][_to]); + balances[tokenId][_to] = value.add(balances[tokenId][_to]); ICashier(cashier)._onERC1155Transfer(_from, _to, tokenId, value); - } emit TransferBatch(msg.sender, _from, _to, _tokenIds, _values); //make sure the tx was accepted - in case of a revert below, the event above is reverted, too - _doSafeBatchTransferAcceptanceCheck(msg.sender, _from, _to, _tokenIds, _values, _data); - } - - + _doSafeBatchTransferAcceptanceCheck( + msg.sender, + _from, + _to, + _tokenIds, + _values, + _data + ); + } + /** * @notice Check successful transfer if recipient is a contract * @dev ERC-1155 @@ -304,16 +325,21 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { uint256 _tokenId, uint256 _value, bytes memory _data - ) - internal - { - if(_to.isContract()) { - require(ERC1155TokenReceiver(_to).onERC1155Received(_operator, _from, _tokenId, _value, _data) == - ERC1155TokenReceiver(_to).onERC1155Received.selector, "NOT_SUPPORTED"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + ) internal { + if (_to.isContract()) { + require( + ERC1155TokenReceiver(_to).onERC1155Received( + _operator, + _from, + _tokenId, + _value, + _data + ) == ERC1155TokenReceiver(_to).onERC1155Received.selector, + "NOT_SUPPORTED" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) } } - /** * @notice Check successful transfer if recipient is a contract * @dev ERC-1155 @@ -323,7 +349,7 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenIds Array of IDs of tokens * @param _values Array of values transferred * @param _data Optional data - */ + */ function _doSafeBatchTransferAcceptanceCheck( address _operator, address _from, @@ -331,16 +357,21 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { uint256[] memory _tokenIds, uint256[] memory _values, bytes memory _data - ) - internal - { - if(_to.isContract()) { - require(ERC1155TokenReceiver(_to).onERC1155BatchReceived(_operator, _from, _tokenIds, _values, _data) == - ERC1155TokenReceiver(_to).onERC1155BatchReceived.selector, "NOT_SUPPORTED"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + ) internal { + if (_to.isContract()) { + require( + ERC1155TokenReceiver(_to).onERC1155BatchReceived( + _operator, + _from, + _tokenIds, + _values, + _data + ) == ERC1155TokenReceiver(_to).onERC1155BatchReceived.selector, + "NOT_SUPPORTED" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) } - } - - + } + /** @notice Get the balance of tokens of an account @dev ERC-1155 @@ -348,31 +379,24 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { @param _tokenId ID of the token @return balance */ - function balanceOf(address _account, uint256 _tokenId) - external + function balanceOf(address _account, uint256 _tokenId) + external view override - returns (uint256) + returns (uint256) { return balances[_tokenId][_account]; - } - - + } + /// @notice Count all NFTs assigned to an owner /// @dev ERC-721 /// @param _owner An address for whom to query the balance /// @return The number of NFTs owned by `_owner`, possibly zero - function balanceOf(address _owner) - public - view - override - returns (uint256) - { - require(_owner != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + function balanceOf(address _owner) public view override returns (uint256) { + require(_owner != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) return balance721[_owner]; } - /** * @notice Gets the owner of the specified token ID. @@ -380,20 +404,13 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenId uint256 ID of the token to query the owner of * @return address currently marked as the owner of the given token ID */ - function ownerOf(uint256 _tokenId) - public - view - override - returns (address) - { + function ownerOf(uint256 _tokenId) public view override returns (address) { address tokenOwner = owners721[_tokenId]; - require(tokenOwner != address(0), "UNDEFINED_OWNER"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require(tokenOwner != address(0), "UNDEFINED_OWNER"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) return tokenOwner; - } - - - + } + /** @notice Get the balance of account-token pairs. @dev ERC-1155 @@ -404,13 +421,11 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { function balanceOfBatch( address[] calldata _accounts, uint256[] calldata _tokenIds - ) - external - view - override - returns (uint256[] memory) - { - require(_accounts.length == _tokenIds.length, "MISMATCHED_ARRAY_LENGTHS"); //hex"28" FISSION.code(FISSION.Category.Find, FISSION.Status.Duplicate_Conflict_Collision) + ) external view override returns (uint256[] memory) { + require( + _accounts.length == _tokenIds.length, + "MISMATCHED_ARRAY_LENGTHS" + ); //hex"28" FISSION.code(FISSION.Category.Find, FISSION.Status.Duplicate_Conflict_Collision) uint256[] memory batchBalances = new uint256[](_accounts.length); for (uint256 i = 0; i < _accounts.length; ++i) { @@ -418,9 +433,8 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { } return batchBalances; - } - - + } + /** * @notice Approves or unapproves the operator. * will revert if the caller attempts to approve itself as it is redundant @@ -428,16 +442,15 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _operator to (un)approve * @param _approve flag to set or unset */ - function setApprovalForAll(address _operator, bool _approve) + function setApprovalForAll(address _operator, bool _approve) external override(IERC1155, IERC721) { require(msg.sender != _operator, "REDUNDANT_CALL"); //hex"18" FISSION.code(FISSION.Category.Permission, FISSION.Status.NotApplicatableToCurrentState) operatorApprovals[msg.sender][_operator] = _approve; emit ApprovalForAll(msg.sender, _operator, _approve); - } - - + } + /** @notice Gets approval status of an operator for a given account. @dev ERC-1155 & ERC-721 @@ -445,27 +458,27 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { @param _operator operator to check @return True if the operator is approved, false if not */ - function isApprovedForAll(address _account, address _operator) - public - view + function isApprovedForAll(address _account, address _operator) + public + view override(IERC1155, IERC721) - returns (bool) + returns (bool) { return operatorApprovals[_account][_operator]; - } - + } /** * @notice Returns true if this contract implements the interface defined by _interfaceId_. * This function call must use less than 30 000 gas. ATM not enforced. */ - function supportsInterface(bytes4 _interfaceId) - external - view + function supportsInterface(bytes4 _interfaceId) + external + view override returns (bool) { - return //check matching against ERC-165 identifiers + return + //check matching against ERC-165 identifiers _interfaceId == 0x01ffc9a7 || //ERC-165 _interfaceId == 0xd9b67a26 || //ERC-1155 _interfaceId == 0x80ac58cd || //ERC-721 @@ -474,8 +487,8 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { } // // // // // // // // - // STANDARD - UTILS - // // // // // // // // + // STANDARD - UTILS + // // // // // // // // /** * @notice Mint an amount of a desired token * Currently no restrictions as to who is allowed to mint - so, it is public. @@ -485,14 +498,15 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _value Amount of the token to be minted * @param _data Additional data forwarded to onERC1155BatchReceived if _to is a contract */ - function mint(address _to, uint256 _tokenId, uint256 _value, bytes memory _data) - public - override - onlyFromVoucherKernel - { + function mint( + address _to, + uint256 _tokenId, + uint256 _value, + bytes memory _data + ) public override onlyFromVoucherKernel { _mint(_to, _tokenId, _value, _data); - } - + } + /** * @notice Internal function to mint an amount of a desired token * @dev ERC-1155 @@ -501,18 +515,27 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _value Amount of the token to be minted * @param _data Additional data forwarded to onERC1155BatchReceived if _to is a contract */ - function _mint(address _to, uint256 _tokenId, uint256 _value, bytes memory _data) - internal - { - require(_to != address(0), "UNSPECIFIED_ADDRESS"); //FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - + function _mint( + address _to, + uint256 _tokenId, + uint256 _value, + bytes memory _data + ) internal { + require(_to != address(0), "UNSPECIFIED_ADDRESS"); //FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + balances[_tokenId][_to] = balances[_tokenId][_to].add(_value); emit TransferSingle(msg.sender, address(0), _to, _tokenId, _value); - _doSafeTransferAcceptanceCheck(msg.sender, address(0), _to, _tokenId, _value, _data); - } - - + _doSafeTransferAcceptanceCheck( + msg.sender, + address(0), + _to, + _tokenId, + _value, + _data + ); + } + /** * @notice Function to mint tokens. * @dev ERC-721 @@ -520,17 +543,16 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param tokenId The token id to mint. * @return A boolean that indicates if the operation was successful. */ - function mint(address to, uint256 tokenId) + function mint(address to, uint256 tokenId) public override onlyFromVoucherKernel - returns (bool) + returns (bool) { _mint(to, tokenId); return true; } - - + /** * @notice Internal function to mint a new token. * Reverts if the given token ID already exists. @@ -538,19 +560,19 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _to The address that will own the minted token * @param _tokenId uint256 ID of the token to be minted */ - function _mint(address _to, uint256 _tokenId) - internal - { - require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(owners721[_tokenId] == address(0), "ERC721: token already minted"); + function _mint(address _to, uint256 _tokenId) internal { + require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require( + owners721[_tokenId] == address(0), + "ERC721: token already minted" + ); owners721[_tokenId] = _to; balance721[_to]++; emit Transfer(address(0), _to, _tokenId); } - - + /** * @notice Batch minting of tokens * Currently no restrictions as to who is allowed to mint - so, it is public. @@ -560,15 +582,17 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _values Amounts of the tokens to be minted * @param _data Additional data forwarded to onERC1155BatchReceived if _to is a contract */ - function mintBatch(address _to, uint256[] memory _tokenIds, uint256[] memory _values, bytes memory _data) - public - onlyFromVoucherKernel - { + function mintBatch( + address _to, + uint256[] memory _tokenIds, + uint256[] memory _values, + bytes memory _data + ) public onlyFromVoucherKernel { //require approved minter - + _mintBatch(_to, _tokenIds, _values, _data); - } - + } + /** * @notice Internal function for batch minting of tokens\ * @dev ERC-1155 @@ -577,22 +601,33 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _values Amounts of the tokens to be minted * @param _data Additional data forwarded to onERC1155BatchReceived if _to is a contract */ - function _mintBatch(address _to, uint256[] memory _tokenIds, uint256[] memory _values, bytes memory _data) - internal - { - require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + function _mintBatch( + address _to, + uint256[] memory _tokenIds, + uint256[] memory _values, + bytes memory _data + ) internal { + require(_to != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) require(_tokenIds.length == _values.length, "MISMATCHED_ARRAY_LENGTHS"); //hex"28" FISSION.code(FISSION.Category.Find, FISSION.Status.Duplicate_Conflict_Collision) - for(uint i = 0; i < _tokenIds.length; i++) { - balances[_tokenIds[i]][_to] = _values[i].add(balances[_tokenIds[i]][_to]); + for (uint256 i = 0; i < _tokenIds.length; i++) { + balances[_tokenIds[i]][_to] = _values[i].add( + balances[_tokenIds[i]][_to] + ); } emit TransferBatch(msg.sender, address(0), _to, _tokenIds, _values); - _doSafeBatchTransferAcceptanceCheck(msg.sender, address(0), _to, _tokenIds, _values, _data); - } - - + _doSafeBatchTransferAcceptanceCheck( + msg.sender, + address(0), + _to, + _tokenIds, + _values, + _data + ); + } + /** * @notice Burn an amount of tokens with the given ID * @dev ERC-1155 @@ -600,14 +635,14 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenId ID of the token * @param _value Amount of the token */ - function burn(address _account, uint256 _tokenId, uint256 _value) - public - override - onlyFromVoucherKernel - { + function burn( + address _account, + uint256 _tokenId, + uint256 _value + ) public override onlyFromVoucherKernel { _burn(_account, _tokenId, _value); } - + /** * @notice Burn an amount of tokens with the given ID * @dev ERC-1155 @@ -615,16 +650,18 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenId ID of the token * @param _value Amount of the token */ - function _burn(address _account, uint256 _tokenId, uint256 _value) internal { - require(_account != address(0), "UNSPECIFIED_ADDRESS"); //"UNSPECIFIED_ADDRESS" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + function _burn( + address _account, + uint256 _tokenId, + uint256 _value + ) internal { + require(_account != address(0), "UNSPECIFIED_ADDRESS"); //"UNSPECIFIED_ADDRESS" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) balances[_tokenId][_account] = balances[_tokenId][_account].sub(_value); emit TransferSingle(msg.sender, _account, address(0), _tokenId, _value); } - - - /* Burning ERC-721 is not allowed, as a voucher (being an ERC-721 token) has a final state and shouldn't be destructed. */ - + + /* Burning ERC-721 is not allowed, as a voucher (being an ERC-721 token) has a final state and shouldn't be destructed. */ /** * @notice Batch burn an amounts of tokens @@ -633,13 +670,14 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenIds IDs of the tokens * @param _values Amounts of the tokens */ - function burnBatch(address _account, uint256[] memory _tokenIds, uint256[] memory _values) - public - onlyFromVoucherKernel - { + function burnBatch( + address _account, + uint256[] memory _tokenIds, + uint256[] memory _values + ) public onlyFromVoucherKernel { _burnBatch(_account, _tokenIds, _values); - } - + } + /** * @notice Internal function to batch burn an amounts of tokens * @dev ERC-1155 @@ -647,70 +685,67 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @param _tokenIds IDs of the tokens * @param _values Amounts of the tokens */ - function _burnBatch(address _account, uint256[] memory _tokenIds, uint256[] memory _values) - internal - { + function _burnBatch( + address _account, + uint256[] memory _tokenIds, + uint256[] memory _values + ) internal { require(_account != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) require(_tokenIds.length == _values.length, "MISMATCHED_ARRAY_LENGTHS"); //hex"28" FISSION.code(FISSION.Category.Find, FISSION.Status.Duplicate_Conflict_Collision) - for(uint i = 0; i < _tokenIds.length; i++) { - balances[_tokenIds[i]][_account] = balances[_tokenIds[i]][_account].sub(_values[i]); + for (uint256 i = 0; i < _tokenIds.length; i++) { + balances[_tokenIds[i]][_account] = balances[_tokenIds[i]][_account] + .sub(_values[i]); } - emit TransferBatch(msg.sender, _account, address(0), _tokenIds, _values); + emit TransferBatch( + msg.sender, + _account, + address(0), + _tokenIds, + _values + ); } - // // // // // // // // - // METADATA EXTENSIONS - // // // // // // // // - + // METADATA EXTENSIONS + // // // // // // // // + /** * @notice Setting the URL prefix for tokens metadata * @param _newBase New prefix to be used */ - function _setMetadataBase(string memory _newBase) - public - onlyOwner - { + function _setMetadataBase(string memory _newBase) public onlyOwner { metadataBase = _newBase; } - - + /** * @notice A distinct Uniform Resource Identifier (URI) for a given token. * @dev ERC-1155 - * URIs are defined in RFC 3986. The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". + * URIs are defined in RFC 3986. The URI MUST point to a JSON file that conforms to the "ERC-1155 Metadata URI JSON Schema". * @param _tokenId The ID of the token * @return Full URI string for metadata of the _tokenId - */ - function uri(uint256 _tokenId) - external view - returns (string memory) - { - return string(abi.encodePacked(metadataBase, _uint2str(_tokenId), ".json")); + */ + function uri(uint256 _tokenId) external view returns (string memory) { + return + string( + abi.encodePacked(metadataBase, _uint2str(_tokenId), ".json") + ); } - /** * @notice A descriptive name for a collection of NFTs in this contract * @dev ERC-721 - */ - function name() - external pure - returns (string memory _name) - { + */ + function name() external pure returns (string memory _name) { return "Boson Smart Voucher"; } /** * @notice An abbreviated name for NFTs in this contract * @dev ERC-721 - */ - function symbol() - external pure - returns (string memory _symbol) - { + */ + function symbol() external pure returns (string memory _symbol) { return "BSV"; } @@ -719,20 +754,19 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @dev ERC-721 * Throws if `_tokenId` is not a valid NFT. URIs are defined in RFC 3986. The URI may point to a JSON file that conforms to the "ERC721 Metadata JSON Schema". * @param _tokenId ID of the token - */ - function tokenURI(uint256 _tokenId) - external view - returns (string memory) - { + */ + function tokenURI(uint256 _tokenId) external view returns (string memory) { require(owners721[_tokenId] != address(0), "INVALID_ID"); - return string(abi.encodePacked(metadataBase, _uint2str(_tokenId), ".json")); + return + string( + abi.encodePacked(metadataBase, _uint2str(_tokenId), ".json") + ); } - - + + // // // // // // // // + // UTILS // // // // // // // // - // UTILS - // // // // // // // // - + /** * @notice Set the address of the VoucherKernel contract * @param _voucherKernelAddress The address of the Cashier contract @@ -741,10 +775,10 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { external onlyOwner { - require(_voucherKernelAddress != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - + require(_voucherKernelAddress != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + voucherKernelAddress = _voucherKernelAddress; - + emit LogVoucherKernelSet(_voucherKernelAddress, msg.sender); } @@ -752,46 +786,41 @@ contract ERC1155ERC721 is IERC1155, IERC721, IERC1155ERC721 { * @notice Set the address of the Cashier contract * @param _cashier The Cashier contract */ - function setCashierContract(address _cashier) - external - onlyOwner - { + function setCashierContract(address _cashier) external onlyOwner { cashier = _cashier; emit LogCashierSet(_cashier, msg.sender); - } - function getCashierAddress() public view returns (address){ + function getCashierAddress() public view returns (address) { address(cashier); } - - + /** * @notice Convert UINT to string * Thank you, Oraclize (aka Provable)! * https://github.com/provable-things/ethereum-api/blob/master/provableAPI_0.5.sol * @param _i uint parameter */ - function _uint2str(uint256 _i) - internal pure + function _uint2str(uint256 _i) + internal + pure returns (string memory _uintAsString) { if (_i == 0) { return "0"; } - uint j = _i; - uint len; + uint256 j = _i; + uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); - uint k = len - 1; + uint256 k = len - 1; while (_i != 0) { - bstr[k--] = byte(uint8(48 + _i % 10)); + bstr[k--] = bytes1(uint8(48 + (_i % 10))); _i /= 10; } - return string(bstr); + return string(bstr); } - -} \ No newline at end of file +} diff --git a/contracts/ERC20WithPermit.sol b/contracts/ERC20WithPermit.sol index e3736398..4c2e2b91 100644 --- a/contracts/ERC20WithPermit.sol +++ b/contracts/ERC20WithPermit.sol @@ -20,7 +20,8 @@ contract ERC20WithPermit is IERC20WithPermit { // solhint-disable-next-line var-name-mixedcase bytes32 public override DOMAIN_SEPARATOR; // representation of keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); - bytes32 public override constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; + bytes32 public constant override PERMIT_TYPEHASH = + 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9; mapping(address => uint256) public override nonces; event Approval( @@ -126,22 +127,23 @@ contract ERC20WithPermit is IERC20WithPermit { ) external override { require(deadline >= block.timestamp, "ERC20WithPermit: EXPIRED"); - bytes32 digest = keccak256( - abi.encodePacked( - "\x19\x01", - DOMAIN_SEPARATOR, - keccak256( - abi.encode( - PERMIT_TYPEHASH, - owner, - spender, - value, - nonces[owner]++, - deadline + bytes32 digest = + keccak256( + abi.encodePacked( + "\x19\x01", + DOMAIN_SEPARATOR, + keccak256( + abi.encode( + PERMIT_TYPEHASH, + owner, + spender, + value, + nonces[owner]++, + deadline + ) ) ) - ) - ); + ); address recoveredAddress = ecrecover(digest, v, r, s); require( diff --git a/contracts/FundLimitsOracle.sol b/contracts/FundLimitsOracle.sol index 602cb4ae..bee1e984 100644 --- a/contracts/FundLimitsOracle.sol +++ b/contracts/FundLimitsOracle.sol @@ -4,19 +4,12 @@ pragma solidity >=0.6.6 <0.7.0; import "@openzeppelin/contracts/access/Ownable.sol"; contract FundLimitsOracle is Ownable { - uint256 private ethLimit; - mapping (address => uint256) private tokenLimits; + mapping(address => uint256) private tokenLimits; - event LogETHLimitChanged( - uint256 _newLimit, - address _triggeredBy - ); + event LogETHLimitChanged(uint256 _newLimit, address _triggeredBy); - event LogTokenLimitChanged( - uint256 _newLimit, - address _triggeredBy - ); + event LogTokenLimitChanged(uint256 _newLimit, address _triggeredBy); modifier notZeroAddress(address tokenAddress) { require(tokenAddress != address(0), "INVALID_TOKEN_ADDRESS"); @@ -27,10 +20,7 @@ contract FundLimitsOracle is Ownable { ethLimit = 1 ether; } - function setETHLimit(uint256 _newLimit) - external - onlyOwner - { + function setETHLimit(uint256 _newLimit) external onlyOwner { ethLimit = _newLimit; emit LogETHLimitChanged(_newLimit, owner()); } @@ -40,8 +30,8 @@ contract FundLimitsOracle is Ownable { @param _tokenAddress Address of the token which will be update. @param _newLimit New limit which will be set. It must comply to the decimals of the token, so the limit is set in the correct decimals. */ - function setTokenLimit(address _tokenAddress, uint256 _newLimit) - external + function setTokenLimit(address _tokenAddress, uint256 _newLimit) + external onlyOwner notZeroAddress(_tokenAddress) { @@ -49,12 +39,15 @@ contract FundLimitsOracle is Ownable { emit LogTokenLimitChanged(_newLimit, owner()); } - function getETHLimit() external view returns(uint256) { + function getETHLimit() external view returns (uint256) { return ethLimit; } - function getTokenLimit(address _tokenAddress) external view returns(uint256) { + function getTokenLimit(address _tokenAddress) + external + view + returns (uint256) + { return tokenLimits[_tokenAddress]; } - -} \ No newline at end of file +} diff --git a/contracts/ICashier.sol b/contracts/ICashier.sol index e7b8d3b2..a5050f6c 100644 --- a/contracts/ICashier.sol +++ b/contracts/ICashier.sol @@ -3,22 +3,20 @@ pragma solidity >=0.6.6 <0.7.0; interface ICashier { - /** - * @notice Pause the Cashier && the Voucher Kernel contracts in case of emergency. - * All functions related to creating new batch, requestVoucher or withdraw will be paused, hence cannot be executed. - * There is special function for withdrawing funds if contract is paused. - */ + * @notice Pause the Cashier && the Voucher Kernel contracts in case of emergency. + * All functions related to creating new batch, requestVoucher or withdraw will be paused, hence cannot be executed. + * There is special function for withdrawing funds if contract is paused. + */ function pause() external; - + /** - * @notice Unpause the Cashier && the Voucher Kernel contracts. - * All functions related to creating new batch, requestVoucher or withdraw will be unpaused. - */ + * @notice Unpause the Cashier && the Voucher Kernel contracts. + * All functions related to creating new batch, requestVoucher or withdraw will be unpaused. + */ function unpause() external; - - /** + /** * @notice Issuer/Seller offers promises as supply tokens and needs to escrow the deposit @param metadata metadata which is required for creation of a voucher Metadata array is used as in some scenarios we need several more params, as we need to recover @@ -45,9 +43,7 @@ interface ICashier { bytes32 r, bytes32 s, uint256[] calldata metadata - ) - external - payable; + ) external payable; function requestCreateOrderETHTKNWithPermit( address _tokenDepositAddress, @@ -57,16 +53,12 @@ interface ICashier { bytes32 r, bytes32 s, uint256[] calldata metadata - ) - external - payable; + ) external payable; function requestCreateOrderTKNETH( address _tokenPriceAddress, uint256[] calldata metadata - ) - external - payable; + ) external payable; /** * @notice Consumer requests/buys a voucher by filling an order and receiving a Voucher Token in return @@ -78,45 +70,47 @@ interface ICashier { payable; function requestVoucherTKNTKNWithPermit( - uint256 _tokenIdSupply, + uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, uint256 deadline, - uint8 vPrice, bytes32 rPrice, bytes32 sPrice, // tokenPrice - uint8 vDeposit, bytes32 rDeposit, bytes32 sDeposit // tokenDeposits - ) - external - payable; + uint8 vPrice, + bytes32 rPrice, + bytes32 sPrice, // tokenPrice + uint8 vDeposit, + bytes32 rDeposit, + bytes32 sDeposit // tokenDeposits + ) external payable; function requestVoucherTKNTKNSameWithPermit( - uint256 _tokenIdSupply, + uint256 _tokenIdSupply, address _issuer, uint256 _tokensSent, uint256 deadline, - uint8 v, bytes32 r, bytes32 s - ) - external; - + uint8 v, + bytes32 r, + bytes32 s + ) external; function requestVoucherETHTKNWithPermit( - uint256 _tokenIdSupply, + uint256 _tokenIdSupply, address _issuer, uint256 _tokensDeposit, uint256 deadline, - uint8 v, bytes32 r, bytes32 s - ) - external - payable; + uint8 v, + bytes32 r, + bytes32 s + ) external payable; function requestVoucherTKNETHWithPermit( - uint256 _tokenIdSupply, + uint256 _tokenIdSupply, address _issuer, uint256 _tokensPrice, uint256 deadline, - uint8 v, bytes32 r, bytes32 s - ) - external - payable; + uint8 v, + bytes32 r, + bytes32 s + ) external payable; /** * @notice Trigger withdrawals of what funds are releasable @@ -134,25 +128,22 @@ interface ICashier { */ function withdrawWhenPaused(uint256 _tokenIdVoucher) external; - /** - * @notice Seller triggers withdrawals of remaining deposits for a given supply, in case the contracts are paused. - * @param _tokenIdSupply an ID of a supply token (ERC-1155) which will be burned and deposits will be returned for - */ + * @notice Seller triggers withdrawals of remaining deposits for a given supply, in case the contracts are paused. + * @param _tokenIdSupply an ID of a supply token (ERC-1155) which will be burned and deposits will be returned for + */ function withdrawDeposits(uint256 _tokenIdSupply) external; - /** * @notice Trigger withdrawals of pooled funds - */ + */ function withdrawPool() external; /** * @notice Set the address of the ERC1155ERC721 contract * @param _tokensContractAddress The address of the ERC1155ERC721 contract */ - function setTokenContractAddress(address _tokensContractAddress) - external; + function setTokenContractAddress(address _tokensContractAddress) external; /** * @notice Get the amount in escrow of an address @@ -162,28 +153,40 @@ interface ICashier { function getEscrowAmount(address _account) external view returns (uint256); /** - * @notice Hook which will be triggered when a _tokenIdVoucher will be transferred. Escrow funds should be allocated to the new owner. - * @param _from prev owner of the _tokenIdVoucher - * @param _to next owner of the _tokenIdVoucher - * @param _tokenIdVoucher _tokenIdVoucher that has been transferred - */ - function _onERC721Transfer(address _from, address _to, uint256 _tokenIdVoucher) external; + * @notice Hook which will be triggered when a _tokenIdVoucher will be transferred. Escrow funds should be allocated to the new owner. + * @param _from prev owner of the _tokenIdVoucher + * @param _to next owner of the _tokenIdVoucher + * @param _tokenIdVoucher _tokenIdVoucher that has been transferred + */ + function _onERC721Transfer( + address _from, + address _to, + uint256 _tokenIdVoucher + ) external; /** - * @notice Pre-validation when a transfer from the the Tokens contract is triggered. Only the whole supply is allowed for transfer, otherwise reverts. - * @param _from owner of the _tokenSupplyId - * @param _tokenSupplyId _tokenSupplyId which will be validated - * @param _value qty which is desired to be transferred - */ - function _beforeERC1155Transfer(address _from, uint256 _tokenSupplyId, uint256 _value) external view; + * @notice Pre-validation when a transfer from the the Tokens contract is triggered. Only the whole supply is allowed for transfer, otherwise reverts. + * @param _from owner of the _tokenSupplyId + * @param _tokenSupplyId _tokenSupplyId which will be validated + * @param _value qty which is desired to be transferred + */ + function _beforeERC1155Transfer( + address _from, + uint256 _tokenSupplyId, + uint256 _value + ) external view; /** - * @notice After the transfer happens the _tokenSupplyId should be updated in the promise. Escrow funds for the deposits (If in ETH) should be allocated to the new owner as well. - * @param _from prev owner of the _tokenSupplyId - * @param _to nex owner of the _tokenSupplyId - * @param _tokenSupplyId _tokenSupplyId for transfer - * @param _value qty which has been transferred - */ - function _onERC1155Transfer(address _from, address _to, uint256 _tokenSupplyId, uint256 _value) external; - -} \ No newline at end of file + * @notice After the transfer happens the _tokenSupplyId should be updated in the promise. Escrow funds for the deposits (If in ETH) should be allocated to the new owner as well. + * @param _from prev owner of the _tokenSupplyId + * @param _to nex owner of the _tokenSupplyId + * @param _tokenSupplyId _tokenSupplyId for transfer + * @param _value qty which has been transferred + */ + function _onERC1155Transfer( + address _from, + address _to, + uint256 _tokenSupplyId, + uint256 _value + ) external; +} diff --git a/contracts/IERC1155.sol b/contracts/IERC1155.sol index dc516d13..a717ca29 100644 --- a/contracts/IERC1155.sol +++ b/contracts/IERC1155.sol @@ -7,7 +7,8 @@ pragma solidity >=0.6.6 <0.7.0; @dev See https://eips.ethereum.org/EIPS/eip-1155 Note: The ERC-165 identifier for this interface is 0xd9b67a26. */ -interface IERC1155 /* is IERC165 */ { +/* is IERC165 */ +interface IERC1155 { /** @dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). The `_operator` argument MUST be the address of an account/contract that is approved to make the transfer (SHOULD be msg.sender). @@ -18,7 +19,13 @@ interface IERC1155 /* is IERC165 */ { When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). */ - event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _value); + event TransferSingle( + address indexed _operator, + address indexed _from, + address indexed _to, + uint256 _id, + uint256 _value + ); /** @dev Either `TransferSingle` or `TransferBatch` MUST emit when tokens are transferred, including zero value transfers as well as minting or burning (see "Safe Transfer Rules" section of the standard). @@ -30,12 +37,22 @@ interface IERC1155 /* is IERC165 */ { When minting/creating tokens, the `_from` argument MUST be set to `0x0` (i.e. zero address). When burning/destroying tokens, the `_to` argument MUST be set to `0x0` (i.e. zero address). */ - event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _values); + event TransferBatch( + address indexed _operator, + address indexed _from, + address indexed _to, + uint256[] _ids, + uint256[] _values + ); /** @dev MUST emit when approval for a second party/operator address to manage all tokens for an owner address is enabled or disabled (absence of an event assumes disabled). */ - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + event ApprovalForAll( + address indexed _owner, + address indexed _operator, + bool _approved + ); /** @dev MUST emit when the URI is updated for a token ID. @@ -58,7 +75,13 @@ interface IERC1155 /* is IERC165 */ { @param _value Transfer amount @param _data Additional data with no specified format, MUST be sent unaltered in call to `onERC1155Received` on `_to` */ - function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _value, bytes calldata _data) external; + function safeTransferFrom( + address _from, + address _to, + uint256 _id, + uint256 _value, + bytes calldata _data + ) external; /** @notice Transfers `_values` amount(s) of `_ids` from the `_from` address to the `_to` address specified (with safety call). @@ -76,7 +99,13 @@ interface IERC1155 /* is IERC165 */ { @param _values Transfer amounts per token type (order and length must match _ids array) @param _data Additional data with no specified format, MUST be sent unaltered in call to the `ERC1155TokenReceiver` hook(s) on `_to` */ - function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external; + function safeBatchTransferFrom( + address _from, + address _to, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external; /** @notice Get the balance of an account's tokens. @@ -84,7 +113,10 @@ interface IERC1155 /* is IERC165 */ { @param _id ID of the token @return The _owner's balance of the token type requested */ - function balanceOf(address _owner, uint256 _id) external view returns (uint256); + function balanceOf(address _owner, uint256 _id) + external + view + returns (uint256); /** @notice Get the balance of multiple account/token pairs @@ -92,7 +124,10 @@ interface IERC1155 /* is IERC165 */ { @param _ids ID of the tokens @return The _owner's balance of the token types requested (i.e. balance for each (owner, id) pair) */ - function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory); + function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) + external + view + returns (uint256[] memory); /** @notice Enable or disable approval for a third party ("operator") to manage all of the caller's tokens. @@ -108,5 +143,8 @@ interface IERC1155 /* is IERC165 */ { @param _operator Address of authorized operator @return True if the operator is approved, false if not */ - function isApprovedForAll(address _owner, address _operator) external view returns (bool); -} \ No newline at end of file + function isApprovedForAll(address _owner, address _operator) + external + view + returns (bool); +} diff --git a/contracts/IERC1155ERC721.sol b/contracts/IERC1155ERC721.sol index 3e18aa29..f86cb879 100644 --- a/contracts/IERC1155ERC721.sol +++ b/contracts/IERC1155ERC721.sol @@ -3,7 +3,6 @@ pragma solidity >=0.6.6 <0.7.0; interface IERC1155ERC721 { - /** * @notice Mint an amount of a desired token * Currently no restrictions as to who is allowed to mint - so, it is external. @@ -13,8 +12,13 @@ interface IERC1155ERC721 { * @param _value Amount of the token to be minted * @param _data Additional data forwarded to onERC1155BatchReceived if _to is a contract */ - function mint(address _to, uint256 _tokenId, uint256 _value, bytes calldata _data) external; - + function mint( + address _to, + uint256 _tokenId, + uint256 _value, + bytes calldata _data + ) external; + /** * @notice Burn an amount of tokens with the given ID * @dev ERC-1155 @@ -22,7 +26,11 @@ interface IERC1155ERC721 { * @param _tokenId ID of the token * @param _value Amount of the token */ - function burn(address _account, uint256 _tokenId, uint256 _value) external; + function burn( + address _account, + uint256 _tokenId, + uint256 _value + ) external; /** * @notice Function to mint tokens. @@ -32,5 +40,4 @@ interface IERC1155ERC721 { * @return A boolean that indicates if the operation was successful. */ function mint(address to, uint256 tokenId) external returns (bool); - -} \ No newline at end of file +} diff --git a/contracts/IERC1155TokenReceiver.sol b/contracts/IERC1155TokenReceiver.sol index 0c0b9bad..deec6d7f 100644 --- a/contracts/IERC1155TokenReceiver.sol +++ b/contracts/IERC1155TokenReceiver.sol @@ -19,7 +19,13 @@ interface ERC1155TokenReceiver { @param _data Additional data with no specified format @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` */ - function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external returns(bytes4); + function onERC1155Received( + address _operator, + address _from, + uint256 _id, + uint256 _value, + bytes calldata _data + ) external returns (bytes4); /** @notice Handle the receipt of multiple ERC1155 token types. @@ -34,5 +40,11 @@ interface ERC1155TokenReceiver { @param _data Additional data with no specified format @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` */ - function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external returns(bytes4); -} \ No newline at end of file + function onERC1155BatchReceived( + address _operator, + address _from, + uint256[] calldata _ids, + uint256[] calldata _values, + bytes calldata _data + ) external returns (bytes4); +} diff --git a/contracts/IERC20WithPermit.sol b/contracts/IERC20WithPermit.sol index 0a36c599..41593d70 100644 --- a/contracts/IERC20WithPermit.sol +++ b/contracts/IERC20WithPermit.sol @@ -41,7 +41,7 @@ interface IERC20WithPermit { function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint256); - + function permit( address owner, address spender, @@ -51,5 +51,4 @@ interface IERC20WithPermit { bytes32 r, bytes32 s ) external; - -} \ No newline at end of file +} diff --git a/contracts/IERC721.sol b/contracts/IERC721.sol index 74693924..c2c02500 100644 --- a/contracts/IERC721.sol +++ b/contracts/IERC721.sol @@ -14,17 +14,29 @@ abstract contract IERC721 is IERC165 { /// (`to` == 0). Exception: during contract creation, any number of NFTs /// may be created and assigned without emitting Transfer. At the time of /// any transfer, the approved address for that NFT (if any) is reset to none. - event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId); + event Transfer( + address indexed _from, + address indexed _to, + uint256 indexed _tokenId + ); /// @dev This emits when the approved address for an NFT is changed or /// reaffirmed. The zero address indicates there is no approved address. /// When a Transfer event emits, this also indicates that the approved /// address for that NFT (if any) is reset to none. - event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId); + event Approval( + address indexed _owner, + address indexed _approved, + uint256 indexed _tokenId + ); /// @dev This emits when an operator is enabled or disabled for an owner. /// The operator can manage all NFTs of the owner. - event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved); + event ApprovalForAll( + address indexed _owner, + address indexed _operator, + bool _approved + ); /// @notice Count all NFTs assigned to an owner /// @dev NFTs assigned to the zero address are considered invalid, and this @@ -52,7 +64,12 @@ abstract contract IERC721 is IERC165 { /// @param _to The new owner /// @param _tokenId The NFT to transfer /// @param data Additional data with no specified format, sent in call to `_to` - function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory data) public virtual; + function safeTransferFrom( + address _from, + address _to, + uint256 _tokenId, + bytes memory data + ) public virtual; /// @notice Transfers the ownership of an NFT from one address to another address /// @dev This works identically to the other function with an extra data parameter, @@ -60,7 +77,11 @@ abstract contract IERC721 is IERC165 { /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer - function safeTransferFrom(address _from, address _to, uint256 _tokenId) public virtual; + function safeTransferFrom( + address _from, + address _to, + uint256 _tokenId + ) public virtual; /// @notice Transfer ownership of an NFT -- THE CALLER IS RESPONSIBLE /// TO CONFIRM THAT `_to` IS CAPABLE OF RECEIVING NFTS OR ELSE @@ -72,7 +93,11 @@ abstract contract IERC721 is IERC165 { /// @param _from The current owner of the NFT /// @param _to The new owner /// @param _tokenId The NFT to transfer - function transferFrom(address _from, address _to, uint256 _tokenId) public virtual; + function transferFrom( + address _from, + address _to, + uint256 _tokenId + ) public virtual; /// @notice Change or reaffirm the approved address for an NFT /// @dev The zero address indicates there is no approved address. @@ -88,17 +113,27 @@ abstract contract IERC721 is IERC165 { /// multiple operators per owner. /// @param _operator Address to add to the set of authorized operators /// @param _approved True if the operator is approved, false to revoke approval - function setApprovalForAll(address _operator, bool _approved) external virtual; + function setApprovalForAll(address _operator, bool _approved) + external + virtual; /// @notice Get the approved address for a single NFT /// @dev Throws if `_tokenId` is not a valid NFT. /// @param _tokenId The NFT to find the approved address for /// @return The approved address for this NFT, or the zero address if there is none - function getApproved(uint256 _tokenId) public view virtual returns (address); + function getApproved(uint256 _tokenId) + public + view + virtual + returns (address); /// @notice Query if an address is an authorized operator for another address /// @param _owner The address that owns the NFTs /// @param _operator The address that acts on behalf of the owner /// @return True if `_operator` is an approved operator for `_owner`, false otherwise - function isApprovedForAll(address _owner, address _operator) public view virtual returns (bool); -} \ No newline at end of file + function isApprovedForAll(address _owner, address _operator) + public + view + virtual + returns (bool); +} diff --git a/contracts/IERC721TokenReceiver.sol b/contracts/IERC721TokenReceiver.sol index bb549cc2..0f4fe8b3 100644 --- a/contracts/IERC721TokenReceiver.sol +++ b/contracts/IERC721TokenReceiver.sol @@ -16,5 +16,10 @@ interface ERC721TokenReceiver { /// @param _data Additional data with no specified format /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` /// unless throwing - function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes calldata _data) external returns(bytes4); -} \ No newline at end of file + function onERC721Received( + address _operator, + address _from, + uint256 _tokenId, + bytes calldata _data + ) external returns (bytes4); +} diff --git a/contracts/IFundLimitsOracle.sol b/contracts/IFundLimitsOracle.sol index 6326ae5e..92f96558 100644 --- a/contracts/IFundLimitsOracle.sol +++ b/contracts/IFundLimitsOracle.sol @@ -2,12 +2,15 @@ pragma solidity >=0.6.6 <0.7.0; - interface IFundLimitsOracle { - function setTokenLimit(address _tokenAddress, uint256 _newLimit) external; - function getTokenLimit(address _tokenAddress) external view returns(uint256); + + function getTokenLimit(address _tokenAddress) + external + view + returns (uint256); function setETHLimit(uint256 _newLimit) external; - function getETHLimit() external view returns(uint256); -} \ No newline at end of file + + function getETHLimit() external view returns (uint256); +} diff --git a/contracts/IVoucherKernel.sol b/contracts/IVoucherKernel.sol index 7c957e73..70a613f0 100644 --- a/contracts/IVoucherKernel.sol +++ b/contracts/IVoucherKernel.sol @@ -3,202 +3,263 @@ pragma solidity >=0.6.6 <0.7.0; interface IVoucherKernel { - /** - * @notice Pause the process of interaction with voucherID's (ERC-721), in case of emergency. - * Only Cashier contract is in control of this function. - */ + * @notice Pause the process of interaction with voucherID's (ERC-721), in case of emergency. + * Only Cashier contract is in control of this function. + */ function pause() external; /** - * @notice Unpause the process of interaction with voucherID's (ERC-721). - * Only Cashier contract is in control of this function. - */ + * @notice Unpause the process of interaction with voucherID's (ERC-721). + * Only Cashier contract is in control of this function. + */ function unpause() external; /** - * @notice Creating a new promise for goods or services. - * Can be reused, e.g. for making different batches of these (but not in prototype). - * @param _seller seller of the promise - * @param _validFrom Start of valid period - * @param _validTo End of valid period - * @param _price Price (payment amount) - * @param _depositSe Seller's deposit - * @param _depositBu Buyer's deposit - */ - function createTokenSupplyID(address _seller, uint256 _validFrom, uint256 _validTo, uint256 _price, uint256 _depositSe, uint256 _depositBu, uint256 _quantity) external returns (uint256); + * @notice Creating a new promise for goods or services. + * Can be reused, e.g. for making different batches of these (but not in prototype). + * @param _seller seller of the promise + * @param _validFrom Start of valid period + * @param _validTo End of valid period + * @param _price Price (payment amount) + * @param _depositSe Seller's deposit + * @param _depositBu Buyer's deposit + */ + function createTokenSupplyID( + address _seller, + uint256 _validFrom, + uint256 _validTo, + uint256 _price, + uint256 _depositSe, + uint256 _depositBu, + uint256 _quantity + ) external returns (uint256); /** - * @notice Creates a Payment method struct recording the details on how the seller requires to receive Price and Deposits for a certain Voucher Set. - * @param _tokenIdSupply _tokenIdSupply of the voucher set this is related to - * @param _paymentMethod might be ETHETH, ETHTKN, TKNETH or TKNTKN - * @param _tokenPrice token address which will hold the funds for the price of the voucher - * @param _tokenDeposits token address which will hold the funds for the deposits of the voucher - */ - function createPaymentMethod(uint256 _tokenIdSupply, uint8 _paymentMethod, address _tokenPrice, address _tokenDeposits) external; - + * @notice Creates a Payment method struct recording the details on how the seller requires to receive Price and Deposits for a certain Voucher Set. + * @param _tokenIdSupply _tokenIdSupply of the voucher set this is related to + * @param _paymentMethod might be ETHETH, ETHTKN, TKNETH or TKNTKN + * @param _tokenPrice token address which will hold the funds for the price of the voucher + * @param _tokenDeposits token address which will hold the funds for the deposits of the voucher + */ + function createPaymentMethod( + uint256 _tokenIdSupply, + uint8 _paymentMethod, + address _tokenPrice, + address _tokenDeposits + ) external; /** - * @notice Get all necessary funds for a supply token - * @param _tokenIdSupply ID of the supply token - * @return returns a tuple (Payment amount, Seller's deposit, Buyer's deposit) - */ - function getOrderCosts(uint256 _tokenIdSupply) external view returns (uint256, uint256, uint256); + * @notice Get all necessary funds for a supply token + * @param _tokenIdSupply ID of the supply token + * @return returns a tuple (Payment amount, Seller's deposit, Buyer's deposit) + */ + function getOrderCosts(uint256 _tokenIdSupply) + external + view + returns ( + uint256, + uint256, + uint256 + ); /** - * @notice Fill Voucher Order, iff funds paid, then extract & mint NFT to the voucher holder - * @param _tokenIdSupply ID of the supply token (ERC-1155) - * @param _issuer Address of the token's issuer - * @param _holder Address of the recipient of the voucher (ERC-721) - */ - function fillOrder(uint256 _tokenIdSupply, address _issuer, address _holder) external; + * @notice Fill Voucher Order, iff funds paid, then extract & mint NFT to the voucher holder + * @param _tokenIdSupply ID of the supply token (ERC-1155) + * @param _issuer Address of the token's issuer + * @param _holder Address of the recipient of the voucher (ERC-721) + */ + function fillOrder( + uint256 _tokenIdSupply, + address _issuer, + address _holder + ) external; /** - * @notice Get the address of the token where the price for the supply is held - * @param _tokenIdSupply ID of the voucher token - * @return Address of the token - */ - function getVoucherPriceToken(uint256 _tokenIdSupply) external view returns (address); + * @notice Get the address of the token where the price for the supply is held + * @param _tokenIdSupply ID of the voucher token + * @return Address of the token + */ + function getVoucherPriceToken(uint256 _tokenIdSupply) + external + view + returns (address); /** - * @notice Get the address of the token where the deposits for the supply are held - * @param _tokenIdSupply ID of the voucher token - * @return Address of the token - */ - function getVoucherDepositToken(uint256 _tokenIdSupply) external view returns (address); + * @notice Get the address of the token where the deposits for the supply are held + * @param _tokenIdSupply ID of the voucher token + * @return Address of the token + */ + function getVoucherDepositToken(uint256 _tokenIdSupply) + external + view + returns (address); /** - * @notice Get Buyer costs required to make an order for a supply token - * @param _tokenIdSupply ID of the supply token - * @return returns a tuple (Payment amount, Buyer's deposit) - */ - function getBuyerOrderCosts(uint256 _tokenIdSupply) external view returns (uint256, uint256); + * @notice Get Buyer costs required to make an order for a supply token + * @param _tokenIdSupply ID of the supply token + * @return returns a tuple (Payment amount, Buyer's deposit) + */ + function getBuyerOrderCosts(uint256 _tokenIdSupply) + external + view + returns (uint256, uint256); /** - * @notice Get the promise ID from a voucher token - * @param _tokenIdVoucher ID of the voucher token - * @return ID of the promise - */ - function getIdSupplyFromVoucher(uint256 _tokenIdVoucher) external pure returns (uint256); + * @notice Get the promise ID from a voucher token + * @param _tokenIdVoucher ID of the voucher token + * @return ID of the promise + */ + function getIdSupplyFromVoucher(uint256 _tokenIdVoucher) + external + pure + returns (uint256); /** - * @notice Get the payment method for a particular _tokenIdSupply - * @param _tokenIdSupply ID of the voucher supply token - * @return payment method - */ - function getVoucherPaymentMethod(uint256 _tokenIdSupply) external view returns (uint8); + * @notice Get the payment method for a particular _tokenIdSupply + * @param _tokenIdSupply ID of the voucher supply token + * @return payment method + */ + function getVoucherPaymentMethod(uint256 _tokenIdSupply) + external + view + returns (uint8); /** - * @notice Get the current status of a voucher - * @param _tokenIdVoucher ID of the voucher token - * @return Status of the voucher (via enum) - */ - function getVoucherStatus(uint256 _tokenIdVoucher) external view returns (uint8, bool, bool); + * @notice Get the current status of a voucher + * @param _tokenIdVoucher ID of the voucher token + * @return Status of the voucher (via enum) + */ + function getVoucherStatus(uint256 _tokenIdVoucher) + external + view + returns ( + uint8, + bool, + bool + ); /** - * @notice Get the holder of a supply - * @param _tokenIdSupply ID of a promise which is mapped to the corresponding Promise - * @return Address of the holder - */ - function getSupplyHolder(uint256 _tokenIdSupply) external view returns (address); + * @notice Get the holder of a supply + * @param _tokenIdSupply ID of a promise which is mapped to the corresponding Promise + * @return Address of the holder + */ + function getSupplyHolder(uint256 _tokenIdSupply) + external + view + returns (address); /** * @notice Get the holder of a voucher * @param _tokenIdVoucher ID of the voucher token * @return Address of the holder - */ - function getVoucherHolder(uint256 _tokenIdVoucher) external view returns (address); + */ + function getVoucherHolder(uint256 _tokenIdVoucher) + external + view + returns (address); /** - * @notice Mark voucher token that the payment was released - * @param _tokenIdVoucher ID of the voucher token - */ + * @notice Mark voucher token that the payment was released + * @param _tokenIdVoucher ID of the voucher token + */ function setPaymentReleased(uint256 _tokenIdVoucher) external; /** - * @notice Mark voucher token that the deposits were released - * @param _tokenIdVoucher ID of the voucher token - */ + * @notice Mark voucher token that the deposits were released + * @param _tokenIdVoucher ID of the voucher token + */ function setDepositsReleased(uint256 _tokenIdVoucher) external; - + /** - * @notice Get Seller deposit - * @param _tokenIdSupply ID of the supply token - * @return returns sellers deposit - */ - function getSellerDeposit(uint256 _tokenIdSupply) external view returns (uint256); + * @notice Get Seller deposit + * @param _tokenIdSupply ID of the supply token + * @return returns sellers deposit + */ + function getSellerDeposit(uint256 _tokenIdSupply) + external + view + returns (uint256); /** - * @notice Get the remaining quantity left in supply of tokens (e.g ERC-721 left in ERC-1155) of an account - * @param _tokenSupplyId Token supply ID - * @param _owner holder of the Token Supply - * @return remaining quantity - */ - function getRemQtyForSupply(uint _tokenSupplyId, address _owner) external view returns (uint256); + * @notice Get the remaining quantity left in supply of tokens (e.g ERC-721 left in ERC-1155) of an account + * @param _tokenSupplyId Token supply ID + * @param _owner holder of the Token Supply + * @return remaining quantity + */ + function getRemQtyForSupply(uint256 _tokenSupplyId, address _owner) + external + view + returns (uint256); /** - * @notice Extract a standard non-fungible tokens ERC-721 from a supply stored in ERC-1155 - * @dev Token ID is derived following the same principles for both ERC-1155 and ERC-721 - * @param _issuer The address of the token issuer - * @param _tokenIdSupply ID of the token type - * @param _qty qty that should be burned - */ - function burnSupplyOnPause(address _issuer, uint256 _tokenIdSupply, uint256 _qty) external; + * @notice Extract a standard non-fungible tokens ERC-721 from a supply stored in ERC-1155 + * @dev Token ID is derived following the same principles for both ERC-1155 and ERC-721 + * @param _issuer The address of the token issuer + * @param _tokenIdSupply ID of the token type + * @param _qty qty that should be burned + */ + function burnSupplyOnPause( + address _issuer, + uint256 _tokenIdSupply, + uint256 _qty + ) external; /** - * @notice Redemption of the vouchers promise - * @param _tokenIdVoucher ID of the voucher - */ + * @notice Redemption of the vouchers promise + * @param _tokenIdVoucher ID of the voucher + */ function redeem(uint256 _tokenIdVoucher) external; /** - * @notice Refunding a voucher - * @param _tokenIdVoucher ID of the voucher - */ + * @notice Refunding a voucher + * @param _tokenIdVoucher ID of the voucher + */ function refund(uint256 _tokenIdVoucher) external; /** - * @notice Issue a complain for a voucher - * @param _tokenIdVoucher ID of the voucher - */ + * @notice Issue a complain for a voucher + * @param _tokenIdVoucher ID of the voucher + */ function complain(uint256 _tokenIdVoucher) external; /** - * @notice Cancel/Fault transaction by the Seller, admitting to a fault or backing out of the deal - * @param _tokenIdVoucher ID of the voucher - */ + * @notice Cancel/Fault transaction by the Seller, admitting to a fault or backing out of the deal + * @param _tokenIdVoucher ID of the voucher + */ function cancelOrFault(uint256 _tokenIdVoucher) external; /** - * @notice Mark voucher token as expired - * @param _tokenIdVoucher ID of the voucher token - */ + * @notice Mark voucher token as expired + * @param _tokenIdVoucher ID of the voucher token + */ function triggerExpiration(uint256 _tokenIdVoucher) external; - /** - * @notice Mark voucher token to the final status - * @param _tokenIdVoucher ID of the voucher token - */ + * @notice Mark voucher token to the final status + * @param _tokenIdVoucher ID of the voucher token + */ function triggerFinalizeVoucher(uint256 _tokenIdVoucher) external; /** - * @notice Set the address of the new holder of a _tokenIdSupply on transfer - * @param _tokenIdSupply _tokenIdSupply which will be transferred - * @param _newSeller new holder of the supply - */ - function setSupplyHolderOnTransfer(uint256 _tokenIdSupply, address _newSeller) external; + * @notice Set the address of the new holder of a _tokenIdSupply on transfer + * @param _tokenIdSupply _tokenIdSupply which will be transferred + * @param _newSeller new holder of the supply + */ + function setSupplyHolderOnTransfer( + uint256 _tokenIdSupply, + address _newSeller + ) external; /** - * @notice Set the address of the Cashier contract - * @param _cashierAddress The address of the Cashier contract - */ + * @notice Set the address of the Cashier contract + * @param _cashierAddress The address of the Cashier contract + */ function setCashierAddress(address _cashierAddress) external; /** - * @notice Set the general complain period, should be used sparingly as it has significant consequences. Here done simply for demo purposes. - * @param _complainPeriod the new value for complain period (in number of seconds) - */ + * @notice Set the general complain period, should be used sparingly as it has significant consequences. Here done simply for demo purposes. + * @param _complainPeriod the new value for complain period (in number of seconds) + */ function setComplainPeriod(uint256 _complainPeriod) external; - -} \ No newline at end of file +} diff --git a/contracts/Migrations.sol b/contracts/Migrations.sol index 2939c65f..9d794c83 100644 --- a/contracts/Migrations.sol +++ b/contracts/Migrations.sol @@ -3,23 +3,23 @@ pragma solidity >=0.6.6 <0.7.0; contract Migrations { - address public owner; - uint public lastCompletedMigration; + address public owner; + uint256 public lastCompletedMigration; - constructor() public { - owner = msg.sender; - } + constructor() public { + owner = msg.sender; + } - modifier restricted() { - if (msg.sender == owner) _; - } + modifier restricted() { + if (msg.sender == owner) _; + } - function setCompleted(uint completed) public restricted { - lastCompletedMigration = completed; - } + function setCompleted(uint256 completed) public restricted { + lastCompletedMigration = completed; + } - function upgrade(address newAddress) public restricted { - Migrations upgraded = Migrations(newAddress); - upgraded.setCompleted(lastCompletedMigration); - } + function upgrade(address newAddress) public restricted { + Migrations upgraded = Migrations(newAddress); + upgraded.setCompleted(lastCompletedMigration); + } } diff --git a/contracts/UsingHelpers.sol b/contracts/UsingHelpers.sol index b2fac9e7..af11b522 100644 --- a/contracts/UsingHelpers.sol +++ b/contracts/UsingHelpers.sol @@ -14,13 +14,13 @@ contract UsingHelpers { uint8 internal constant IDX_COMPLAIN = 3; uint8 internal constant IDX_CANCEL_FAULT = 2; uint8 internal constant IDX_FINAL = 1; - + /* Status of the voucher in 8 bits: [7:COMMITTED] [6:REDEEMED] [5:REFUNDED] [4:EXPIRED] [3:COMPLAINED] [2:CANCELORFAULT] [1:FINAL] [1:/] */ - // Those are the payment methods we are using throughout the system. - // Depending on how to user choose to interact with it's funds we store the method, so we could distribute its tokens afterwise + // Those are the payment methods we are using throughout the system. + // Depending on how to user choose to interact with it's funds we store the method, so we could distribute its tokens afterwise uint8 internal constant ETHETH = 1; uint8 internal constant ETHTKN = 2; uint8 internal constant TKNETH = 3; @@ -33,52 +33,36 @@ contract UsingHelpers { uint256 complainPeriodStart; uint256 cancelFaultPeriodStart; } - - - function isStateCommitted(uint8 _status) - internal pure - returns (bool) - { + + function isStateCommitted(uint8 _status) internal pure returns (bool) { return _status == setChange(0, IDX_COMMIT); } - - + function isStateRedemptionSigned(uint8 _status) - internal pure + internal + pure returns (bool) { return _status == setChange(setChange(0, IDX_COMMIT), IDX_REDEEM); - } - - - function isStateRefunded(uint8 _status) - internal pure - returns (bool) - { + } + + function isStateRefunded(uint8 _status) internal pure returns (bool) { return _status == setChange(setChange(0, IDX_COMMIT), IDX_REFUND); - } - + } - function isStateExpired(uint8 _status) - internal pure - returns (bool) - { + function isStateExpired(uint8 _status) internal pure returns (bool) { return _status == setChange(setChange(0, IDX_COMMIT), IDX_EXPIRE); - } - - - function isStatus(uint8 _status, uint8 _idx) - internal pure - returns (bool) - { - return _status >> _idx & ONE == 1; } - - - function setChange(uint8 _status, uint8 _changeIdx) - internal pure - returns (uint8) + + function isStatus(uint8 _status, uint8 _idx) internal pure returns (bool) { + return (_status >> _idx) & ONE == 1; + } + + function setChange(uint8 _status, uint8 _changeIdx) + internal + pure + returns (uint8) { - return _status | ONE << _changeIdx; - } + return _status | (ONE << _changeIdx); + } } diff --git a/contracts/VoucherKernel.sol b/contracts/VoucherKernel.sol index 7aa64996..d2875850 100644 --- a/contracts/VoucherKernel.sol +++ b/contracts/VoucherKernel.sol @@ -18,35 +18,33 @@ import "./UsingHelpers.sol"; /** * @title VoucherKernel contract is controlling the core business logic - * @dev Notes: - * - Since this is a demo app, it is not yet optimized. + * @dev Notes: + * - Since this is a demo app, it is not yet optimized. * In the next phase, the bulk raw data will be packed into a single bytes32 field and/or pushed off-chain. * - The usage of block.timestamp is honored since vouchers are defined with day-precision and the demo app is not covering all edge cases. * See: https://ethereum.stackexchange.com/questions/5924/how-do-ethereum-mining-nodes-maintain-a-time-consistent-with-the-network/5931#5931 -*/ + */ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { using Address for address; - using SafeMath for uint; + using SafeMath for uint256; //using Counters for Counters.Counter; //Counters.Counter private voucherTokenId; //unique IDs for voucher tokens - + //AssetRegistry assetRegistry; address public tokensContract; - + //promise for an asset could be reusable, but simplified here for brevitbytes32 struct Promise { bytes32 promiseId; - uint256 nonce; //the asset that is offered - address seller; //the seller who created the promise - + uint256 nonce; //the asset that is offered + address seller; //the seller who created the promise //we simplify the value for the demoapp, otherwise voucher details would be packed in one bytes32 field value uint256 validFrom; uint256 validTo; uint256 price; uint256 depositSe; uint256 depositBu; - - uint idx; + uint256 idx; } struct VoucherPaymentMethod { @@ -54,36 +52,36 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { address addressTokenPrice; address addressTokenDeposits; } - - address public cashierAddress; //address of the Cashier contract - - mapping(bytes32 => Promise) public promises; //promises to deliver goods or services + + address public cashierAddress; //address of the Cashier contract + + mapping(bytes32 => Promise) public promises; //promises to deliver goods or services mapping(address => uint256) public tokenNonces; //mapping between seller address and its own nonces. Every time seller creates supply ID it gets incremented. Used to avoid duplicate ID's - mapping (uint256 => VoucherPaymentMethod) public paymentDetails; // tokenSupplyId to VoucherPaymentMethod + mapping(uint256 => VoucherPaymentMethod) public paymentDetails; // tokenSupplyId to VoucherPaymentMethod bytes32[] public promiseKeys; - + mapping(address => uint256) public accountSupply; - mapping(uint256 => bytes32) public ordersPromise; //mapping between an order (supply token) and a promise - - mapping(uint256 => VoucherStatus) public vouchersStatus; //recording the vouchers evolution - mapping(uint256 => address) public voucherIssuers; //issuers of vouchers // TODO on refactoring this must be removed as if we are to transfer 1155, issuer should be fetched from the promise, not from the 721 - + mapping(uint256 => bytes32) public ordersPromise; //mapping between an order (supply token) and a promise + + mapping(uint256 => VoucherStatus) public vouchersStatus; //recording the vouchers evolution + mapping(uint256 => address) public voucherIssuers; //issuers of vouchers // TODO on refactoring this must be removed as if we are to transfer 1155, issuer should be fetched from the promise, not from the 721 + //standard reqs - mapping (uint256 => mapping(address => uint256)) private balances; //balance of token ids of an account - mapping (address => mapping(address => bool)) private operatorApprovals; //approval of accounts of an operator - + mapping(uint256 => mapping(address => uint256)) private balances; //balance of token ids of an account + mapping(address => mapping(address => bool)) private operatorApprovals; //approval of accounts of an operator + //ID reqs - mapping (uint256 => uint256) public typeCounters; //counter for ID of a particular type of NFT - uint256 public constant MASK_TYPE = uint256(uint128(~0)) << 128; //the type mask in the upper 128 bits -//1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + mapping(uint256 => uint256) public typeCounters; //counter for ID of a particular type of NFT + uint256 public constant MASK_TYPE = uint256(uint128(~0)) << 128; //the type mask in the upper 128 bits + //1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + + uint256 public constant MASK_NF_INDEX = uint128(~0); //the non-fungible index mask in the lower 128 + //0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 - uint256 public constant MASK_NF_INDEX = uint128(~0); //the non-fungible index mask in the lower 128 -//0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 - uint256 public constant TYPE_NF_BIT = 1 << 255; //the first bit represents an NFT type -//1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 - + //1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + uint256 public typeId; //base token type ... 127-bits cover 1.701411835*10^38 types (not differentiating between FTs and NFTs) /* Token IDs: Fungibles: 0, followed by 127-bit FT type ID, in the upper 128 bits, followed by 0 in lower 128-bits @@ -95,11 +93,10 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { Non-fungible vouchers: 1, followed by 127-bit NFT type ID, in the upper 128 bits, followed by a 1-based index of an NFT token ID. <1> */ - + uint256 public complainPeriod; //for demo purposes, this is fixed/set by owner uint256 public cancelFaultPeriod; //for demo purposes, this is fixed/set by owner - - + event LogPromiseCreated( bytes32 indexed _promiseId, uint256 indexed _nonce, @@ -109,137 +106,119 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { uint256 _idx ); - event LogVoucherDelivered( + event LogVoucherDelivered( uint256 indexed _tokenIdSupply, uint256 _tokenIdVoucher, address _issuer, address _holder, bytes32 _promiseId - ); - + ); + event LogVoucherRedeemed( uint256 _tokenIdVoucher, address _holder, bytes32 _promiseId ); - - event LogVoucherRefunded( - uint256 _tokenIdVoucher - ); - - event LogVoucherComplain( - uint256 _tokenIdVoucher - ); - - event LogVoucherFaultCancel( - uint256 _tokenIdVoucher - ); - - event LogExpirationTriggered( - uint256 _tokenIdVoucher, - address _triggeredBy - ); - - event LogFinalizeVoucher( - uint256 _tokenIdVoucher, - address _triggeredBy - ); - - event LogCashierSet( - address _newCashier, - address _triggeredBy - ); - + + event LogVoucherRefunded(uint256 _tokenIdVoucher); + + event LogVoucherComplain(uint256 _tokenIdVoucher); + + event LogVoucherFaultCancel(uint256 _tokenIdVoucher); + + event LogExpirationTriggered(uint256 _tokenIdVoucher, address _triggeredBy); + + event LogFinalizeVoucher(uint256 _tokenIdVoucher, address _triggeredBy); + + event LogCashierSet(address _newCashier, address _triggeredBy); + event LogComplainPeriodChanged( uint256 _newComplainPeriod, address _triggeredBy ); - + event LogCancelFaultPeriodChanged( uint256 _newCancelFaultPeriod, address _triggeredBy - ); - + ); + event LogFundsReleased( uint256 _tokenIdVoucher, - uint8 _type //0 .. payment, 1 .. deposits + uint8 _type //0 .. payment, 1 .. deposits ); - modifier onlyFromCashier() { - require(cashierAddress != address(0), "UNSPECIFIED_CASHIER"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(msg.sender == cashierAddress, "UNAUTHORIZED_C"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + require(cashierAddress != address(0), "UNSPECIFIED_CASHIER"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require(msg.sender == cashierAddress, "UNAUTHORIZED_C"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) _; } - + modifier onlyVoucherOwner(uint256 _tokenIdVoucher) { //check authorization - require(IERC721(tokensContract).ownerOf(_tokenIdVoucher) == msg.sender, "UNAUTHORIZED_V"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + require( + IERC721(tokensContract).ownerOf(_tokenIdVoucher) == msg.sender, + "UNAUTHORIZED_V" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) _; } - - constructor( - address _tokensContract - ) - public - { + + constructor(address _tokensContract) public { tokensContract = _tokensContract; - + complainPeriod = 7 * 1 days; cancelFaultPeriod = 7 * 1 days; } /** - * @notice Pause the process of interaction with voucherID's (ERC-721), in case of emergency. - * Only Cashier contract is in control of this function. - */ + * @notice Pause the process of interaction with voucherID's (ERC-721), in case of emergency. + * Only Cashier contract is in control of this function. + */ function pause() external override onlyFromCashier { _pause(); } /** - * @notice Unpause the process of interaction with voucherID's (ERC-721). - * Only Cashier contract is in control of this function. - */ + * @notice Unpause the process of interaction with voucherID's (ERC-721). + * Only Cashier contract is in control of this function. + */ function unpause() external override onlyFromCashier { _unpause(); - } - + } + /** - * @notice Creating a new promise for goods or services. - * Can be reused, e.g. for making different batches of these (but not in prototype). - * @param _seller seller of the promise - * @param _validFrom Start of valid period - * @param _validTo End of valid period - * @param _price Price (payment amount) - * @param _depositSe Seller's deposit - * @param _depositBu Buyer's deposit - */ + * @notice Creating a new promise for goods or services. + * Can be reused, e.g. for making different batches of these (but not in prototype). + * @param _seller seller of the promise + * @param _validFrom Start of valid period + * @param _validTo End of valid period + * @param _price Price (payment amount) + * @param _depositSe Seller's deposit + * @param _depositBu Buyer's deposit + */ function createTokenSupplyID( - address _seller, + address _seller, uint256 _validFrom, uint256 _validTo, uint256 _price, uint256 _depositSe, uint256 _depositBu, uint256 _quantity - ) - external - override - onlyFromCashier - returns (uint256) - { - - require(_validFrom <= _validTo, "INVALID_VALIDITY_FROM"); //hex"26" FISSION.code(FISSION.Category.Find, FISSION.Status.Above_Range_Overflow) - require(_validTo >= block.timestamp, "INVALID_VALIDITY_TO"); //hex"24" FISSION.code(FISSION.Category.Find, FISSION.Status.BelowRange_Underflow) - + ) external override onlyFromCashier returns (uint256) { + require(_validFrom <= _validTo, "INVALID_VALIDITY_FROM"); //hex"26" FISSION.code(FISSION.Category.Find, FISSION.Status.Above_Range_Overflow) + require(_validTo >= block.timestamp, "INVALID_VALIDITY_TO"); //hex"24" FISSION.code(FISSION.Category.Find, FISSION.Status.BelowRange_Underflow) + bytes32 key; - key = keccak256(abi.encodePacked(tokenNonces[_seller]++, _validFrom, _validTo)); - + key = keccak256( + abi.encodePacked(tokenNonces[_seller]++, _validFrom, _validTo) + ); + if (promiseKeys.length > 0) { - require(promiseKeys[promises[key].idx] != key, "PROMISE_ALREADY_EXISTS"); + require( + promiseKeys[promises[key].idx] != key, + "PROMISE_ALREADY_EXISTS" + ); } - + promises[key] = Promise({ promiseId: key, nonce: tokenNonces[_seller], @@ -251,11 +230,17 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { depositBu: _depositBu, idx: promiseKeys.length }); - + promiseKeys.push(key); - - emit LogPromiseCreated(key, tokenNonces[_seller], _seller, _validFrom, _validTo, //_price, _depositSe, _depositBu, _complainPeriod, _cancelFaultPeriod, - promiseKeys.length - 1); + + emit LogPromiseCreated( + key, + tokenNonces[_seller], + _seller, + _validFrom, + _validTo, //_price, _depositSe, _depositBu, _complainPeriod, _cancelFaultPeriod, + promiseKeys.length - 1 + ); return createOrder(_seller, key, _quantity); } @@ -272,17 +257,11 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { uint8 _paymentMethod, address _tokenPrice, address _tokenDeposits - ) - external - override - onlyFromCashier - { - + ) external override onlyFromCashier { paymentDetails[_tokenIdSupply] = VoucherPaymentMethod({ paymentMethod: _paymentMethod, addressTokenPrice: _tokenPrice, addressTokenDeposits: _tokenDeposits - }); } @@ -293,69 +272,83 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @param _promiseId ID of a promise (simplified into asset for demo) * @param _quantity Quantity of assets on offer */ - function createOrder(address _seller, bytes32 _promiseId, uint256 _quantity) - private - returns (uint256) - { - require(_promiseId != bytes32(0), "UNSPECIFIED_PROMISE"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(promises[_promiseId].seller == _seller, "UNAUTHORIZED_CO"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + function createOrder( + address _seller, + bytes32 _promiseId, + uint256 _quantity + ) private returns (uint256) { + require(_promiseId != bytes32(0), "UNSPECIFIED_PROMISE"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require(promises[_promiseId].seller == _seller, "UNAUTHORIZED_CO"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) require(_quantity > 0, "INVALID_QUANTITY"); //hex"24" FISSION.code(FISSION.Category.Find, FISSION.Status.BelowRange_Underflow) - + uint256 tokenIdSupply = generateTokenType(true); //create & assign a new non-fungible type - IERC1155ERC721(tokensContract).mint(_seller, tokenIdSupply, _quantity, ""); - + IERC1155ERC721(tokensContract).mint( + _seller, + tokenIdSupply, + _quantity, + "" + ); + ordersPromise[tokenIdSupply] = _promiseId; accountSupply[_seller] += _quantity; return tokenIdSupply; } - - + /** - * @notice Fill Voucher Order, iff funds paid, then extract & mint NFT to the voucher holder - * @param _tokenIdSupply ID of the supply token (ERC-1155) - * @param _issuer Address of the token's issuer - * @param _holder Address of the recipient of the voucher (ERC-721) - */ - function fillOrder(uint256 _tokenIdSupply, address _issuer, address _holder) - external - override - onlyFromCashier - - { + * @notice Fill Voucher Order, iff funds paid, then extract & mint NFT to the voucher holder + * @param _tokenIdSupply ID of the supply token (ERC-1155) + * @param _issuer Address of the token's issuer + * @param _holder Address of the recipient of the voucher (ERC-721) + */ + function fillOrder( + uint256 _tokenIdSupply, + address _issuer, + address _holder + ) external override onlyFromCashier { //checks checkOrderFillable(_tokenIdSupply, _issuer, _holder); //close order uint256 voucherTokenId = extract721(_issuer, _holder, _tokenIdSupply); - emit LogVoucherDelivered(_tokenIdSupply, voucherTokenId, _issuer, _holder, getPromiseIdFromVoucherId(voucherTokenId)); + emit LogVoucherDelivered( + _tokenIdSupply, + voucherTokenId, + _issuer, + _holder, + getPromiseIdFromVoucherId(voucherTokenId) + ); } - - + /** * @notice Check order is fillable * @dev Will throw if checks don't pass * @param _tokenIdSupply ID of the supply token - * @param _issuer Address of the token's issuer - * @param _holder Address of the recipient of the voucher (ERC-721) + * @param _issuer Address of the token's issuer + * @param _holder Address of the recipient of the voucher (ERC-721) */ - function checkOrderFillable(uint256 _tokenIdSupply, address _issuer, address _holder) - internal - view - { + function checkOrderFillable( + uint256 _tokenIdSupply, + address _issuer, + address _holder + ) internal view { require(_tokenIdSupply != 0, "UNSPECIFIED_ID"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) if (_holder.isContract()) { - require(IERC165(_holder).supportsInterface(0x150b7a02), "UNSUPPORTED_ERC721_RECEIVED"); //hex"31" + require( + IERC165(_holder).supportsInterface(0x150b7a02), + "UNSUPPORTED_ERC721_RECEIVED" + ); //hex"31" //bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) - } - - require(_holder != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - require(IERC1155(tokensContract).balanceOf(_issuer, _tokenIdSupply) > 0, "OFFER_EMPTY"); //hex"40" FISSION.code(FISSION.Category.Availability, FISSION.Status.Unavailable) - + } + + require(_holder != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + require( + IERC1155(tokensContract).balanceOf(_issuer, _tokenIdSupply) > 0, + "OFFER_EMPTY" + ); //hex"40" FISSION.code(FISSION.Category.Availability, FISSION.Status.Unavailable) } - /** * @notice Extract a standard non-fungible token ERC-721 from a supply stored in ERC-1155 @@ -365,31 +358,43 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @param _tokenIdSupply ID of the token type * @return ID of the voucher token */ - function extract721(address _issuer, address _to, uint256 _tokenIdSupply) - internal - returns (uint256) - { + function extract721( + address _issuer, + address _to, + uint256 _tokenIdSupply + ) internal returns (uint256) { if (_to.isContract()) { - require(ERC721TokenReceiver(_to).onERC721Received(_issuer, msg.sender, _tokenIdSupply, "") == ERC721TokenReceiver(_to).onERC721Received.selector, "UNSUPPORTED_ERC721_RECEIVED"); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) + require( + ERC721TokenReceiver(_to).onERC721Received( + _issuer, + msg.sender, + _tokenIdSupply, + "" + ) == ERC721TokenReceiver(_to).onERC721Received.selector, + "UNSUPPORTED_ERC721_RECEIVED" + ); //hex"10" FISSION.code(FISSION.Category.Permission, FISSION.Status.Disallowed_Stop) //bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")) - } + } IERC1155ERC721(tokensContract).burn(_issuer, _tokenIdSupply, 1); // This is hardcoded as 1 on purpose accountSupply[_issuer]--; - - + //calculate tokenId - uint256 voucherTokenId = _tokenIdSupply | ++typeCounters[_tokenIdSupply]; - + uint256 voucherTokenId = + _tokenIdSupply | ++typeCounters[_tokenIdSupply]; + //set status - vouchersStatus[voucherTokenId].status = setChange(vouchersStatus[voucherTokenId].status, IDX_COMMIT); + vouchersStatus[voucherTokenId].status = setChange( + vouchersStatus[voucherTokenId].status, + IDX_COMMIT + ); vouchersStatus[voucherTokenId].isPaymentReleased = false; vouchersStatus[voucherTokenId].isDepositsReleased = false; - + //mint voucher NFT as ERC-721 IERC1155ERC721(tokensContract).mint(_to, voucherTokenId); voucherIssuers[voucherTokenId] = _issuer; //TODO THIS MIGHT NOT BE REQUIRED ANYMORE - + return voucherTokenId; } @@ -399,42 +404,39 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @param _issuer The address of the token issuer * @param _tokenIdSupply ID of the token type * @param _qty qty that should be burned - */ - function burnSupplyOnPause(address _issuer, uint256 _tokenIdSupply, uint256 _qty) - external - override - whenPaused - onlyFromCashier - { + */ + function burnSupplyOnPause( + address _issuer, + uint256 _tokenIdSupply, + uint256 _qty + ) external override whenPaused onlyFromCashier { IERC1155ERC721(tokensContract).burn(_issuer, _tokenIdSupply, _qty); accountSupply[_issuer] = accountSupply[_issuer].sub(_qty); } - - + /** * @notice Creating a new token type, serving as the base for tokenID generation for NFTs, and a de facto ID for FTs. * @param _isNonFungible Flag for generating NFT or FT * @return _tokenType Returns a newly generated token type - */ + */ function generateTokenType(bool _isNonFungible) internal returns (uint256 _tokenType) { typeId++; - + if (_isNonFungible) { - _tokenType = TYPE_NF_BIT | typeId << 128; //upper bit is 1, followed by sequence, leaving lower 128-bits as 0 + _tokenType = TYPE_NF_BIT | (typeId << 128); //upper bit is 1, followed by sequence, leaving lower 128-bits as 0 } else { _tokenType = typeId << 128; //upper bit is not set, followed by sequence, leaving lower 128-bits as 0 } - + //not needed: //assert(typeId= vouchersStatus[_tokenIdVoucher].complainPeriodStart + cancelFaultPeriod) { + } else if ( + block.timestamp >= + vouchersStatus[_tokenIdVoucher].complainPeriodStart + + cancelFaultPeriod + ) { //if COMPLAIN: then final after cof period mark = true; } - - } else if (isStatus(tStatus, IDX_CANCEL_FAULT) && - block.timestamp >= vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod - ) { + } else if ( + isStatus(tStatus, IDX_CANCEL_FAULT) && + block.timestamp >= + vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod + ) { //if COF: then final after complain period mark = true; - - } else if (isStateRedemptionSigned(tStatus) || - isStateRefunded(tStatus)) { + } else if ( + isStateRedemptionSigned(tStatus) || isStateRefunded(tStatus) + ) { //if RDM/RFND NON_COMPLAIN: then final after complainPeriodStart + complainPeriod - if (block.timestamp >= vouchersStatus[_tokenIdVoucher].complainPeriodStart + complainPeriod) { + if ( + block.timestamp >= + vouchersStatus[_tokenIdVoucher].complainPeriodStart + + complainPeriod + ) { mark = true; } - } else if (isStateExpired(tStatus)) { //if EXP NON_COMPLAIN: then final after validTo + complainPeriod if (block.timestamp >= tPromise.validTo + complainPeriod) { mark = true; - } + } } - + if (mark) { - vouchersStatus[_tokenIdVoucher].status = setChange(tStatus, IDX_FINAL); - emit LogFinalizeVoucher(_tokenIdVoucher, msg.sender); + vouchersStatus[_tokenIdVoucher].status = setChange( + tStatus, + IDX_FINAL + ); + emit LogFinalizeVoucher(_tokenIdVoucher, msg.sender); } // - } - - // // // // // // // // - // UTILS - // // // // // // // // + } + // // // // // // // // + // UTILS + // // // // // // // // /** * @notice Set the address of the new holder of a _tokenIdSupply on transfer * @param _tokenIdSupply _tokenIdSupply which will be transferred * @param _newSeller new holder of the supply - */ - function setSupplyHolderOnTransfer(uint256 _tokenIdSupply, address _newSeller) - external - override - onlyFromCashier - { + */ + function setSupplyHolderOnTransfer( + uint256 _tokenIdSupply, + address _newSeller + ) external override onlyFromCashier { bytes32 promiseKey = ordersPromise[_tokenIdSupply]; promises[promiseKey].seller = _newSeller; } @@ -740,14 +839,13 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { override onlyOwner { - require(_cashierAddress != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - + require(_cashierAddress != address(0), "UNSPECIFIED_ADDRESS"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + cashierAddress = _cashierAddress; - + emit LogCashierSet(_cashierAddress, msg.sender); } - - + /** * @notice Set the general complain period, should be used sparingly as it has significant consequences. Here done simply for demo purposes. * @param _complainPeriod the new value for complain period (in number of seconds) @@ -758,11 +856,10 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { onlyOwner { complainPeriod = _complainPeriod; - + emit LogComplainPeriodChanged(_complainPeriod, msg.sender); } - - + /** * @notice Set the general cancelOrFault period, should be used sparingly as it has significant consequences. Here done simply for demo purposes. * @param _cancelFaultPeriod the new value for cancelOrFault period (in number of seconds) @@ -772,67 +869,60 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { onlyOwner { cancelFaultPeriod = _cancelFaultPeriod; - + emit LogCancelFaultPeriodChanged(_cancelFaultPeriod, msg.sender); - } - - + } + // // // // // // // // - // GETTERS - // // // // // // // // - + // GETTERS + // // // // // // // // + /** * @notice Get the promise ID at specific index * @param _idx Index in the array of promise keys * @return Promise ID */ - function getPromiseKey(uint256 _idx) - public view - returns (bytes32) - { + function getPromiseKey(uint256 _idx) public view returns (bytes32) { return promiseKeys[_idx]; } - - + /** * @notice Get the supply token ID from a voucher token * @param _tokenIdVoucher ID of the voucher token * @return ID of the supply token */ function getIdSupplyFromVoucher(uint256 _tokenIdVoucher) - public pure override + public + pure + override returns (uint256) { return _tokenIdVoucher & MASK_TYPE; } - - + /** * @notice Get the promise ID from a voucher token * @param _tokenIdVoucher ID of the voucher token * @return ID of the promise */ function getPromiseIdFromVoucherId(uint256 _tokenIdVoucher) - public view + public + view returns (bytes32) { - require(_tokenIdVoucher != 0, "UNSPECIFIED_ID"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) - + require(_tokenIdVoucher != 0, "UNSPECIFIED_ID"); //hex"20" FISSION.code(FISSION.Category.Find, FISSION.Status.NotFound_Unequal_OutOfRange) + uint256 tokenIdSupply = getIdSupplyFromVoucher(_tokenIdVoucher); return promises[ordersPromise[tokenIdSupply]].promiseId; } - - + /** * @notice Get the current supply of tokens of an account * @param _account Address to query * @return Balance */ //TODO: might not need it - function getTotalSupply(address _account) - public view - returns (uint256) - { + function getTotalSupply(address _account) public view returns (uint256) { return accountSupply[_account]; } @@ -842,8 +932,8 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @param _owner holder of the Token Supply * @return remaining quantity */ - function getRemQtyForSupply(uint _tokenSupplyId, address _owner) - external + function getRemQtyForSupply(uint256 _tokenSupplyId, address _owner) + external view override returns (uint256) @@ -851,18 +941,27 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { return IERC1155(tokensContract).balanceOf(_owner, _tokenSupplyId); } - /** * @notice Get all necessary funds for a supply token * @param _tokenIdSupply ID of the supply token * @return returns a tuple (Payment amount, Seller's deposit, Buyer's deposit) */ function getOrderCosts(uint256 _tokenIdSupply) - public view override - returns (uint256, uint256, uint256) + public + view + override + returns ( + uint256, + uint256, + uint256 + ) { bytes32 promiseKey = ordersPromise[_tokenIdSupply]; - return (promises[promiseKey].price, promises[promiseKey].depositSe, promises[promiseKey].depositBu); + return ( + promises[promiseKey].price, + promises[promiseKey].depositSe, + promises[promiseKey].depositBu + ); } /** @@ -871,7 +970,9 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @return returns a tuple (Payment amount, Buyer's deposit) */ function getBuyerOrderCosts(uint256 _tokenIdSupply) - public view override + public + view + override returns (uint256, uint256) { bytes32 promiseKey = ordersPromise[_tokenIdSupply]; @@ -879,55 +980,70 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { } /** - * @notice Get Seller deposit + * @notice Get Seller deposit * @param _tokenIdSupply ID of the supply token * @return returns sellers deposit - */ + */ function getSellerDeposit(uint256 _tokenIdSupply) - public view override + public + view + override returns (uint256) { bytes32 promiseKey = ordersPromise[_tokenIdSupply]; return promises[promiseKey].depositSe; } - + /** * @notice Get the current status of a voucher * @param _tokenIdVoucher ID of the voucher token * @return Status of the voucher (via enum) */ function getVoucherStatus(uint256 _tokenIdVoucher) - public view override - returns (uint8, bool, bool) + public + view + override + returns ( + uint8, + bool, + bool + ) { - return (vouchersStatus[_tokenIdVoucher].status, vouchersStatus[_tokenIdVoucher].isPaymentReleased, vouchersStatus[_tokenIdVoucher].isDepositsReleased); + return ( + vouchersStatus[_tokenIdVoucher].status, + vouchersStatus[_tokenIdVoucher].isPaymentReleased, + vouchersStatus[_tokenIdVoucher].isDepositsReleased + ); } - + /** * @notice Get the holder of a voucher * @param _tokenIdVoucher ID of the voucher token * @return Address of the holder - */ + */ function getVoucherHolder(uint256 _tokenIdVoucher) - public view override + public + view + override returns (address) { return IERC721(tokensContract).ownerOf(_tokenIdVoucher); } /** - * @notice Get the holder of a supply - * @param _tokenIdSupply ID of a promise which is mapped to the corresponding Promise - * @return Address of the holder - */ + * @notice Get the holder of a supply + * @param _tokenIdSupply ID of a promise which is mapped to the corresponding Promise + * @return Address of the holder + */ function getSupplyHolder(uint256 _tokenIdSupply) - public view override + public + view + override returns (address) { bytes32 promiseKey = ordersPromise[_tokenIdSupply]; return promises[promiseKey].seller; } - /** * @notice Get the address of the token where the price for the supply is held @@ -935,7 +1051,9 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @return Address of the token */ function getVoucherPriceToken(uint256 _tokenIdSupply) - public view override + public + view + override returns (address) { return paymentDetails[_tokenIdSupply].addressTokenPrice; @@ -947,7 +1065,9 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @return Address of the token */ function getVoucherDepositToken(uint256 _tokenIdSupply) - public view override + public + view + override returns (address) { return paymentDetails[_tokenIdSupply].addressTokenDeposits; @@ -959,24 +1079,28 @@ contract VoucherKernel is IVoucherKernel, Ownable, Pausable, UsingHelpers { * @return payment method */ function getVoucherPaymentMethod(uint256 _tokenIdSupply) - public view override + public + view + override returns (uint8) { return paymentDetails[_tokenIdSupply].paymentMethod; } - - /** - * + + /** + * */ function isInValidityPeriod(uint256 _tokenIdVoucher) - public view + public + view returns (bool) { //check validity period - Promise memory tPromise = promises[getPromiseIdFromVoucherId(_tokenIdVoucher)]; + Promise memory tPromise = + promises[getPromiseIdFromVoucherId(_tokenIdVoucher)]; require(tPromise.validFrom <= block.timestamp, "INVALID_VALIDITY_FROM"); //hex"26" FISSION.code(FISSION.Category.Find, FISSION.Status.Above_Range_Overflow) - require(tPromise.validTo >= block.timestamp, "INVALID_VALIDITY_TO"); //hex"24" FISSION.code(FISSION.Category.Find, FISSION.Status.BelowRange_Underflow) - + require(tPromise.validTo >= block.timestamp, "INVALID_VALIDITY_TO"); //hex"24" FISSION.code(FISSION.Category.Find, FISSION.Status.BelowRange_Underflow) + return true; } -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index b3a85f60..ee08afd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2883,6 +2883,11 @@ "path-type": "^4.0.0" } }, + "dir-to-object": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-to-object/-/dir-to-object-2.0.0.tgz", + "integrity": "sha512-sXs0JKIhymON7T1UZuO2Ud6VTNAx/VTBXIl4+3mjb2RgfOpt+hectX0x04YqPOPdkeOAKoJuKqwqnXXURNPNEA==" + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -6292,10 +6297,79 @@ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=" }, "prettier": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", - "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", - "optional": true + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==" + }, + "prettier-plugin-solidity": { + "version": "1.0.0-beta.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.3.tgz", + "integrity": "sha512-iLbf5ZqwSUqi/BQuRGh+fHy0y3VLX9WayI7qB3wqakSUHItbiKsUKyXbTeho4pfTJVr0D3M4c8BNuEr2OMAOVg==", + "requires": { + "@solidity-parser/parser": "^0.11.0", + "dir-to-object": "^2.0.0", + "emoji-regex": "^9.0.0", + "escape-string-regexp": "^4.0.0", + "prettier": "^2.0.5", + "semver": "^7.3.2", + "solidity-comments-extractor": "^0.0.4", + "string-width": "^4.2.0" + }, + "dependencies": { + "@solidity-parser/parser": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/@solidity-parser/parser/-/parser-0.11.1.tgz", + "integrity": "sha512-H8BSBoKE8EubJa0ONqecA2TviT3TnHeC4NpgnAHSUiuhZoQBfPB4L2P9bs8R6AoTW10Endvh3vc+fomVMIDIYQ==" + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "emoji-regex": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.0.tgz", + "integrity": "sha512-DNc3KFPK18bPdElMJnf/Pkv5TXhxFU3YFDEuGLDRtPmV4rkmCjBkCSEp22u6rBHdSN9Vlp/GK7k98prmE1Jgug==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "semver": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + } + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } + } + } }, "process": { "version": "0.11.10", @@ -6975,6 +7049,12 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "optional": true + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", @@ -6990,6 +7070,11 @@ } } }, + "solidity-comments-extractor": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/solidity-comments-extractor/-/solidity-comments-extractor-0.0.4.tgz", + "integrity": "sha512-58glBODwXIKMaQ7rfcJOrWtFQMMOK28tJ0/LcB5Xhu7WtAxk4UX2fpgKPuaL41XjMp/y0gAa1MTLqk018wuSzA==" + }, "solidity-coverage": { "version": "0.7.13", "resolved": "https://registry.npmjs.org/solidity-coverage/-/solidity-coverage-0.7.13.tgz", diff --git a/package.json b/package.json index 70176fbc..67fb41ef 100644 --- a/package.json +++ b/package.json @@ -10,10 +10,14 @@ "contracts:compile": "truffle compile --all", "contracts:lint": "solhint contracts/**/*.sol -w 27", "contracts:lint-fix": "solhint contracts/**/*.sol -w 27 --fix", - "test:integration": "truffle test --network test", - "test:coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage", + "contracts:format": "prettier --list-different contracts/**/*.sol", + "contracts:format-fix": "prettier --write contracts/**/*.sol", "migrate-dev": "truffle migrate --network=rinkeby", - "verify-dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby" + "verify-dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby", + "tests:format": "prettier --list-different test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", + "tests:format-fix": "prettier --write test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", + "tests:integration": "truffle test --network test", + "tests:coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage" }, "repository": { "type": "git", @@ -34,6 +38,8 @@ "ethereumjs-util": "^7.0.7", "ethers": "5.0.4", "mocha": "^8.2.1", + "prettier": "^2.2.1", + "prettier-plugin-solidity": "^1.0.0-beta.3", "solhint": "^3.3.2", "solidity-coverage": "^0.7.12", "truffle": "5.1.10", diff --git a/test/1_test_fullpath.js b/test/1_test_fullpath.js index a663044e..a3330de3 100644 --- a/test/1_test_fullpath.js +++ b/test/1_test_fullpath.js @@ -1,91 +1,94 @@ -const truffleAssert = require('truffle-assertions') +const truffleAssert = require('truffle-assertions'); // later consider using // https://github.com/OpenZeppelin/openzeppelin-test-helpers -const constants = require("../testHelpers/constants") -const timemachine = require('../testHelpers/timemachine') -const Utils = require('../testHelpers/utils') -const Users = require('../testHelpers/users') +const constants = require('../testHelpers/constants'); +const timemachine = require('../testHelpers/timemachine'); +const Utils = require('../testHelpers/utils'); +const Users = require('../testHelpers/users'); -const ERC1155ERC721 = artifacts.require("ERC1155ERC721") -const VoucherKernel = artifacts.require("VoucherKernel") -const Cashier = artifacts.require("Cashier") -const FundLimitsOracle = artifacts.require('FundLimitsOracle') +const ERC1155ERC721 = artifacts.require('ERC1155ERC721'); +const VoucherKernel = artifacts.require('VoucherKernel'); +const Cashier = artifacts.require('Cashier'); +const FundLimitsOracle = artifacts.require('FundLimitsOracle'); -let snapshot +let snapshot; -contract("Voucher tests", async addresses => { - const users = new Users(addresses) +contract('Voucher tests', async (addresses) => { + const users = new Users(addresses); let contractERC1155ERC721, contractVoucherKernel, contractCashier, - contractFundLimitsOracle - let tokenSupplyKey1, - tokenSupplyKey2, - tokenVoucherKey1, - tokenVoucherKey2 + contractFundLimitsOracle; + let tokenSupplyKey1, tokenSupplyKey2, tokenVoucherKey1, tokenVoucherKey2; before('setup contracts for tests', async () => { - snapshot = await timemachine.takeSnapshot() + snapshot = await timemachine.takeSnapshot(); - const timestamp = await Utils.getCurrTimestamp() - constants.PROMISE_VALID_FROM = timestamp - constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY + const timestamp = await Utils.getCurrTimestamp(); + constants.PROMISE_VALID_FROM = timestamp; + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY; - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new() + contractFundLimitsOracle = await FundLimitsOracle.new(); + contractERC1155ERC721 = await ERC1155ERC721.new(); contractVoucherKernel = await VoucherKernel.new( - contractERC1155ERC721.address) + contractERC1155ERC721.address + ); contractCashier = await Cashier.new( contractVoucherKernel.address, contractERC1155ERC721.address, - contractFundLimitsOracle.address) + contractFundLimitsOracle.address + ); await contractERC1155ERC721.setApprovalForAll( - contractVoucherKernel.address, 'true') + contractVoucherKernel.address, + 'true' + ); await contractERC1155ERC721.setVoucherKernelAddress( - contractVoucherKernel.address) - await contractVoucherKernel.setCashierAddress( - contractCashier.address) + contractVoucherKernel.address + ); + await contractVoucherKernel.setCashierAddress(contractCashier.address); - console.log("Seller: " + users.seller.address) - console.log("Buyer: " + users.buyer.address) - console.log("Attacker: " + users.attacker.address) - console.log() - }) + console.log('Seller: ' + users.seller.address); + console.log('Buyer: ' + users.buyer.address); + console.log('Attacker: ' + users.attacker.address); + console.log(); + }); describe('Direct minting', function () { - it("must fail: unauthorized minting ERC-1155", async () => { + it('must fail: unauthorized minting ERC-1155', async () => { await truffleAssert.reverts( contractERC1155ERC721.mint(users.attacker.address, 666, 1, []), truffleAssert.ErrorType.REVERT - ) - }) + ); + }); - it("must fail: unauthorized minting ERC-721", async () => { + it('must fail: unauthorized minting ERC-721', async () => { await truffleAssert.reverts( contractERC1155ERC721.mint(users.attacker.address, 666), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + }); + }); describe('Orders (aka supply tokens - ERC1155)', () => { - it("adding one new order / promise", async () => { - const txOrder = await contractCashier - .requestCreateOrderETHETH([ + it('adding one new order / promise', async () => { + const txOrder = await contractCashier.requestCreateOrderETHETH( + [ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE1, constants.PROMISE_DEPOSITSE1, constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { + constants.ORDER_QUANTITY1, + ], + { from: users.buyer.address, to: contractCashier.address, - value: constants.PROMISE_DEPOSITSE1 - }) + value: constants.PROMISE_DEPOSITSE1, + } + ); // // would need truffle-events as the event emitted is from a nested // // contract, so truffle-assert doesn't detect it @@ -104,190 +107,223 @@ contract("Voucher tests", async addresses => { txOrder, 'LogOrderCreated', (ev) => { - tokenSupplyKey1 = ev._tokenIdSupply - return ev._seller === users.buyer.address - }, "order1 not created successfully") - - }) - - it("adding second order", async () => { - const txOrder = await contractCashier - .requestCreateOrderETHETH([ + tokenSupplyKey1 = ev._tokenIdSupply; + return ev._seller === users.buyer.address; + }, + 'order1 not created successfully' + ); + }); + + it('adding second order', async () => { + const txOrder = await contractCashier.requestCreateOrderETHETH( + [ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE2, constants.PROMISE_DEPOSITSE2, constants.PROMISE_DEPOSITBU2, - constants.ORDER_QUANTITY2 - ], { + constants.ORDER_QUANTITY2, + ], + { from: users.buyer.address, to: contractCashier.address, - value: constants.PROMISE_DEPOSITSE2 - }) + value: constants.PROMISE_DEPOSITSE2, + } + ); truffleAssert.eventEmitted( txOrder, 'LogOrderCreated', (ev) => { - tokenSupplyKey2 = ev._tokenIdSupply - return ev._seller === users.buyer.address - }, "order2 not created successfully") - }) - - it("fill one order (aka buy a voucher)", async () => { - const txFillOrder = await contractCashier - .requestVoucherETHETH( - tokenSupplyKey1, - users.buyer.address, { - from: users.buyer.address, - to: contractCashier.address, - value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1 - }) - const internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + tokenSupplyKey2 = ev._tokenIdSupply; + return ev._seller === users.buyer.address; + }, + 'order2 not created successfully' + ); + }); + + it('fill one order (aka buy a voucher)', async () => { + const txFillOrder = await contractCashier.requestVoucherETHETH( + tokenSupplyKey1, + users.buyer.address, + { + from: users.buyer.address, + to: contractCashier.address, + value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1, + } + ); + const internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); truffleAssert.eventEmitted( internalTx, 'LogVoucherDelivered', (ev) => { - return ev._issuer === users.buyer.address - }, "order1 not created successfully") - - const filtered = internalTx.logs - .filter(e => e.event === 'LogVoucherDelivered')[0] - - tokenVoucherKey1 = filtered.returnValues['_tokenIdVoucher'] - }) - - it("fill second order (aka buy a voucher)", async () => { - const txFillOrder = await contractCashier - .requestVoucherETHETH( - tokenSupplyKey2, - users.buyer.address, { - from: users.buyer.address, - to: contractCashier.address, - value: constants.PROMISE_PRICE2 + constants.PROMISE_DEPOSITBU2 - }) - const internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + return ev._issuer === users.buyer.address; + }, + 'order1 not created successfully' + ); + + const filtered = internalTx.logs.filter( + (e) => e.event === 'LogVoucherDelivered' + )[0]; + + tokenVoucherKey1 = filtered.returnValues['_tokenIdVoucher']; + }); + + it('fill second order (aka buy a voucher)', async () => { + const txFillOrder = await contractCashier.requestVoucherETHETH( + tokenSupplyKey2, + users.buyer.address, + { + from: users.buyer.address, + to: contractCashier.address, + value: constants.PROMISE_PRICE2 + constants.PROMISE_DEPOSITBU2, + } + ); + const internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); truffleAssert.eventEmitted( internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey2 = ev._tokenIdVoucher - return ev._tokenIdSupply.toString() === tokenSupplyKey2.toString() - }, "order1 not filled successfully") - }) - - it("must fail: adding new order with incorrect value sent", - async () => { - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHETH([ + tokenVoucherKey2 = ev._tokenIdVoucher; + return ev._tokenIdSupply.toString() === tokenSupplyKey2.toString(); + }, + 'order1 not filled successfully' + ); + }); + + it('must fail: adding new order with incorrect value sent', async () => { + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHETH( + [ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE1, constants.PROMISE_DEPOSITSE1, constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { + constants.ORDER_QUANTITY1, + ], + { from: users.buyer.address, to: contractCashier.address, - value: 0 - }), - truffleAssert.ErrorType.REVERT - ) - }) + value: 0, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - it("must fail: fill an order with incorrect value", async () => { + it('must fail: fill an order with incorrect value', async () => { await truffleAssert.reverts( contractCashier.requestVoucherETHETH( tokenSupplyKey1, - users.buyer.address, { + users.buyer.address, + { from: users.buyer.address, to: contractCashier.address, - value: 0 - }), + value: 0, + } + ), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + }); + }); describe('Voucher tokens', function () { - it("redeeming one voucher", async () => { - const txRedeem = await contractVoucherKernel - .redeem(tokenVoucherKey1, { from: users.buyer.address }) + it('redeeming one voucher', async () => { + const txRedeem = await contractVoucherKernel.redeem(tokenVoucherKey1, { + from: users.buyer.address, + }); truffleAssert.eventEmitted( txRedeem, 'LogVoucherRedeemed', (ev) => { - return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString() - }, "voucher not redeemed successfully") - }) + return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString(); + }, + 'voucher not redeemed successfully' + ); + }); - it("mark non-redeemed voucher as expired", async () => { - const statusBefore = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey2) + it('mark non-redeemed voucher as expired', async () => { + const statusBefore = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey2 + ); // [1000.0000] = hex"80" = 128 = COMMITTED assert.equal( web3.utils.toHex(statusBefore[0]), web3.utils.numberToHex(128), - "initial voucher status not as expected (COMMITTED)") + 'initial voucher status not as expected (COMMITTED)' + ); // fast-forward for a year - await timemachine.advanceTimeSeconds( - constants.SECONDS_IN_DAY * 365) - await contractVoucherKernel.triggerExpiration(tokenVoucherKey2) + await timemachine.advanceTimeSeconds(constants.SECONDS_IN_DAY * 365); + await contractVoucherKernel.triggerExpiration(tokenVoucherKey2); - const statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey2) + const statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey2 + ); //[1001.0000] = hex"90" = 144 = EXPIRED assert.equal( web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(144), - "end voucher status not as expected (EXPIRED)") - }) + 'end voucher status not as expected (EXPIRED)' + ); + }); - it("mark voucher as finalized", async () => { - const txFinalize = await contractVoucherKernel - .triggerFinalizeVoucher(tokenVoucherKey1, { from: users.buyer.address }) + it('mark voucher as finalized', async () => { + const txFinalize = await contractVoucherKernel.triggerFinalizeVoucher( + tokenVoucherKey1, + {from: users.buyer.address} + ); truffleAssert.eventEmitted( txFinalize, 'LogFinalizeVoucher', (ev) => { - return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString() - }, "voucher not finalized successfully") - }) + return ev._tokenIdVoucher.toString() === tokenVoucherKey1.toString(); + }, + 'voucher not finalized successfully' + ); + }); - it("must fail: unauthorized redemption", async () => { + it('must fail: unauthorized redemption', async () => { await truffleAssert.reverts( - contractVoucherKernel.redeem( - tokenVoucherKey1, { from: users.attacker.address }), + contractVoucherKernel.redeem(tokenVoucherKey1, { + from: users.attacker.address, + }), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + }); + }); describe('Withdrawals', function () { - it("withdraw the escrowed payment from one redeemed voucher", - async () => { - const escrowedBefore = await contractCashier - .getEscrowAmount.call(users.buyer.address) + it('withdraw the escrowed payment from one redeemed voucher', async () => { + const escrowedBefore = await contractCashier.getEscrowAmount.call( + users.buyer.address + ); - await contractCashier.withdraw(tokenVoucherKey1) + await contractCashier.withdraw(tokenVoucherKey1); - const escrowedAfter = await contractCashier - .getEscrowAmount.call(users.buyer.address) + const escrowedAfter = await contractCashier.getEscrowAmount.call( + users.buyer.address + ); - assert.isBelow( - escrowedAfter.toNumber(), - escrowedBefore.toNumber(), - "escrowed amount not decreased") - }) + assert.isBelow( + escrowedAfter.toNumber(), + escrowedBefore.toNumber(), + 'escrowed amount not decreased' + ); + }); // it("must fail: unauthorized withdrawal of escrowed pool", async () => { // await truffleAssert.reverts( @@ -295,315 +331,356 @@ contract("Voucher tests", async addresses => { // truffleAssert.ErrorType.REVERT // ); // }); - - }) + }); after(async () => { - await timemachine.revertToSnapShot(snapshot.id) - }) -}) + await timemachine.revertToSnapShot(snapshot.id); + }); +}); -contract("Voucher tests - UNHAPPY PATH", async addresses => { - const users = new Users(addresses) +contract('Voucher tests - UNHAPPY PATH', async (addresses) => { + const users = new Users(addresses); let contractERC1155ERC721, contractVoucherKernel, contractCashier, - contractFundLimitsOracle - let tokenSupplyKey1, - tokenVoucherKey1 + contractFundLimitsOracle; + let tokenSupplyKey1, tokenVoucherKey1; - before('setup promise dates based on the block timestamp', - async () => { - snapshot = await timemachine.takeSnapshot() + before('setup promise dates based on the block timestamp', async () => { + snapshot = await timemachine.takeSnapshot(); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - constants.PROMISE_VALID_FROM = timestamp - constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY - }) + constants.PROMISE_VALID_FROM = timestamp; + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY; + }); beforeEach('setup contracts for tests', async () => { - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new() + contractFundLimitsOracle = await FundLimitsOracle.new(); + contractERC1155ERC721 = await ERC1155ERC721.new(); contractVoucherKernel = await VoucherKernel.new( - contractERC1155ERC721.address) + contractERC1155ERC721.address + ); contractCashier = await Cashier.new( contractVoucherKernel.address, contractERC1155ERC721.address, - contractFundLimitsOracle.address) + contractFundLimitsOracle.address + ); await contractERC1155ERC721.setApprovalForAll( - contractVoucherKernel.address, 'true') + contractVoucherKernel.address, + 'true' + ); await contractERC1155ERC721.setVoucherKernelAddress( - contractVoucherKernel.address) - await contractVoucherKernel.setCashierAddress( - contractCashier.address) + contractVoucherKernel.address + ); + await contractVoucherKernel.setCashierAddress(contractCashier.address); - const txOrder = await contractCashier - .requestCreateOrderETHETH([ + const txOrder = await contractCashier.requestCreateOrderETHETH( + [ constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.PROMISE_PRICE1, constants.PROMISE_DEPOSITSE1, constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { + constants.ORDER_QUANTITY1, + ], + { from: users.seller.address, to: contractCashier.address, - value: constants.PROMISE_DEPOSITSE1 - }) + value: constants.PROMISE_DEPOSITSE1, + } + ); truffleAssert.eventEmitted( txOrder, 'LogOrderCreated', (ev) => { - tokenSupplyKey1 = ev._tokenIdSupply - return ev._seller === users.seller.address - }, "order1 not created successfully") - - const txFillOrder = await contractCashier - .requestVoucherETHETH( - tokenSupplyKey1, - users.seller.address, - { - from: users.buyer.address, - to: contractCashier.address, - value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1 - }) - const internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + tokenSupplyKey1 = ev._tokenIdSupply; + return ev._seller === users.seller.address; + }, + 'order1 not created successfully' + ); + + const txFillOrder = await contractCashier.requestVoucherETHETH( + tokenSupplyKey1, + users.seller.address, + { + from: users.buyer.address, + to: contractCashier.address, + value: constants.PROMISE_PRICE1 + constants.PROMISE_DEPOSITBU1, + } + ); + const internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); truffleAssert.eventEmitted( internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey1 = ev._tokenIdVoucher - return ev._issuer === users.seller.address - }, "order1 not created successfully") - }) + tokenVoucherKey1 = ev._tokenIdVoucher; + return ev._issuer === users.seller.address; + }, + 'order1 not created successfully' + ); + }); describe('Wait periods', () => { - it("change complain period", async () => { + it('change complain period', async () => { const complainPeriodSeconds = - constants.PROMISE_CHALLENGE_PERIOD * constants.SECONDS_IN_DAY + constants.PROMISE_CHALLENGE_PERIOD * constants.SECONDS_IN_DAY; - const txChangePeriod = await contractVoucherKernel - .setComplainPeriod(complainPeriodSeconds) + const txChangePeriod = await contractVoucherKernel.setComplainPeriod( + complainPeriodSeconds + ); truffleAssert.eventEmitted( txChangePeriod, 'LogComplainPeriodChanged', (ev) => { - return ev._newComplainPeriod.toString() === + return ( + ev._newComplainPeriod.toString() === complainPeriodSeconds.toString() - }, "complain period not changed successfully") - }) - - it("must fail: unauthorized change of complain period", - async () => { - const complainPeriodSeconds = - constants.PROMISE_CHALLENGE_PERIOD * constants.SECONDS_IN_DAY - - await truffleAssert.reverts( - contractVoucherKernel.setComplainPeriod( - complainPeriodSeconds, { from: users.attacker.address }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("change cancelOrFault period", async () => { + ); + }, + 'complain period not changed successfully' + ); + }); + + it('must fail: unauthorized change of complain period', async () => { + const complainPeriodSeconds = + constants.PROMISE_CHALLENGE_PERIOD * constants.SECONDS_IN_DAY; + + await truffleAssert.reverts( + contractVoucherKernel.setComplainPeriod(complainPeriodSeconds, { + from: users.attacker.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + + it('change cancelOrFault period', async () => { const cancelFaultPeriodSeconds = - constants.PROMISE_CANCELORFAULT_PERIOD * constants.SECONDS_IN_DAY - const txChangePeriod = await contractVoucherKernel - .setCancelFaultPeriod(cancelFaultPeriodSeconds) + constants.PROMISE_CANCELORFAULT_PERIOD * constants.SECONDS_IN_DAY; + const txChangePeriod = await contractVoucherKernel.setCancelFaultPeriod( + cancelFaultPeriodSeconds + ); await truffleAssert.eventEmitted( txChangePeriod, 'LogCancelFaultPeriodChanged', (ev) => { - return ev._newCancelFaultPeriod.toString() === + return ( + ev._newCancelFaultPeriod.toString() === cancelFaultPeriodSeconds.toString() - }, "complain period not changed successfully") - }) - - it("must fail: unauthorized change of cancelOrFault period", - async () => { - const cancelFaultPeriodSeconds = - constants.PROMISE_CANCELORFAULT_PERIOD * constants.SECONDS_IN_DAY - await truffleAssert.reverts( - contractVoucherKernel.setCancelFaultPeriod( - cancelFaultPeriodSeconds, { from: users.attacker.address }), - truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + }, + 'complain period not changed successfully' + ); + }); + + it('must fail: unauthorized change of cancelOrFault period', async () => { + const cancelFaultPeriodSeconds = + constants.PROMISE_CANCELORFAULT_PERIOD * constants.SECONDS_IN_DAY; + await truffleAssert.reverts( + contractVoucherKernel.setCancelFaultPeriod(cancelFaultPeriodSeconds, { + from: users.attacker.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + }); describe('Refunds ...', function () { - it("refunding one voucher", async () => { - const txRefund = await contractVoucherKernel.refund( - tokenVoucherKey1, { - from: users.buyer.address - }) + it('refunding one voucher', async () => { + const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + from: users.buyer.address, + }); - const statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey1) + const statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey1 + ); // [1010.0000] = hex"A0" = 160 = REFUND assert.equal( web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(160), - "end voucher status not as expected (REFUNDED)") - }) - - it("refunding one voucher, then complain", async () => { - const txRefund = await contractVoucherKernel.refund( - tokenVoucherKey1, { - from: users.buyer.address - }) + 'end voucher status not as expected (REFUNDED)' + ); + }); + + it('refunding one voucher, then complain', async () => { + const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + from: users.buyer.address, + }); const txComplain = await contractVoucherKernel.complain( - tokenVoucherKey1, { - from: users.buyer.address - }) + tokenVoucherKey1, + { + from: users.buyer.address, + } + ); - const statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey1) + const statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey1 + ); // [1010.1000] = hex"A8" = 168 = REFUND_COMPLAIN assert.equal( web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(168), - "end voucher status not as expected (REFUNDED_COMPLAINED)") - }) - - it("refunding one voucher, then complain, then cancel/fault", - async () => { - const txRefund = await contractVoucherKernel.refund( - tokenVoucherKey1, { - from: users.buyer.address - }) - const txComplain = await contractVoucherKernel.complain( - tokenVoucherKey1, { - from: users.buyer.address - }) - const txCoF = await contractVoucherKernel.cancelOrFault( - tokenVoucherKey1, { - from: users.seller.address - }) - - const statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey1) - - // [1010.1100] = hex"AC" = 172 = REFUND_COMPLAIN_COF - assert.equal( - web3.utils.toHex(statusAfter[0]), - web3.utils.numberToHex(172), - "end voucher status not as expected " + - "(REFUNDED_COMPLAINED_CANCELORFAULT)") - }) - - it("must fail: refund then try to redeem", async () => { - const txRefund = await contractVoucherKernel.refund( - tokenVoucherKey1, { - from: users.buyer.address - }) + 'end voucher status not as expected (REFUNDED_COMPLAINED)' + ); + }); + + it('refunding one voucher, then complain, then cancel/fault', async () => { + const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + from: users.buyer.address, + }); + const txComplain = await contractVoucherKernel.complain( + tokenVoucherKey1, + { + from: users.buyer.address, + } + ); + const txCoF = await contractVoucherKernel.cancelOrFault( + tokenVoucherKey1, + { + from: users.seller.address, + } + ); + + const statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey1 + ); + + // [1010.1100] = hex"AC" = 172 = REFUND_COMPLAIN_COF + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(172), + 'end voucher status not as expected ' + + '(REFUNDED_COMPLAINED_CANCELORFAULT)' + ); + }); + + it('must fail: refund then try to redeem', async () => { + const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + from: users.buyer.address, + }); await truffleAssert.reverts( - contractVoucherKernel.redeem( - tokenVoucherKey1, { from: users.buyer.address }), + contractVoucherKernel.redeem(tokenVoucherKey1, { + from: users.buyer.address, + }), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + }); + }); describe('Cancel/Fault by the seller ...', () => { - it("canceling one voucher", async () => { - const txCoF = await contractVoucherKernel - .cancelOrFault( - tokenVoucherKey1, { - from: users.seller.address - }) + it('canceling one voucher', async () => { + const txCoF = await contractVoucherKernel.cancelOrFault( + tokenVoucherKey1, + { + from: users.seller.address, + } + ); - const statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey1) + const statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey1 + ); // [1000.0100] = hex"84" = 132 = CANCELORFAULT assert.equal( web3.utils.toHex(statusAfter[0]), web3.utils.numberToHex(132), - "end voucher status not as expected (CANCELORFAULT)") - }) + 'end voucher status not as expected (CANCELORFAULT)' + ); + }); - it("must fail: cancel/fault then try to redeem", async () => { - const txCoF = await contractVoucherKernel - .cancelOrFault( - tokenVoucherKey1, { - from: users.seller.address - }) + it('must fail: cancel/fault then try to redeem', async () => { + const txCoF = await contractVoucherKernel.cancelOrFault( + tokenVoucherKey1, + { + from: users.seller.address, + } + ); await truffleAssert.reverts( - contractVoucherKernel.redeem( - tokenVoucherKey1, { from: users.buyer.address }), + contractVoucherKernel.redeem(tokenVoucherKey1, { + from: users.buyer.address, + }), truffleAssert.ErrorType.REVERT - ) - }) - - }) + ); + }); + }); describe('Expirations (one universal test) ...', () => { - it("Expired, then complain, then Cancel/Fault, then try to redeem", - async () => { - // fast-forward for three days - const secondsInThreeDays = constants.SECONDS_IN_DAY * 3 - await timemachine.advanceTimeSeconds(secondsInThreeDays) - - await contractVoucherKernel.triggerExpiration(tokenVoucherKey1) - - let statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey1) - - // [1001.0000] = hex"90" = 144 = EXPIRED - assert.equal( - web3.utils.toHex(statusAfter[0]), - web3.utils.numberToHex(144), - "end voucher status not as expected (EXPIRED)") - - const txComplain = await contractVoucherKernel - .complain(tokenVoucherKey1, { from: users.buyer.address }) - - statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey1) - - // [1001.1000] = hex"98" = 152 = EXPIRED_COMPLAIN - assert.equal( - web3.utils.toHex(statusAfter[0]), - web3.utils.numberToHex(152), - "end voucher status not as expected (EXPIRED_COMPLAINED)") - - // in the same test, because the EVM time machine is funky ... - const txCoF = await contractVoucherKernel - .cancelOrFault(tokenVoucherKey1, { from: users.seller.address }) - - statusAfter = await contractVoucherKernel - .getVoucherStatus.call(tokenVoucherKey1) - - // [1001.1000] = hex"9C" = 156 = EXPIRED_COMPLAINED_CANCELORFAULT - assert.equal( - web3.utils.toHex(statusAfter[0]), - web3.utils.numberToHex(156), - "end voucher status not as expected " + - "(EXPIRED_COMPLAINED_CANCELORFAULT)") - - // in the same test, because the EVM time machine is funky ... - await truffleAssert.reverts( - contractVoucherKernel.redeem( - tokenVoucherKey1, { from: users.buyer.address }), - truffleAssert.ErrorType.REVERT - ) - }) + it('Expired, then complain, then Cancel/Fault, then try to redeem', async () => { + // fast-forward for three days + const secondsInThreeDays = constants.SECONDS_IN_DAY * 3; + await timemachine.advanceTimeSeconds(secondsInThreeDays); + + await contractVoucherKernel.triggerExpiration(tokenVoucherKey1); + + let statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey1 + ); + + // [1001.0000] = hex"90" = 144 = EXPIRED + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(144), + 'end voucher status not as expected (EXPIRED)' + ); + + const txComplain = await contractVoucherKernel.complain( + tokenVoucherKey1, + {from: users.buyer.address} + ); + + statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey1 + ); + + // [1001.1000] = hex"98" = 152 = EXPIRED_COMPLAIN + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(152), + 'end voucher status not as expected (EXPIRED_COMPLAINED)' + ); + + // in the same test, because the EVM time machine is funky ... + const txCoF = await contractVoucherKernel.cancelOrFault( + tokenVoucherKey1, + {from: users.seller.address} + ); + + statusAfter = await contractVoucherKernel.getVoucherStatus.call( + tokenVoucherKey1 + ); + + // [1001.1000] = hex"9C" = 156 = EXPIRED_COMPLAINED_CANCELORFAULT + assert.equal( + web3.utils.toHex(statusAfter[0]), + web3.utils.numberToHex(156), + 'end voucher status not as expected ' + + '(EXPIRED_COMPLAINED_CANCELORFAULT)' + ); + + // in the same test, because the EVM time machine is funky ... + await truffleAssert.reverts( + contractVoucherKernel.redeem(tokenVoucherKey1, { + from: users.buyer.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); after(async () => { - await timemachine.revertToSnapShot(snapshot.id) - }) - }) -}) + await timemachine.revertToSnapShot(snapshot.id); + }); + }); +}); diff --git a/test/2_test_fullpath_with_permit.js b/test/2_test_fullpath_with_permit.js index 62e01c6f..1d62b860 100644 --- a/test/2_test_fullpath_with_permit.js +++ b/test/2_test_fullpath_with_permit.js @@ -1,110 +1,116 @@ -const { assert } = require("chai") -const { ecsign } = require('ethereumjs-util') -const truffleAssert = require('truffle-assertions') +const {assert} = require('chai'); +const {ecsign} = require('ethereumjs-util'); +const truffleAssert = require('truffle-assertions'); // later consider using // https://github.com/OpenZeppelin/openzeppelin-test-helpers -const constants = require("../testHelpers/constants") -const timemachine = require('../testHelpers/timemachine') -const Users = require('../testHelpers/users') -const Utils = require('../testHelpers/utils') -const UtilsBuilder = require('../testHelpers/utilsBuilder') -const { toWei, getApprovalDigest } = require('../testHelpers/permitUtils') +const constants = require('../testHelpers/constants'); +const timemachine = require('../testHelpers/timemachine'); +const Users = require('../testHelpers/users'); +const Utils = require('../testHelpers/utils'); +const UtilsBuilder = require('../testHelpers/utilsBuilder'); +const {toWei, getApprovalDigest} = require('../testHelpers/permitUtils'); -const ERC1155ERC721 = artifacts.require("ERC1155ERC721") -const VoucherKernel = artifacts.require("VoucherKernel") -const Cashier = artifacts.require("Cashier") -const BosonToken = artifacts.require('BosonTokenPrice') -const FundLimitsOracle = artifacts.require('FundLimitsOracle') +const ERC1155ERC721 = artifacts.require('ERC1155ERC721'); +const VoucherKernel = artifacts.require('VoucherKernel'); +const Cashier = artifacts.require('Cashier'); +const BosonToken = artifacts.require('BosonTokenPrice'); +const FundLimitsOracle = artifacts.require('FundLimitsOracle'); -const BN = web3.utils.BN +const BN = web3.utils.BN; -let utils +let utils; -contract("Cashier && VK", async addresses => { - const users = new Users(addresses) +contract('Cashier && VK', async (addresses) => { + const users = new Users(addresses); let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit, - contractFundLimitsOracle - let tokenSupplyKey, - tokenVoucherKey + contractFundLimitsOracle; + let tokenSupplyKey, tokenVoucherKey; - const ZERO = new BN(0) - const ONE_VOUCHER = 1 - const deadline = toWei(1) + const ZERO = new BN(0); + const ONE_VOUCHER = 1; + const deadline = toWei(1); - let timestamp + let timestamp; let distributedAmounts = { buyerAmount: new BN(0), sellerAmount: new BN(0), - escrowAmount: new BN(0) - } + escrowAmount: new BN(0), + }; - async function deployContracts () { - const timestamp = await Utils.getCurrTimestamp() - const sixtySeconds = 60 + async function deployContracts() { + const timestamp = await Utils.getCurrTimestamp(); + const sixtySeconds = 60; - constants.PROMISE_VALID_FROM = timestamp - constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY + constants.PROMISE_VALID_FROM = timestamp; + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY; - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new() + contractFundLimitsOracle = await FundLimitsOracle.new(); + contractERC1155ERC721 = await ERC1155ERC721.new(); contractVoucherKernel = await VoucherKernel.new( - contractERC1155ERC721.address) + contractERC1155ERC721.address + ); contractCashier = await Cashier.new( contractVoucherKernel.address, contractERC1155ERC721.address, - contractFundLimitsOracle.address) - - contractBSNTokenPrice = await BosonToken.new("BosonTokenPrice", "BPRC") - contractBSNTokenDeposit = await BosonToken.new("BosonTokenDeposit", "BDEP") - - await contractERC1155ERC721 - .setApprovalForAll(contractVoucherKernel.address, 'true') - await contractERC1155ERC721 - .setVoucherKernelAddress(contractVoucherKernel.address) - await contractVoucherKernel - .setCashierAddress(contractCashier.address) - - await contractERC1155ERC721 - .setCashierContract(contractCashier.address) - await contractCashier - .setTokenContractAddress(contractERC1155ERC721.address) - - await contractVoucherKernel.setComplainPeriod(sixtySeconds) - await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds) - - await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenPrice.address, constants.TOKEN_LIMIT) - await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenDeposit.address, constants.TOKEN_LIMIT) - await contractFundLimitsOracle - .setETHLimit(constants.ETHER_LIMIT) + contractFundLimitsOracle.address + ); + + contractBSNTokenPrice = await BosonToken.new('BosonTokenPrice', 'BPRC'); + contractBSNTokenDeposit = await BosonToken.new('BosonTokenDeposit', 'BDEP'); + + await contractERC1155ERC721.setApprovalForAll( + contractVoucherKernel.address, + 'true' + ); + await contractERC1155ERC721.setVoucherKernelAddress( + contractVoucherKernel.address + ); + await contractVoucherKernel.setCashierAddress(contractCashier.address); + + await contractERC1155ERC721.setCashierContract(contractCashier.address); + await contractCashier.setTokenContractAddress( + contractERC1155ERC721.address + ); + + await contractVoucherKernel.setComplainPeriod(sixtySeconds); + await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds); + + await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenPrice.address, + constants.TOKEN_LIMIT + ); + await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenDeposit.address, + constants.TOKEN_LIMIT + ); + await contractFundLimitsOracle.setETHLimit(constants.ETHER_LIMIT); } describe('TOKEN SUPPLY CREATION (Voucher batch creation)', () => { - let remQty = constants.QTY_10 - let vouchersToBuy = 5 + let remQty = constants.QTY_10; + let vouchersToBuy = 5; const paymentMethods = { ETHETH: 1, ETHTKN: 2, TKNETH: 3, - TKNTKN: 4 - } + TKNTKN: 4, + }; afterEach(() => { - remQty = constants.QTY_10 - }) + remQty = constants.QTY_10; + }); - describe("ETHETH", () => { + describe('ETHETH', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ETHETH() @@ -112,177 +118,196 @@ contract("Cashier && VK", async addresses => { contractERC1155ERC721, contractVoucherKernel, contractCashier, - constants.QTY_10) + constants.QTY_10 + ); - timestamp = await Utils.getCurrTimestamp() + timestamp = await Utils.getCurrTimestamp(); tokenSupplyKey = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_10) - }) - - it("ESCROW has correct initial balance", async () => { - const expectedBalance = - new BN(constants.seller_deposit).mul(new BN(remQty)) - const escrowAmount = await contractCashier - .getEscrowAmount(users.seller.address) + constants.QTY_10 + ); + }); + + it('ESCROW has correct initial balance', async () => { + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(remQty) + ); + const escrowAmount = await contractCashier.getEscrowAmount( + users.seller.address + ); assert.isTrue( escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) + 'Escrow amount is incorrect' + ); + }); - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + it('Get correct remaining qty for supply', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey); + remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, --remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); } - }) + }); - it("Should create payment method ETHETH", async () => { - timestamp = await Utils.getCurrTimestamp() + it('Should create payment method ETHETH', async () => { + timestamp = await Utils.getCurrTimestamp(); - let tokenSupplyKey = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_10) + let tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ); - const paymentDetails = await contractVoucherKernel - .paymentDetails(tokenSupplyKey) + const paymentDetails = await contractVoucherKernel.paymentDetails( + tokenSupplyKey + ); assert.equal( paymentDetails.paymentMethod.toString(), paymentMethods.ETHETH, - "Payment Method ETHETH not set correctly") + 'Payment Method ETHETH not set correctly' + ); assert.equal( paymentDetails.addressTokenPrice.toString(), constants.ZERO_ADDRESS, - "ETHETH Method Price Token Address mismatch") + 'ETHETH Method Price Token Address mismatch' + ); assert.equal( paymentDetails.addressTokenDeposits.toString(), constants.ZERO_ADDRESS, - "ETHETH Method Deposit Token Address mismatch") - }) + 'ETHETH Method Deposit Token Address mismatch' + ); + }); - it("[NEGATIVE] Should fail if additional token address is provided", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + it('[NEGATIVE] Should fail if additional token address is provided', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); - timestamp = await Utils.getCurrTimestamp() + timestamp = await Utils.getCurrTimestamp(); - await truffleAssert.fails( - contractCashier.requestCreateOrderETHETH( - contractBSNTokenDeposit.address, - [ - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, - value: txValue - } - ) + await truffleAssert.fails( + contractCashier.requestCreateOrderETHETH( + contractBSNTokenDeposit.address, + [ + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue, + } ) - }) + ); + }); - it("[NEGATIVE] Should not create a supply if price is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + it('[NEGATIVE] Should not create a supply if price is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHETH( - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.ABOVE_ETH_LIMIT, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, - value: txValue - } - ), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHETH( + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_ETH_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + it('[NEGATIVE] Should not create a supply if depositBu is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHETH( - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.ABOVE_ETH_LIMIT, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, - value: txValue - } - ), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHETH( + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_ETH_LIMIT, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) + it('[NEGATIVE] Should not create a supply if depositSe is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHETH( - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.ABOVE_ETH_LIMIT, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, - value: txValue - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHETH( + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_ETH_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("[WITH PERMIT]", () => { - describe("ETHTKN", () => { + describe('[WITH PERMIT]', () => { + describe('ETHTKN', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() @@ -292,21 +317,25 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const tokensToMint = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_20)) + const tokensToMint = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_20) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.seller.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.buyer.address, - tokensToMint) + tokensToMint + ); - timestamp = await Utils.getCurrTimestamp() + timestamp = await Utils.getCurrTimestamp(); tokenSupplyKey = await utils.createOrder( users.seller, @@ -314,281 +343,318 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) - }) + ); + }); - it("ESCROW has correct initial balance", async () => { - const expectedBalance = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_10)) - const escrowAmount = await contractBSNTokenDeposit - .balanceOf(contractCashier.address) + it('ESCROW has correct initial balance', async () => { + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_10) + ); + const escrowAmount = await contractBSNTokenDeposit.balanceOf( + contractCashier.address + ); assert.isTrue( escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) + 'Escrow amount is incorrect' + ); + }); - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + it('Get correct remaining qty for supply', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey); + remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, --remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); } - }) + }); - it("Should create payment method ETHTKN", async () => { + it('Should create payment method ETHTKN', async () => { tokenSupplyKey = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) + ); - const paymentDetails = await contractVoucherKernel - .paymentDetails(tokenSupplyKey) + const paymentDetails = await contractVoucherKernel.paymentDetails( + tokenSupplyKey + ); assert.equal( paymentDetails.paymentMethod.toString(), paymentMethods.ETHTKN, - "Payment Method ETHTKN not set correctly") + 'Payment Method ETHTKN not set correctly' + ); assert.equal( paymentDetails.addressTokenPrice.toString(), constants.ZERO_ADDRESS, - "ETHTKN Method Price Token Address mismatch") + 'ETHTKN Method Price Token Address mismatch' + ); assert.equal( paymentDetails.addressTokenDeposits.toString(), contractBSNTokenDeposit.address, - "ETHTKN Method Deposit Token Address mismatch") - }) - - it("[NEGATIVE] Should fail if token deposit contract address is not provided", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.fails( - contractCashier.requestCreateOrderETHTKNWithPermit( - '', - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ) - ) - }) + 'ETHTKN Method Deposit Token Address mismatch' + ); + }); + + it('[NEGATIVE] Should fail if token deposit contract address is not provided', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - it("[NEGATIVE] Should revert if token deposit contract address is zero address", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + await truffleAssert.fails( + contractCashier.requestCreateOrderETHTKNWithPermit( + '', txValue, - nonce, - deadline + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } ) + ); + }); + + it('[NEGATIVE] Should revert if token deposit contract address is zero address', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHTKNWithPermit( - constants.ZERO_ADDRESS, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if price is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) - const deadline = toWei(1) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); + + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHTKNWithPermit( + constants.ZERO_ADDRESS, txValue, - nonce, - deadline - ) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create a supply if price is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + const deadline = toWei(1); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHTKNWithPermit( - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.ABOVE_ETH_LIMIT, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) - const deadline = toWei(1) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); + + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHTKNWithPermit( + contractBSNTokenDeposit.address, txValue, - nonce, - deadline - ) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_ETH_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create a supply if depositBu is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + const deadline = toWei(1); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHTKNWithPermit( - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.ABOVE_TOKEN_LIMIT, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) - const deadline = toWei(1) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); + + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHTKNWithPermit( + contractBSNTokenDeposit.address, txValue, - nonce, - deadline - ) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_TOKEN_LIMIT, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create a supply if depositSe is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + const deadline = toWei(1); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderETHTKNWithPermit( - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.ABOVE_TOKEN_LIMIT, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); + + await truffleAssert.reverts( + contractCashier.requestCreateOrderETHTKNWithPermit( + contractBSNTokenDeposit.address, + txValue, + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_TOKEN_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNETH", () => { + describe('TKNETH', () => { before(async () => { - await deployContracts() + await deployContracts(); - utils = UtilsBuilder - .create() + utils = UtilsBuilder.create() .ERC20withPermit() .TKNETH() .build( @@ -596,16 +662,19 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - '') + '' + ); - timestamp = await Utils.getCurrTimestamp() + timestamp = await Utils.getCurrTimestamp(); - const tokensToMint = - new BN(constants.product_price).mul(new BN(constants.QTY_10)) + const tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenPrice', users.buyer.address, - tokensToMint) + tokensToMint + ); tokenSupplyKey = await utils.createOrder( users.seller, @@ -613,214 +682,236 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) - }) + ); + }); - it("ESCROW has correct initial balance", async () => { - const expectedBalance = - new BN(constants.seller_deposit).mul(new BN(remQty)) - const escrowAmount = await contractCashier - .getEscrowAmount(users.seller.address) + it('ESCROW has correct initial balance', async () => { + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(remQty) + ); + const escrowAmount = await contractCashier.getEscrowAmount( + users.seller.address + ); assert.isTrue( escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) + 'Escrow amount is incorrect' + ); + }); - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + it('Get correct remaining qty for supply', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey); + remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, --remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); } - }) + }); - it("Should create payment method TKNETH", async () => { + it('Should create payment method TKNETH', async () => { tokenSupplyKey = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_1 - ) + ); - const paymentDetails = await contractVoucherKernel - .paymentDetails(tokenSupplyKey) + const paymentDetails = await contractVoucherKernel.paymentDetails( + tokenSupplyKey + ); assert.equal( paymentDetails.paymentMethod.toString(), paymentMethods.TKNETH, - "Payment Method TKNETH not set correctly") + 'Payment Method TKNETH not set correctly' + ); assert.equal( paymentDetails.addressTokenPrice.toString(), contractBSNTokenPrice.address, - "TKNETH Method Price Token Address mismatch") + 'TKNETH Method Price Token Address mismatch' + ); assert.equal( paymentDetails.addressTokenDeposits.toString(), constants.ZERO_ADDRESS, - "TKNETH Method Deposit Token Address mismatch") - }) - - it("[NEGATIVE] Should fail if price token contract address is not provided", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.fails( - contractCashier.requestCreateOrderTKNETH( - '', - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, - value: txValue.toString() - } - ) - ) - }) - - it("[NEGATIVE] Should fail if token price contract is zero address", - async () => { - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNETH( - constants.ZERO_ADDRESS, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if price is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNETH( - contractBSNTokenPrice.address, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.ABOVE_TOKEN_LIMIT, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, value: txValue.toString() - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNETH( - contractBSNTokenPrice.address, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.ABOVE_ETH_LIMIT, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, - value: txValue.toString() - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNETH( - contractBSNTokenPrice.address, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.ABOVE_ETH_LIMIT, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address, - value: txValue.toString() - } - ), - truffleAssert.ErrorType.REVERT + 'TKNETH Method Deposit Token Address mismatch' + ); + }); + + it('[NEGATIVE] Should fail if price token contract address is not provided', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + + await truffleAssert.fails( + contractCashier.requestCreateOrderTKNETH( + '', + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue.toString(), + } ) - }) - }) + ); + }); - describe("TKNTKN", () => { - before(async () => { - await deployContracts() + it('[NEGATIVE] Should fail if token price contract is zero address', async () => { + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNETH( + constants.ZERO_ADDRESS, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - utils = UtilsBuilder.create() - .ERC20withPermit() - .TKNTKN() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - contractBSNTokenDeposit) + it('[NEGATIVE] Should not create a supply if price is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); - timestamp = await Utils.getCurrTimestamp() + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNETH( + contractBSNTokenPrice.address, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_TOKEN_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue.toString(), + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - const tokensToMint = - new BN(constants.product_price).mul(new BN(constants.QTY_20)) + it('[NEGATIVE] Should not create a supply if depositBu is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.seller.address, - tokensToMint) - await utils.mintTokens( - 'contractBSNTokenPrice', - users.buyer.address, - tokensToMint) - await utils.mintTokens( - 'contractBSNTokenDeposit', + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNETH( + contractBSNTokenPrice.address, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_ETH_LIMIT, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue.toString(), + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create a supply if depositSe is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNETH( + contractBSNTokenPrice.address, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_ETH_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + value: txValue.toString(), + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); + + describe('TKNTKN', () => { + before(async () => { + await deployContracts(); + + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKNTKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit + ); + + timestamp = await Utils.getCurrTimestamp(); + + const tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_20) + ); + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint + ); + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMint + ); + await utils.mintTokens( + 'contractBSNTokenDeposit', users.buyer.address, - tokensToMint) + tokensToMint + ); tokenSupplyKey = await utils.createOrder( users.seller, @@ -828,455 +919,502 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) - }) + ); + }); - it("ESCROW has correct initial balance", async () => { - const expectedBalance = - new BN(constants.seller_deposit).mul(new BN(remQty)) - const escrowAmount = await contractBSNTokenDeposit - .balanceOf(contractCashier.address) + it('ESCROW has correct initial balance', async () => { + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(remQty) + ); + const escrowAmount = await contractBSNTokenDeposit.balanceOf( + contractCashier.address + ); assert.isTrue( escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) + 'Escrow amount is incorrect' + ); + }); - it("Get correct remaining qty for supply", async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + it('Get correct remaining qty for supply', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); for (let i = 0; i < vouchersToBuy; i++) { - await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey) - remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(tokenSupplyKey, users.seller.address) + await utils.commitToBuy(users.buyer, users.seller, tokenSupplyKey); + remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + tokenSupplyKey, + users.seller.address + ); assert.equal( remainingQtyInContract, --remQty, - "Remaining qty is not correct") + 'Remaining qty is not correct' + ); } - }) + }); - it("Should create payment method TKNTKN", async () => { + it('Should create payment method TKNTKN', async () => { tokenSupplyKey = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_1 - ) + ); - const paymentDetails = await contractVoucherKernel - .paymentDetails(tokenSupplyKey) + const paymentDetails = await contractVoucherKernel.paymentDetails( + tokenSupplyKey + ); assert.equal( paymentDetails.paymentMethod.toString(), paymentMethods.TKNTKN, - "Payment Method TKNTKN not set correctly") + 'Payment Method TKNTKN not set correctly' + ); assert.equal( paymentDetails.addressTokenPrice.toString(), contractBSNTokenPrice.address, - "TKNTKN Method Price Token Address mismatch") + 'TKNTKN Method Price Token Address mismatch' + ); assert.equal( paymentDetails.addressTokenDeposits.toString(), contractBSNTokenDeposit.address, - "TKNTKN Method Deposit Token Address mismatch") - }) - - it("[NEGATIVE] Should fail if token price contract address is not provided", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) - - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, - txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.fails( - contractCashier.requestCreateOrderTKNTKNWithPermit( - '', - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ) - ) - - }) + 'TKNTKN Method Deposit Token Address mismatch' + ); + }); + + it('[NEGATIVE] Should fail if token price contract address is not provided', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - it("[NEGATIVE] Should fail if token deposit contract address is not provided", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + await truffleAssert.fails( + contractCashier.requestCreateOrderTKNTKNWithPermit( + '', + contractBSNTokenDeposit.address, txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.fails( - contractCashier.requestCreateOrderTKNTKNWithPermit( - contractBSNTokenPrice.address, - '', - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } ) + ); + }); + + it('[NEGATIVE] Should fail if token deposit contract address is not provided', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - }) - - it("[NEGATIVE] Should revert if token price contract address is zero address", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + await truffleAssert.fails( + contractCashier.requestCreateOrderTKNTKNWithPermit( + contractBSNTokenPrice.address, + '', txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNTKNWithPermit( - constants.ZERO_ADDRESS, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } ) + ); + }); + + it('[NEGATIVE] Should revert if token price contract address is zero address', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - }) - - it("[NEGATIVE] Should revert if token deposit contract address is zero address", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(ONE_VOUCHER)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) - const deadline = toWei(1) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNTKNWithPermit( + constants.ZERO_ADDRESS, + contractBSNTokenDeposit.address, txValue, - nonce, - deadline - ) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should revert if token deposit contract address is zero address', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(ONE_VOUCHER) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + const deadline = toWei(1); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNTKNWithPermit( - contractBSNTokenPrice.address, - constants.ZERO_ADDRESS, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - }) + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNTKNWithPermit( + contractBSNTokenPrice.address, + constants.ZERO_ADDRESS, + txValue, + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create a supply if price is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_1) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - it("[NEGATIVE] Should not create a supply if price is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNTKNWithPermit( + contractBSNTokenPrice.address, + contractBSNTokenDeposit.address, txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNTKNWithPermit( - contractBSNTokenPrice.address, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.ABOVE_TOKEN_LIMIT, - constants.seller_deposit, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.ABOVE_TOKEN_LIMIT, + constants.seller_deposit, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create a supply if depositBu is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_1) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - it("[NEGATIVE] Should not create a supply if depositBu is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNTKNWithPermit( + contractBSNTokenPrice.address, + contractBSNTokenDeposit.address, txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNTKNWithPermit( - contractBSNTokenPrice.address, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.seller_deposit, - constants.ABOVE_TOKEN_LIMIT, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.seller_deposit, + constants.ABOVE_TOKEN_LIMIT, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create a supply if depositSe is above the limit', async () => { + const txValue = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_1) + ); + const nonce = await contractBSNTokenDeposit.nonces( + users.seller.address + ); + + const digest = await getApprovalDigest( + contractBSNTokenDeposit, + users.seller.address, + contractCashier.address, + txValue, + nonce, + deadline + ); - it("[NEGATIVE] Should not create a supply if depositSe is above the limit", - async () => { - const txValue = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) - const nonce = await contractBSNTokenDeposit - .nonces(users.seller.address) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.seller.privateKey.slice(2), 'hex') + ); - const digest = await getApprovalDigest( - contractBSNTokenDeposit, - users.seller.address, - contractCashier.address, + await truffleAssert.reverts( + contractCashier.requestCreateOrderTKNTKNWithPermit( + contractBSNTokenPrice.address, + contractBSNTokenDeposit.address, txValue, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.seller.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestCreateOrderTKNTKNWithPermit( - contractBSNTokenPrice.address, - contractBSNTokenDeposit.address, - txValue, - deadline, - v, r, s, - [ - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.PROMISE_PRICE1, - constants.ABOVE_TOKEN_LIMIT, - constants.PROMISE_DEPOSITBU1, - constants.ORDER_QUANTITY1 - ], { - from: users.seller.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) + deadline, + v, + r, + s, + [ + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.PROMISE_PRICE1, + constants.ABOVE_TOKEN_LIMIT, + constants.PROMISE_DEPOSITBU1, + constants.ORDER_QUANTITY1, + ], + { + from: users.seller.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); + }); + }); - describe("VOUCHER CREATION (Commit to buy)", () => { - const ORDER_QTY = 5 - let TOKEN_SUPPLY_ID + describe('VOUCHER CREATION (Commit to buy)', () => { + const ORDER_QTY = 5; + let TOKEN_SUPPLY_ID; before(async () => { - await deployContracts() - }) + await deployContracts(); + }); - describe("ETHETH", async () => { + describe('ETHETH', async () => { before(async () => { utils = UtilsBuilder.create() .ETHETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier) + .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.seller_deposit, - constants.QTY_10) - }) - - it("Should create order", async () => { - const txValue = - new BN(constants.buyer_deposit).add(new BN(constants.product_price)) - let txFillOrder = await contractCashier - .requestVoucherETHETH( - TOKEN_SUPPLY_ID, - users.seller.address, - { - from: users.buyer.address, - value: txValue - }) + constants.QTY_10 + ); + }); - let internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + it('Should create order', async () => { + const txValue = new BN(constants.buyer_deposit).add( + new BN(constants.product_price) + ); + let txFillOrder = await contractCashier.requestVoucherETHETH( + TOKEN_SUPPLY_ID, + users.seller.address, + { + from: users.buyer.address, + value: txValue, + } + ); + + let internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); truffleAssert.eventEmitted( internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === users.seller.address - }, "order1 not created successfully") - }) - - it("[NEGATIVE] Should not create order with incorrect price", - async () => { - const txValue = - new BN(constants.buyer_deposit) - .add(new BN(constants.incorrect_product_price)) + tokenVoucherKey = ev._tokenIdVoucher; + return ev._issuer === users.seller.address; + }, + 'order1 not created successfully' + ); + }); + + it('[NEGATIVE] Should not create order with incorrect price', async () => { + const txValue = new BN(constants.buyer_deposit).add( + new BN(constants.incorrect_product_price) + ); - await truffleAssert.reverts( - contractCashier.requestVoucherETHETH( - TOKEN_SUPPLY_ID, - users.seller.address, - { - from: users.buyer.address, - value: txValue - }), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + contractCashier.requestVoucherETHETH( + TOKEN_SUPPLY_ID, + users.seller.address, + { + from: users.buyer.address, + value: txValue, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not create order with incorrect deposit", - async () => { - const txValue = - new BN(constants.buyer_incorrect_deposit) - .add(new BN(constants.product_price)) + it('[NEGATIVE] Should not create order with incorrect deposit', async () => { + const txValue = new BN(constants.buyer_incorrect_deposit).add( + new BN(constants.product_price) + ); - await truffleAssert.reverts( - contractCashier.requestVoucherETHETH( - TOKEN_SUPPLY_ID, - users.seller.address, - { - from: users.buyer.address, - value: txValue - }), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + contractCashier.requestVoucherETHETH( + TOKEN_SUPPLY_ID, + users.seller.address, + { + from: users.buyer.address, + value: txValue, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("[WITH PERMIT]", () => { - describe("ETHTKN", async () => { + describe('[WITH PERMIT]', () => { + describe('ETHTKN', async () => { before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() @@ -1286,17 +1424,24 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const tokensToMintSeller = - new BN(constants.seller_deposit).mul(new BN(ORDER_QTY)) - const tokensToMintBuyer = - new BN(constants.buyer_deposit).mul(new BN(ORDER_QTY)) + const tokensToMintSeller = new BN(constants.seller_deposit).mul( + new BN(ORDER_QTY) + ); + const tokensToMintBuyer = new BN(constants.buyer_deposit).mul( + new BN(ORDER_QTY) + ); - await contractBSNTokenDeposit - .mint(users.seller.address, tokensToMintSeller) - await contractBSNTokenDeposit - .mint(users.buyer.address, tokensToMintBuyer) + await contractBSNTokenDeposit.mint( + users.seller.address, + tokensToMintSeller + ); + await contractBSNTokenDeposit.mint( + users.buyer.address, + tokensToMintBuyer + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -1304,12 +1449,13 @@ contract("Cashier && VK", async addresses => { constants.PROMISE_VALID_TO, constants.seller_deposit, ORDER_QTY - ) - }) + ); + }); - it("Should create order", async () => { - const nonce = await contractBSNTokenDeposit - .nonces(users.buyer.address) + it('Should create order', async () => { + const nonce = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); const digestDeposit = await getApprovalDigest( contractBSNTokenDeposit, users.buyer.address, @@ -1317,105 +1463,117 @@ contract("Cashier && VK", async addresses => { constants.buyer_deposit, nonce, deadline - ) + ); + + const {v, r, s} = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); + + const txFillOrder = await contractCashier.requestVoucherETHTKNWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.buyer_deposit, + deadline, + v, + r, + s, + { + from: users.buyer.address, + value: constants.product_price, + } + ); + + let internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey = ev._tokenIdVoucher; + return ev._issuer === users.seller.address; + }, + 'order1 not created successfully' + ); + }); + + it('[NEGATIVE] Should not create order with incorrect price', async () => { + const nonce = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce, + deadline + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - const txFillOrder = await contractCashier - .requestVoucherETHTKNWithPermit( + await truffleAssert.reverts( + contractCashier.requestVoucherETHTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, constants.buyer_deposit, deadline, - v, r, s, + v, + r, + s, { from: users.buyer.address, - value: constants.product_price + value: constants.incorrect_product_price, } - ) - - let internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + ), + truffleAssert.ErrorType.REVERT + ); + }); - truffleAssert.eventEmitted( - internalTx, - 'LogVoucherDelivered', - (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === users.seller.address - }, "order1 not created successfully") - }) - - it("[NEGATIVE] Should not create order with incorrect price", - async () => { - const nonce = await contractBSNTokenDeposit - .nonces(users.buyer.address) - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - users.buyer.address, - contractCashier.address, - constants.buyer_deposit, - nonce, - deadline - ) + it('[NEGATIVE] Should not create order with incorrect deposit', async () => { + const nonce = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestVoucherETHTKNWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - constants.buyer_deposit, - deadline, - v, r, s, - { - from: users.buyer.address, - value: constants.incorrect_product_price - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", - async () => { - const nonce = await contractBSNTokenDeposit - .nonces(users.buyer.address) - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - users.buyer.address, - contractCashier.address, - constants.buyer_deposit, - nonce, - deadline - ) + const {v, r, s} = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - const { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestVoucherETHTKNWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - constants.buyer_incorrect_deposit, - deadline, - v, r, s, - { - from: users.buyer.address, - value: constants.product_price - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + contractCashier.requestVoucherETHTKNWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.buyer_incorrect_deposit, + deadline, + v, + r, + s, + { + from: users.buyer.address, + value: constants.product_price, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNTKN", () => { + describe('TKNTKN', () => { before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() @@ -1425,19 +1583,28 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const tokensToMintSeller = - new BN(constants.seller_deposit).mul(new BN(ORDER_QTY)) - const tokensToMintBuyer = - new BN(constants.product_price).mul(new BN(ORDER_QTY)) + const tokensToMintSeller = new BN(constants.seller_deposit).mul( + new BN(ORDER_QTY) + ); + const tokensToMintBuyer = new BN(constants.product_price).mul( + new BN(ORDER_QTY) + ); - await contractBSNTokenDeposit - .mint(users.seller.address, tokensToMintSeller) - await contractBSNTokenDeposit - .mint(users.buyer.address, tokensToMintBuyer) - await contractBSNTokenPrice - .mint(users.buyer.address, tokensToMintBuyer) + await contractBSNTokenDeposit.mint( + users.seller.address, + tokensToMintSeller + ); + await contractBSNTokenDeposit.mint( + users.buyer.address, + tokensToMintBuyer + ); + await contractBSNTokenPrice.mint( + users.buyer.address, + tokensToMintBuyer + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -1445,15 +1612,96 @@ contract("Cashier && VK", async addresses => { constants.PROMISE_VALID_TO, constants.seller_deposit, ORDER_QTY - ) - }) + ); + }); + + it('Should create order', async () => { + const nonce1 = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); + const tokensToSend = new BN(constants.product_price).add( + new BN(constants.buyer_deposit) + ); + + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce1, + deadline + ); - it("Should create order", async () => { - const nonce1 = await contractBSNTokenDeposit - .nonces(users.buyer.address) - const tokensToSend = - new BN(constants.product_price) - .add(new BN(constants.buyer_deposit)) + let VRS_DEPOSIT = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); + + let vDeposit = VRS_DEPOSIT.v; + let rDeposit = VRS_DEPOSIT.r; + let sDeposit = VRS_DEPOSIT.s; + + const nonce2 = await contractBSNTokenPrice.nonces( + users.buyer.address + ); + + const digestPrice = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce2, + deadline + ); + + let VRS_PRICE = ecsign( + Buffer.from(digestPrice.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); + + let vPrice = VRS_PRICE.v; + let rPrice = VRS_PRICE.r; + let sPrice = VRS_PRICE.s; + + let txFillOrder = await contractCashier.requestVoucherTKNTKNWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + vPrice, + rPrice, + sPrice, + vDeposit, + rDeposit, + sDeposit, + { + from: users.buyer.address, + } + ); + + let internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey = ev._tokenIdVoucher; + return ev._issuer === users.seller.address; + }, + 'order1 not created successfully' + ); + }); + + it('[NEGATIVE] Should not create order with incorrect price', async () => { + const nonce1 = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); + const tokensToSend = new BN(constants.incorrect_product_price).add( + new BN(constants.buyer_deposit) + ); const digestDeposit = await getApprovalDigest( contractBSNTokenDeposit, @@ -1462,17 +1710,20 @@ contract("Cashier && VK", async addresses => { constants.buyer_deposit, nonce1, deadline - ) + ); let VRS_DEPOSIT = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s + let vDeposit = VRS_DEPOSIT.v; + let rDeposit = VRS_DEPOSIT.r; + let sDeposit = VRS_DEPOSIT.s; - const nonce2 = await contractBSNTokenPrice.nonces(users.buyer.address) + const nonce2 = await contractBSNTokenPrice.nonces( + users.buyer.address + ); const digestPrice = await getApprovalDigest( contractBSNTokenPrice, @@ -1481,202 +1732,323 @@ contract("Cashier && VK", async addresses => { constants.product_price, nonce2, deadline - ) + ); let VRS_PRICE = ecsign( Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s + let vPrice = VRS_PRICE.v; + let rPrice = VRS_PRICE.r; + let sPrice = VRS_PRICE.s; - let txFillOrder = await contractCashier - .requestVoucherTKNTKNWithPermit( + await truffleAssert.reverts( + contractCashier.requestVoucherTKNTKNWithPermit( TOKEN_SUPPLY_ID, users.seller.address, tokensToSend, deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, + vPrice, + rPrice, + sPrice, + vDeposit, + rDeposit, + sDeposit, { - from: users.buyer.address - }) + from: users.buyer.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create order with incorrect deposit', async () => { + const nonce1 = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); + const tokensToSend = new BN(constants.product_price).add( + new BN(constants.buyer_incorrect_deposit) + ); - let internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + const digestDeposit = await getApprovalDigest( + contractBSNTokenDeposit, + users.buyer.address, + contractCashier.address, + constants.buyer_deposit, + nonce1, + deadline + ); - truffleAssert.eventEmitted( - internalTx, - 'LogVoucherDelivered', - (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === users.seller.address - }, "order1 not created successfully") - }) - - it("[NEGATIVE] Should not create order with incorrect price", - async () => { - const nonce1 = await contractBSNTokenDeposit - .nonces(users.buyer.address) - const tokensToSend = - new BN(constants.incorrect_product_price) - .add(new BN(constants.buyer_deposit)) - - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - users.buyer.address, - contractCashier.address, - constants.buyer_deposit, - nonce1, - deadline - ) + let VRS_DEPOSIT = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); + + let vDeposit = VRS_DEPOSIT.v; + let rDeposit = VRS_DEPOSIT.r; + let sDeposit = VRS_DEPOSIT.s; + + const nonce2 = await contractBSNTokenPrice.nonces( + users.buyer.address + ); + + const digestPrice = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce2, + deadline + ); - let VRS_DEPOSIT = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + let VRS_PRICE = ecsign( + Buffer.from(digestPrice.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s + let vPrice = VRS_PRICE.v; + let rPrice = VRS_PRICE.r; + let sPrice = VRS_PRICE.s; - const nonce2 = await contractBSNTokenPrice - .nonces(users.buyer.address) + await truffleAssert.reverts( + contractCashier.requestVoucherTKNTKNWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + vPrice, + rPrice, + sPrice, + vDeposit, + rDeposit, + sDeposit, + { + from: users.buyer.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - const digestPrice = await getApprovalDigest( + // Ignored due to deployment failure. + xdescribe('TKNTKNSAME', () => { + const tokensToMintSeller = new BN(constants.seller_deposit).mul( + new BN(ORDER_QTY) + ); + const tokensToMintBuyer = new BN(constants.product_price).mul( + new BN(ORDER_QTY) + ); + + before(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKNTKNSAME() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, contractBSNTokenPrice, - users.buyer.address, - contractCashier.address, - constants.product_price, - nonce2, - deadline - ) + contractBSNTokenDeposit + ); - let VRS_PRICE = ecsign( - Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s - - await truffleAssert.reverts( - contractCashier.requestVoucherTKNTKNWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - tokensToSend, - deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, - { - from: users.buyer.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", - async () => { - const nonce1 = await contractBSNTokenDeposit - .nonces(users.buyer.address) - const tokensToSend = - new BN(constants.product_price) - .add(new BN(constants.buyer_incorrect_deposit)) - - const digestDeposit = await getApprovalDigest( - contractBSNTokenDeposit, - users.buyer.address, - contractCashier.address, - constants.buyer_deposit, - nonce1, - deadline - ) + await utils.contractBSNTokenSAME.mint( + users.seller.address, + tokensToMintSeller + ); + await utils.contractBSNTokenSAME.mint( + users.buyer.address, + tokensToMintBuyer + ); - let VRS_DEPOSIT = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + ORDER_QTY + ); + }); + + it('Should create voucher', async () => { + const nonce = await utils.contractBSNTokenSAME.nonces( + users.buyer.address + ); + const tokensToSend = new BN(constants.product_price).add( + new BN(constants.buyer_deposit) + ); - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s + const digestTokens = await getApprovalDigest( + utils.contractBSNTokenSAME, + users.buyer.address, + contractCashier.address, + tokensToSend, + nonce, + deadline + ); - const nonce2 = await contractBSNTokenPrice - .nonces(users.buyer.address) + let VRS_TOKENS = ecsign( + Buffer.from(digestTokens.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - const digestPrice = await getApprovalDigest( - contractBSNTokenPrice, - users.buyer.address, - contractCashier.address, - constants.product_price, - nonce2, - deadline - ) + let v = VRS_TOKENS.v; + let r = VRS_TOKENS.r; + let s = VRS_TOKENS.s; + + let txFillOrder = await contractCashier.requestVoucherTKNTKNSameWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + tokensToSend, + deadline, + v, + r, + s, + { + from: users.buyer.address, + } + ); + + let internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); + + truffleAssert.eventEmitted( + internalTx, + 'LogVoucherDelivered', + (ev) => { + tokenVoucherKey1 = ev._tokenIdVoucher; + return ev._issuer === users.seller.address; + }, + 'order1 not created successfully' + ); + }); + + it('[NEGATIVE] Should not create order with incorrect price', async () => { + const nonce = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); + const incorrectTokensToSign = new BN( + constants.incorrect_product_price + ).add(new BN(constants.buyer_deposit)); + const digestTokens = await getApprovalDigest( + utils.contractBSNTokenSAME, + users.buyer.address, + contractCashier.address, + incorrectTokensToSign, + nonce, + deadline + ); + + let VRS_TOKENS = ecsign( + Buffer.from(digestTokens.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); + + let v = VRS_TOKENS.v; + let r = VRS_TOKENS.r; + let s = VRS_TOKENS.s; + + await truffleAssert.reverts( + contractCashier.requestVoucherTKNTKNSameWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + incorrectTokensToSign, + deadline, + v, + r, + s, + { + from: users.buyer.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not create order with incorrect deposit', async () => { + const nonce = await contractBSNTokenDeposit.nonces( + users.buyer.address + ); + const incorrectTokensToSign = new BN(constants.product_price).add( + new BN(constants.buyer_incorrect_deposit) + ); + const digestTokens = await getApprovalDigest( + utils.contractBSNTokenSAME, + users.buyer.address, + contractCashier.address, + incorrectTokensToSign, + nonce, + deadline + ); - let VRS_PRICE = ecsign( - Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s - - await truffleAssert.reverts( - contractCashier.requestVoucherTKNTKNWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - tokensToSend, - deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, - { - from: users.buyer.address - }), - truffleAssert.ErrorType.REVERT - ) - }) + let VRS_TOKENS = ecsign( + Buffer.from(digestTokens.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - }) + let v = VRS_TOKENS.v; + let r = VRS_TOKENS.r; + let s = VRS_TOKENS.s; - // Ignored due to deployment failure. - xdescribe("TKNTKNSAME", () => { - const tokensToMintSeller = - new BN(constants.seller_deposit) - .mul(new BN(ORDER_QTY)) - const tokensToMintBuyer = - new BN(constants.product_price) - .mul(new BN(ORDER_QTY)) + await truffleAssert.reverts( + contractCashier.requestVoucherTKNTKNSameWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + incorrectTokensToSign, + deadline, + v, + r, + s, + { + from: users.buyer.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - before(async () => { - utils = UtilsBuilder.create() + it('[NEGATIVE] Should revert if Price Token and Deposit Token are diff contracts', async () => { + let utilsTKNTKN = UtilsBuilder.create() .ERC20withPermit() - .TKNTKNSAME() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - await utils.contractBSNTokenSAME - .mint(users.seller.address, tokensToMintSeller) - await utils.contractBSNTokenSAME - .mint(users.buyer.address, tokensToMintBuyer) + await contractBSNTokenDeposit.mint( + users.seller.address, + tokensToMintSeller + ); + await contractBSNTokenDeposit.mint( + users.buyer.address, + tokensToMintBuyer + ); + await contractBSNTokenPrice.mint( + users.buyer.address, + tokensToMintBuyer + ); - TOKEN_SUPPLY_ID = await utils.createOrder( + TOKEN_SUPPLY_ID = await utilsTKNTKN.createOrder( users.seller, constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.seller_deposit, ORDER_QTY - ) - }) + ); - it("Should create voucher", async () => { - const nonce = await utils.contractBSNTokenSAME - .nonces(users.buyer.address) - const tokensToSend = - new BN(constants.product_price) - .add(new BN(constants.buyer_deposit)) + const nonce = await utils.contractBSNTokenSAME.nonces( + users.buyer.address + ); + const tokensToSend = new BN(constants.product_price).add( + new BN(constants.buyer_deposit) + ); const digestTokens = await getApprovalDigest( utils.contractBSNTokenSAME, @@ -1685,182 +2057,36 @@ contract("Cashier && VK", async addresses => { tokensToSend, nonce, deadline - ) + ); let VRS_TOKENS = ecsign( Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s + let v = VRS_TOKENS.v; + let r = VRS_TOKENS.r; + let s = VRS_TOKENS.s; - let txFillOrder = await contractCashier - .requestVoucherTKNTKNSameWithPermit( + await truffleAssert.reverts( + contractCashier.requestVoucherTKNTKNSameWithPermit( TOKEN_SUPPLY_ID, users.seller.address, tokensToSend, deadline, - v, r, s, + v, + r, + s, { - from: users.buyer.address - }) - - let internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) - - truffleAssert.eventEmitted( - internalTx, - 'LogVoucherDelivered', - (ev) => { - tokenVoucherKey1 = ev._tokenIdVoucher - return ev._issuer === users.seller.address - }, "order1 not created successfully") - }) - - it("[NEGATIVE] Should not create order with incorrect price", - async () => { - const nonce = await contractBSNTokenDeposit - .nonces(users.buyer.address) - const incorrectTokensToSign = - new BN(constants.incorrect_product_price) - .add(new BN(constants.buyer_deposit)) - const digestTokens = await getApprovalDigest( - utils.contractBSNTokenSAME, - users.buyer.address, - contractCashier.address, - incorrectTokensToSign, - nonce, - deadline - ) - - let VRS_TOKENS = ecsign( - Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s - - await truffleAssert.reverts( - contractCashier.requestVoucherTKNTKNSameWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - incorrectTokensToSign, - deadline, - v, r, s, - { - from: users.buyer.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should not create order with incorrect deposit", - async () => { - const nonce = await contractBSNTokenDeposit - .nonces(users.buyer.address) - const incorrectTokensToSign = - new BN(constants.product_price) - .add(new BN(constants.buyer_incorrect_deposit)) - const digestTokens = await getApprovalDigest( - utils.contractBSNTokenSAME, - users.buyer.address, - contractCashier.address, - incorrectTokensToSign, - nonce, - deadline - ) - - let VRS_TOKENS = ecsign( - Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s - - await truffleAssert.reverts( - contractCashier.requestVoucherTKNTKNSameWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - incorrectTokensToSign, - deadline, - v, r, s, - { - from: users.buyer.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Should revert if Price Token and Deposit Token are diff contracts", - async () => { - let utilsTKNTKN = UtilsBuilder.create() - .ERC20withPermit() - .TKNTKN() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - contractBSNTokenDeposit) - - await contractBSNTokenDeposit - .mint(users.seller.address, tokensToMintSeller) - await contractBSNTokenDeposit - .mint(users.buyer.address, tokensToMintBuyer) - await contractBSNTokenPrice - .mint(users.buyer.address, tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utilsTKNTKN.createOrder( - users.seller, - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.seller_deposit, - ORDER_QTY - ) - - const nonce = await utils.contractBSNTokenSAME - .nonces(users.buyer.address) - const tokensToSend = - new BN(constants.product_price) - .add(new BN(constants.buyer_deposit)) - - const digestTokens = await getApprovalDigest( - utils.contractBSNTokenSAME, - users.buyer.address, - contractCashier.address, - tokensToSend, - nonce, - deadline - ) - - let VRS_TOKENS = ecsign( - Buffer.from(digestTokens.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - let v = VRS_TOKENS.v - let r = VRS_TOKENS.r - let s = VRS_TOKENS.s - - await truffleAssert.reverts( - contractCashier.requestVoucherTKNTKNSameWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - tokensToSend, - deadline, - v, r, s, - { - from: users.buyer.address - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) + from: users.buyer.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNETH", () => { + describe('TKNETH', () => { before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() @@ -1870,13 +2096,17 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const tokensToMintBuyer = - new BN(constants.product_price).mul(new BN(ORDER_QTY)) + const tokensToMintBuyer = new BN(constants.product_price).mul( + new BN(ORDER_QTY) + ); - await contractBSNTokenPrice - .mint(users.buyer.address, tokensToMintBuyer) + await contractBSNTokenPrice.mint( + users.buyer.address, + tokensToMintBuyer + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -1884,12 +2114,11 @@ contract("Cashier && VK", async addresses => { constants.PROMISE_VALID_TO, constants.seller_deposit, ORDER_QTY - ) - }) + ); + }); - it("Should create order", async () => { - const nonce = await contractBSNTokenPrice - .nonces(users.buyer.address) + it('Should create order', async () => { + const nonce = await contractBSNTokenPrice.nonces(users.buyer.address); const digestDeposit = await getApprovalDigest( contractBSNTokenPrice, @@ -1898,410 +2127,458 @@ contract("Cashier && VK", async addresses => { constants.product_price, nonce, deadline - ) + ); - let { v, r, s } = ecsign( + let {v, r, s} = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - let txFillOrder = await contractCashier - .requestVoucherTKNETHWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - constants.product_price, - deadline, - v, r, s, - { - from: users.buyer.address, - value: constants.buyer_deposit - } - ) + let txFillOrder = await contractCashier.requestVoucherTKNETHWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.product_price, + deadline, + v, + r, + s, + { + from: users.buyer.address, + value: constants.buyer_deposit, + } + ); - let internalTx = await truffleAssert - .createTransactionResult(contractVoucherKernel, txFillOrder.tx) + let internalTx = await truffleAssert.createTransactionResult( + contractVoucherKernel, + txFillOrder.tx + ); truffleAssert.eventEmitted( internalTx, 'LogVoucherDelivered', (ev) => { - tokenVoucherKey = ev._tokenIdVoucher - return ev._issuer === users.seller.address - }, "order1 not created successfully") - }) + tokenVoucherKey = ev._tokenIdVoucher; + return ev._issuer === users.seller.address; + }, + 'order1 not created successfully' + ); + }); - it("[NEGATIVE] Should not create order with incorrect deposit", - async () => { - const nonce = await contractBSNTokenPrice - .nonces(users.buyer.address) + it('[NEGATIVE] Should not create order with incorrect deposit', async () => { + const nonce = await contractBSNTokenPrice.nonces(users.buyer.address); - const digestDeposit = await getApprovalDigest( - contractBSNTokenPrice, - users.buyer.address, - contractCashier.address, + const digestDeposit = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce, + deadline + ); + + let {v, r, s} = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); + + await truffleAssert.reverts( + contractCashier.requestVoucherTKNETHWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, constants.product_price, - nonce, - deadline - ) + deadline, + v, + r, + s, + { + from: users.buyer.address, + value: constants.buyer_incorrect_deposit, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - let { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestVoucherTKNETHWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - constants.product_price, - deadline, - v, r, s, - { - from: users.buyer.address, - value: constants.buyer_incorrect_deposit - } - ), - truffleAssert.ErrorType.REVERT - ) - }) + it('[NEGATIVE] Should not create order with incorrect price', async () => { + const nonce = await contractBSNTokenPrice.nonces(users.buyer.address); - it("[NEGATIVE] Should not create order with incorrect price", - async () => { - const nonce = await contractBSNTokenPrice - .nonces(users.buyer.address) + const digestDeposit = await getApprovalDigest( + contractBSNTokenPrice, + users.buyer.address, + contractCashier.address, + constants.product_price, + nonce, + deadline + ); - const digestDeposit = await getApprovalDigest( - contractBSNTokenPrice, - users.buyer.address, - contractCashier.address, - constants.product_price, - nonce, - deadline - ) + let {v, r, s} = ecsign( + Buffer.from(digestDeposit.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - let { v, r, s } = ecsign( - Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts( - contractCashier.requestVoucherTKNETHWithPermit( - TOKEN_SUPPLY_ID, - users.seller.address, - constants.incorrect_product_price, - deadline, - v, r, s, - { - from: users.buyer.address, - value: constants.buyer_deposit - } - ), - truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) + await truffleAssert.reverts( + contractCashier.requestVoucherTKNETHWithPermit( + TOKEN_SUPPLY_ID, + users.seller.address, + constants.incorrect_product_price, + deadline, + v, + r, + s, + { + from: users.buyer.address, + value: constants.buyer_deposit, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); + }); + }); - describe("TOKEN SUPPLY TRANSFER", () => { - let actualOldOwnerBalanceFromEscrow = new BN(0) - let actualNewOwnerBalanceFromEscrow = new BN(0) - let expectedBalanceInEscrow = new BN(0) + describe('TOKEN SUPPLY TRANSFER', () => { + let actualOldOwnerBalanceFromEscrow = new BN(0); + let actualNewOwnerBalanceFromEscrow = new BN(0); + let expectedBalanceInEscrow = new BN(0); afterEach(() => { distributedAmounts = { buyerAmount: new BN(0), sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - }) - - describe("Common transfer", () => { + escrowAmount: new BN(0), + }; + }); + describe('Common transfer', () => { beforeEach(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ETHETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier) + .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); tokenSupplyKey = await utils.createOrder( users.other1, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_10) - }) + constants.QTY_10 + ); + }); - it("Should transfer voucher supply", async () => { + it('Should transfer voucher supply', async () => { let transferTx = await utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_10, { - from: users.other1.address - }) + constants.QTY_10, + { + from: users.other1.address, + } + ); truffleAssert.eventEmitted( transferTx, 'TransferSingle', (ev) => { - assert.equal(ev._from, users.other1.address) - assert.equal(ev._to, users.other2.address) - assert.equal(ev._id.toString(), tokenSupplyKey) - assert.equal(ev._value.toString(), constants.QTY_10) - - return true - }, "TransferSingle not emitted") - - }) - - it("[NEGATIVE] Should revert if owner tries to transfer voucher supply partially", - async () => { - await truffleAssert.reverts( - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }), - truffleAssert.ErrorType.REVERT - ) - }) + assert.equal(ev._from, users.other1.address); + assert.equal(ev._to, users.other2.address); + assert.equal(ev._id.toString(), tokenSupplyKey); + assert.equal(ev._value.toString(), constants.QTY_10); + + return true; + }, + 'TransferSingle not emitted' + ); + }); + + it('[NEGATIVE] Should revert if owner tries to transfer voucher supply partially', async () => { + await truffleAssert.reverts( + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should revert if Attacker tries to transfer voucher supply", - async () => { - await truffleAssert.reverts( - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_10, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) + it('[NEGATIVE] Should revert if Attacker tries to transfer voucher supply', async () => { + await truffleAssert.reverts( + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_10, + { + from: users.attacker.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - it("Should transfer batch voucher supply", async () => { + it('Should transfer batch voucher supply', async () => { let transferTx = await utils.safeBatchTransfer1155( users.other1.address, users.other2.address, - [ tokenSupplyKey ], - [ constants.QTY_10 ], { - from: users.other1.address - }) + [tokenSupplyKey], + [constants.QTY_10], + { + from: users.other1.address, + } + ); truffleAssert.eventEmitted( transferTx, 'TransferBatch', (ev) => { - assert.equal(ev._from, users.other1.address) - assert.equal(ev._to, users.other2.address) + assert.equal(ev._from, users.other1.address); + assert.equal(ev._to, users.other2.address); assert.equal( JSON.stringify(ev._ids), - JSON.stringify([ new BN(tokenSupplyKey) ])) + JSON.stringify([new BN(tokenSupplyKey)]) + ); assert.equal( JSON.stringify(ev._values), - JSON.stringify([ new BN(constants.QTY_10) ])) + JSON.stringify([new BN(constants.QTY_10)]) + ); - return true - }, "TransferSingle not emitted") - }) + return true; + }, + 'TransferSingle not emitted' + ); + }); - it("[NEGATIVE] Should revert if owner tries to transfer voucher supply batch partially", - async () => { - await truffleAssert.reverts( - utils.safeBatchTransfer1155( - users.other1.address, - users.other2.address, - [ tokenSupplyKey ], - [ constants.QTY_1 ], { - from: users.other1.address - }), - truffleAssert.ErrorType.REVERT - ) - }) + it('[NEGATIVE] Should revert if owner tries to transfer voucher supply batch partially', async () => { + await truffleAssert.reverts( + utils.safeBatchTransfer1155( + users.other1.address, + users.other2.address, + [tokenSupplyKey], + [constants.QTY_1], + { + from: users.other1.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should revert if Attacker tries to transfer batch voucher supply", - async () => { - await truffleAssert.reverts( - utils.safeBatchTransfer1155( - users.other1.address, - users.other2.address, - [ tokenSupplyKey ], - [ constants.QTY_10 ], { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - }) + it('[NEGATIVE] Should revert if Attacker tries to transfer batch voucher supply', async () => { + await truffleAssert.reverts( + utils.safeBatchTransfer1155( + users.other1.address, + users.other2.address, + [tokenSupplyKey], + [constants.QTY_10], + { + from: users.attacker.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("ETHETH", () => { + describe('ETHETH', () => { beforeEach(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ETHETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier) + .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); tokenSupplyKey = await utils.createOrder( users.other1, constants.PROMISE_VALID_FROM, constants.PROMISE_VALID_TO, constants.seller_deposit, - constants.QTY_1) - }) - - it("Should update escrow amounts after transfer", async () => { - expectedBalanceInEscrow = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) - - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + constants.QTY_1 + ); + }); + + it('Should update escrow amounts after transfer', async () => { + expectedBalanceInEscrow = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_1) + ); + + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); assert.isTrue( actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "Old owner balance from escrow does not match") + 'Old owner balance from escrow does not match' + ); assert.isTrue( actualNewOwnerBalanceFromEscrow.eq(ZERO), - "New owner balance from escrow does not match") + 'New owner balance from escrow does not match' + ); utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + constants.QTY_1, + { + from: users.other1.address, + } + ); - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); assert.isTrue( actualOldOwnerBalanceFromEscrow.eq(ZERO), - "Old owner balance from escrow does not match") + 'Old owner balance from escrow does not match' + ); assert.isTrue( actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - // 0.04 - const expectedBuyerAmount = - new BN(constants.buyer_deposit) - // 0.35 - const expectedSellerAmount = - new BN(constants.seller_deposit) - .add(new BN(constants.product_price)) - // 0 - const expectedEscrowAmount = new BN(0) + 'New owner balance from escrow does not match' + ); + }); + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + // 0.04 + const expectedBuyerAmount = new BN(constants.buyer_deposit); + // 0.35 + const expectedSellerAmount = new BN(constants.seller_deposit).add( + new BN(constants.product_price) + ); + // 0 + const expectedEscrowAmount = new BN(0); - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - await utils.redeem(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - let withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) + let withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.other2.address) - return true - }, "Amounts not distributed successfully") + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.other2.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); - it("New owner should be able to COF", async () => { + it('New owner should be able to COF', async () => { utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - await utils.redeem(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); - await utils.cancel(voucherID, users.other2.address) - }) + await utils.cancel(voucherID, users.other2.address); + }); - it("[NEGATIVE] Old owner should not be able to COF", async () => { + it('[NEGATIVE] Old owner should not be able to COF', async () => { utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - await utils.redeem(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); await truffleAssert.reverts( utils.cancel(voucherID, users.other1.address), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + }); + }); - describe("[WITH PERMIT]", () => { - describe("ETHTKN", () => { - let balanceBuyerFromDeposits = new BN(0) + describe('[WITH PERMIT]', () => { + describe('ETHTKN', () => { + let balanceBuyerFromDeposits = new BN(0); - let balanceSellerFromDeposits = new BN(0) + let balanceSellerFromDeposits = new BN(0); - let escrowBalanceFromDeposits = new BN(0) + let escrowBalanceFromDeposits = new BN(0); - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); beforeEach(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() @@ -2311,171 +2588,197 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); + + const timestamp = await Utils.getCurrTimestamp(); + + const tokensToMint = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_1) + ); + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.other1.address, + tokensToMint + ); + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + constants.buyer_deposit + ); + + tokenSupplyKey = await utils.createOrder( + users.other1, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); + }); + + async function getBalancesDepositToken() { + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.buyer.address + ); + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.other2.address + ); + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.deployer.address + ); + cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf( + utils.contractCashier.address + ); + } + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + const expectedEscrowAmountDeposit = new BN(0); + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); + + await utils.redeem(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + let withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); + + await getBalancesDepositToken(); - const timestamp = await Utils.getCurrTimestamp() + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal(ev._payee, users.other2.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedSellerPrice)); - const tokensToMint = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + return true; + }, + 'Event LogWithdrawal was not emitted' + ); - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.other1.address, - tokensToMint) - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.buyer.address, - constants.buyer_deposit) + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); - tokenSupplyKey = await utils.createOrder( - users.other1, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1 - ) - }) - - async function getBalancesDepositToken () { - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.buyer.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.other2.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.deployer.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit - .balanceOf(utils.contractCashier.address) - } + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - const expectedEscrowAmountDeposit = new BN(0) - - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) - - const voucherID = await utils.commitToBuy( - users.buyer, - users.other2, - tokenSupplyKey - ) + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - await utils.redeem(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - let withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) - - await getBalancesDepositToken() - - // Payment should have been sent to seller - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.other2.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("New owner should be able to COF", async () => { + it('New owner should be able to COF', async () => { utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - await utils.redeem(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); - await utils.cancel(voucherID, users.other2.address) - }) + await utils.cancel(voucherID, users.other2.address); + }); - it("[NEGATIVE] Old owner should not be able to COF", - async () => { - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + it('[NEGATIVE] Old owner should not be able to COF', async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - await utils.redeem(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); - await truffleAssert.reverts( - utils.cancel(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + utils.cancel(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNTKN", () => { - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDeposits = new BN(0) + describe('TKNTKN', () => { + let balanceBuyerFromPayment = new BN(0); + let balanceBuyerFromDeposits = new BN(0); - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDeposits = new BN(0) + let balanceSellerFromPayment = new BN(0); + let balanceSellerFromDeposits = new BN(0); - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) + let escrowBalanceFromPayment = new BN(0); + let escrowBalanceFromDeposits = new BN(0); - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); beforeEach(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() @@ -2485,26 +2788,31 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - const supplyQty = 1 - const tokensToMint = - new BN(constants.seller_deposit).mul(new BN(supplyQty)) + const supplyQty = 1; + const tokensToMint = new BN(constants.seller_deposit).mul( + new BN(supplyQty) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.other1.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenPrice', users.buyer.address, - constants.product_price) + constants.product_price + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.buyer.address, - constants.buyer_deposit) + constants.buyer_deposit + ); tokenSupplyKey = await utils.createOrder( users.other1, @@ -2512,154 +2820,184 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, supplyQty - ) + ); + }); + + async function getBalancesFromPriceTokenAndDepositToken() { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.buyer.address + ); + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.buyer.address + ); + + balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.other2.address + ); + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.other2.address + ); + + escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.deployer.address + ); + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.deployer.address + ); + + cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf( + utils.contractCashier.address + ); + cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf( + utils.contractCashier.address + ); + } + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + const expectedBuyerPrice = new BN(0); + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + const expectedEscrowAmountDeposit = new BN(0); + const expectedEscrowAmountPrice = new BN(0); + + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ); - }) + voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - async function getBalancesFromPriceTokenAndDepositToken () { + await utils.redeem(voucherID, users.buyer.address); - balanceBuyerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.buyer.address) - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.buyer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - balanceSellerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.other2.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.other2.address) + const withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); - escrowBalanceFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.deployer.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.deployer.address) + await getBalancesFromPriceTokenAndDepositToken(); - cashierPaymentLeft = await utils.contractBSNTokenPrice - .balanceOf(utils.contractCashier.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit - .balanceOf(utils.contractCashier.address) - } + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - const expectedBuyerPrice = new BN(0) - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) - - voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) - - await utils.redeem(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(ZERO), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(ZERO), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("New owner should be able to COF", async () => { + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(ZERO), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(ZERO), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('New owner should be able to COF', async () => { utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - await utils.redeem(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); - await utils.cancel(voucherID, users.other2.address) - }) + await utils.cancel(voucherID, users.other2.address); + }); - it("[NEGATIVE] Old owner should not be able to COF", - async () => { - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + it('[NEGATIVE] Old owner should not be able to COF', async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); - await utils.redeem(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); - await truffleAssert.reverts( - utils.cancel(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + utils.cancel(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNETH", () => { - let balanceBuyerFromPayment = new BN(0) - let balanceSellerFromPayment = new BN(0) - let escrowBalanceFromPayment = new BN(0) + describe('TKNETH', () => { + let balanceBuyerFromPayment = new BN(0); + let balanceSellerFromPayment = new BN(0); + let escrowBalanceFromPayment = new BN(0); - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); beforeEach(async () => { - - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() @@ -2669,14 +3007,16 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - '') + '' + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); await utils.mintTokens( 'contractBSNTokenPrice', users.buyer.address, - constants.product_price) + constants.product_price + ); tokenSupplyKey = await utils.createOrder( users.other1, @@ -2684,338 +3024,696 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_1 - ) - }) - - async function getBalancesPriceToken () { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.buyer.address) - balanceSellerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.other2.address) - escrowBalanceFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.deployer.address) - cashierPaymentLeft = await utils.contractBSNTokenPrice - .balanceOf(utils.contractCashier.address) + ); + }); + + async function getBalancesPriceToken() { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.buyer.address + ); + balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.other2.address + ); + escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.deployer.address + ); + cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf( + utils.contractCashier.address + ); } - it("Should update escrow amounts after transfer", async () => { - expectedBalanceInEscrow = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_1)) + it('Should update escrow amounts after transfer', async () => { + expectedBalanceInEscrow = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_1) + ); - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); assert.isTrue( actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "Old owner balance from escrow does not match") + 'Old owner balance from escrow does not match' + ); assert.isTrue( actualNewOwnerBalanceFromEscrow.eq(ZERO), - "New owner balance from escrow does not match") + 'New owner balance from escrow does not match' + ); utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + constants.QTY_1, + { + from: users.other1.address, + } + ); - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); assert.isTrue( actualOldOwnerBalanceFromEscrow.eq(ZERO), - "Old owner balance from escrow does not match") + 'Old owner balance from escrow does not match' + ); assert.isTrue( actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - const expectedBuyerPrice = new BN(0) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedEscrowPrice = new BN(0) - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - const expectedEscrowAmountDeposit = new BN(0) - - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) - - const voucherID = await utils.commitToBuy( - users.buyer, - users.other2, - tokenSupplyKey - ) - await utils.redeem(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - let withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) - - await getBalancesPriceToken() - - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") - - //Deposits in ETH - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.buyer.address, - users.other2.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') - - //Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("New owner should be able to COF", async () => { + 'New owner balance from escrow does not match' + ); + }); + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + const expectedBuyerPrice = new BN(0); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + const expectedEscrowPrice = new BN(0); + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + const expectedEscrowAmountDeposit = new BN(0); + utils.safeTransfer1155( users.other1.address, users.other2.address, tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + constants.QTY_1, + { + from: users.other1.address, + } + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); + await utils.redeem(voucherID, users.buyer.address); - await utils.redeem(voucherID, users.buyer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await utils.cancel(voucherID, users.other2.address) - }) + let withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); - it("[NEGATIVE] Old owner should not be able to COF", - async () => { - utils.safeTransfer1155( - users.other1.address, - users.other2.address, - tokenSupplyKey, - constants.QTY_1, { - from: users.other1.address - }) + await getBalancesPriceToken(); - const voucherID = await utils - .commitToBuy(users.buyer, users.other2, tokenSupplyKey) + // Payments in TKN + // Payment should have been sent to seller + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); + + //Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.other2.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - await utils.redeem(voucherID, users.buyer.address) + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); - await truffleAssert.reverts( - utils.cancel(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) + //Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('New owner should be able to COF', async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); + + await utils.redeem(voucherID, users.buyer.address); + + await utils.cancel(voucherID, users.other2.address); + }); + + it('[NEGATIVE] Old owner should not be able to COF', async () => { + utils.safeTransfer1155( + users.other1.address, + users.other2.address, + tokenSupplyKey, + constants.QTY_1, + { + from: users.other1.address, + } + ); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.other2, + tokenSupplyKey + ); + + await utils.redeem(voucherID, users.buyer.address); + + await truffleAssert.reverts( + utils.cancel(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); + }); + }); - describe("VOUCHER TRANSFER", () => { - let actualOldOwnerBalanceFromEscrow = new BN(0) - let actualNewOwnerBalanceFromEscrow = new BN(0) - let expectedBalanceInEscrow = new BN(0) + describe('VOUCHER TRANSFER', () => { + let actualOldOwnerBalanceFromEscrow = new BN(0); + let actualNewOwnerBalanceFromEscrow = new BN(0); + let expectedBalanceInEscrow = new BN(0); afterEach(() => { distributedAmounts = { buyerAmount: new BN(0), sellerAmount: new BN(0), - escrowAmount: new BN(0) - } + escrowAmount: new BN(0), + }; - actualOldOwnerBalanceFromEscrow = new BN(0) - actualNewOwnerBalanceFromEscrow = new BN(0) - expectedBalanceInEscrow = new BN(0) - }) - - describe("Common transfer", () => { + actualOldOwnerBalanceFromEscrow = new BN(0); + actualNewOwnerBalanceFromEscrow = new BN(0); + expectedBalanceInEscrow = new BN(0); + }); + describe('Common transfer', () => { before(async () => { - - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ETHETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier) + .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); - tokenSupplyKey = await utils - .createOrder( - users.seller, - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.seller_deposit, - constants.QTY_10) - }) + tokenSupplyKey = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + constants.QTY_10 + ); + }); - it("Should transfer a voucher", async () => { + it('Should transfer a voucher', async () => { voucherID = await utils.commitToBuy( users.other1, users.seller, - tokenSupplyKey) + tokenSupplyKey + ); let transferTx = await utils.safeTransfer721( users.other1.address, users.other2.address, - voucherID, { - from: users.other1.address - }) + voucherID, + { + from: users.other1.address, + } + ); + + truffleAssert.eventEmitted( + transferTx, + 'Transfer', + (ev) => { + assert.equal(ev._from, users.other1.address); + assert.equal(ev._to, users.other2.address); + assert.equal(ev._tokenId.toString(), voucherID); + + return true; + }, + 'Transfer not emitted' + ); + }); + }); + + describe('ETHETH', async () => { + beforeEach(async () => { + await deployContracts(); + + utils = UtilsBuilder.create() + .ETHETH() + .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); + + tokenSupplyKey = await utils.createOrder( + users.seller, + constants.PROMISE_VALID_FROM, + constants.PROMISE_VALID_TO, + constants.seller_deposit, + constants.QTY_10 + ); + }); + + it('Should update escrow amounts after transfer', async () => { + expectedBalanceInEscrow = new BN(constants.product_price).add( + new BN(constants.buyer_deposit) + ); + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); + + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + 'Old owner balance from escrow does not match' + ); + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(ZERO), + 'New owner balance from escrow does not match' + ); + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); + + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); + + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(ZERO), + 'Old owner balance from escrow does not match' + ); + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + 'New owner balance from escrow does not match' + ); + }); + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))); + // 0.0125 + const expectedSellerAmount = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmount = new BN(constants.seller_deposit).div( + new BN(4) + ); + + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); + + await utils.refund(voucherID, users.other2.address); + await utils.complain(voucherID, users.other2.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.other2.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); + + await truffleAssert.reverts( + utils.redeem(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + + await truffleAssert.reverts( + utils.refund(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); + + await truffleAssert.reverts( + utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.attacker.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); + + describe('[WITH PERMIT]', () => { + describe('ETHTKN', () => { + let balanceBuyerFromDeposits = new BN(0); + let balanceSellerFromDeposits = new BN(0); + let escrowBalanceFromDeposits = new BN(0); + + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); + + async function getBalancesDepositToken() { + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.other2.address + ); + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.seller.address + ); + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.deployer.address + ); + cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf( + utils.contractCashier.address + ); + } + + beforeEach(async () => { + await deployContracts(); + + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETHTKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit + ); + + const timestamp = await Utils.getCurrTimestamp(); + + const supplyQty = 1; + const tokensToMint = new BN(constants.seller_deposit).mul( + new BN(supplyQty) + ); + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint + ); + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.other1.address, + constants.buyer_deposit + ); + + tokenSupplyKey = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ); + }); - truffleAssert.eventEmitted( - transferTx, - 'Transfer', - (ev) => { - assert.equal(ev._from, users.other1.address) - assert.equal(ev._to, users.other2.address) - assert.equal(ev._tokenId.toString(), voucherID) + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0), + }; - return true - }, "Transfer not emitted") - }) - }) + balanceBuyerFromPayment = new BN(0); + balanceBuyerFromDeposits = new BN(0); - describe("ETHETH", async () => { - beforeEach(async () => { - await deployContracts() + balanceSellerFromPayment = new BN(0); + balanceSellerFromDeposits = new BN(0); - utils = UtilsBuilder.create() - .ETHETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier) + escrowBalanceFromPayment = new BN(0); + escrowBalanceFromDeposits = new BN(0); - tokenSupplyKey = await utils.createOrder( - users.seller, - constants.PROMISE_VALID_FROM, - constants.PROMISE_VALID_TO, - constants.seller_deposit, - constants.QTY_10) - }) + cashierPaymentLeft = new BN(0); + cashierDepositLeft = new BN(0); - it("Should update escrow amounts after transfer", async () => { - expectedBalanceInEscrow = - new BN(constants.product_price) - .add(new BN(constants.buyer_deposit)) - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) + const isPaused = await contractCashier.paused(); + if (isPaused) { + await contractCashier.unpause(); + } + }); - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + it('Should update escrow amounts after transfer', async () => { + expectedBalanceInEscrow = new BN(constants.product_price); + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); - assert.isTrue( - actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "Old owner balance from escrow does not match") - assert.isTrue( - actualNewOwnerBalanceFromEscrow.eq(ZERO), - "New owner balance from escrow does not match") + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); - await utils.safeTransfer721( - users.other1.address, - users.other2.address, voucherID, { - from: users.other1.address - }) + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + 'Old owner balance from escrow does not match' + ); + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(ZERO), + 'New owner balance from escrow does not match' + ); - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); - assert.isTrue( - actualOldOwnerBalanceFromEscrow.eq(ZERO), - "Old owner balance from escrow does not match") - assert.isTrue( - actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "New owner balance from escrow does not match") - }) + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - // 0.3 + 0.04 + 0.025 - const expectedBuyerAmount = - new BN(constants.buyer_deposit) - .add(new BN(constants.product_price)) - .add(new BN(constants.seller_deposit).div(new BN(2))) + assert.isTrue( + actualOldOwnerBalanceFromEscrow.eq(ZERO), + 'Old owner balance from escrow does not match' + ); + assert.isTrue( + actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), + 'New owner balance from escrow does not match' + ); + }); + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); // 0.0125 - const expectedSellerAmount = - new BN(constants.seller_deposit).div(new BN(4)) + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); // 0.0125 - const expectedEscrowAmount = - new BN(constants.seller_deposit).div(new BN(4)) + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); await utils.safeTransfer721( users.other1.address, users.other2.address, - voucherID, { - from: users.other1.address - }) + voucherID, + { + from: users.other1.address, + } + ); + + await utils.refund(voucherID, users.other2.address); + await utils.complain(voucherID, users.other2.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); - await utils.refund(voucherID, users.other2.address) - await utils.complain(voucherID, users.other2.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) + await getBalancesDepositToken(); + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal(ev._payee, users.other2.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedBuyerPrice)); + + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + + //Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'NewVoucherOwner did not get expected tokens from ' + + 'DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); - const withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) + //Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, @@ -3026,108 +3724,141 @@ contract("Cashier && VK", async addresses => { distributedAmounts, '_to', users.other2.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + }); + + it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); await utils.safeTransfer721( users.other1.address, users.other2.address, - voucherID, { - from: users.other1.address - }) + voucherID, + { + from: users.other1.address, + } + ); await truffleAssert.reverts( utils.redeem(voucherID, users.other1.address), truffleAssert.ErrorType.REVERT - ) + ); await truffleAssert.reverts( utils.refund(voucherID, users.other1.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + }); - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) + it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); await truffleAssert.reverts( utils.safeTransfer721( users.other1.address, users.other2.address, - voucherID, { - from: users.attacker.address - }), + voucherID, + { + from: users.attacker.address, + } + ), truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("[WITH PERMIT]", () => { - describe("ETHTKN", () => { - let balanceBuyerFromDeposits = new BN(0) - let balanceSellerFromDeposits = new BN(0) - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - async function getBalancesDepositToken () { - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.other2.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.seller.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.deployer.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit - .balanceOf(utils.contractCashier.address) + ); + }); + }); + + describe('TKNTKN', () => { + let balanceBuyerFromPayment = new BN(0); + let balanceBuyerFromDeposits = new BN(0); + + let balanceSellerFromPayment = new BN(0); + let balanceSellerFromDeposits = new BN(0); + + let escrowBalanceFromPayment = new BN(0); + let escrowBalanceFromDeposits = new BN(0); + + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); + + async function getBalancesFromPriceTokenAndDepositToken() { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.other2.address + ); + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.other2.address + ); + + balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.seller.address + ); + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.seller.address + ); + + escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.deployer.address + ); + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.deployer.address + ); + + cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf( + utils.contractCashier.address + ); + cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf( + utils.contractCashier.address + ); } beforeEach(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() - .ETHTKN() + .TKNTKN() .build( contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - const supplyQty = 1 - const tokensToMint = - new BN(constants.seller_deposit).mul(new BN(supplyQty)) + const supplyQty = 1; + const tokensToMint = new BN(constants.seller_deposit).mul( + new BN(supplyQty) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.seller.address, - tokensToMint) + tokensToMint + ); + await utils.mintTokens( + 'contractBSNTokenPrice', + users.other1.address, + constants.product_price + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.other1.address, - constants.buyer_deposit) + constants.buyer_deposit + ); tokenSupplyKey = await utils.createOrder( users.seller, @@ -3135,399 +3866,160 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, supplyQty - ) - }) - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyerFromPayment = new BN(0) - balanceBuyerFromDeposits = new BN(0) - - balanceSellerFromPayment = new BN(0) - balanceSellerFromDeposits = new BN(0) + ); + }); + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + const expectedSellerPrice = new BN(0); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); + const expectedEscrowAmountPrice = new BN(0); - escrowBalanceFromPayment = new BN(0) - escrowBalanceFromDeposits = new BN(0) + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); - const isPaused = await contractCashier.paused() - if (isPaused) { - await contractCashier.unpause() - } - }) - - it("Should update escrow amounts after transfer", - async () => { - expectedBalanceInEscrow = new BN(constants.product_price) - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) - - assert.isTrue( - actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "Old owner balance from escrow does not match") - assert.isTrue( - actualNewOwnerBalanceFromEscrow.eq(ZERO), - "New owner balance from escrow does not match") - - await utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.other1.address - }) - - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) - - assert.isTrue( - actualOldOwnerBalanceFromEscrow.eq(ZERO), - "Old owner balance from escrow does not match") - assert.isTrue( - actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - await utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.other1.address - }) - - await utils.refund(voucherID, users.other2.address) - await utils.complain(voucherID, users.other2.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) - - await getBalancesDepositToken() - - // Payment should have been returned to buyer - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.other2.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogAmountDistribution was not emitted") - - //Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "NewVoucherOwner did not get expected tokens from " + - "DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - //Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.other2.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - await utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.other1.address - }) + await utils.refund(voucherID, users.other2.address); + await utils.complain(voucherID, users.other2.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); - await truffleAssert.reverts( - utils.redeem(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) + const withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); - await truffleAssert.reverts( - utils.refund(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) - }) + await getBalancesFromPriceTokenAndDepositToken(); - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); - await truffleAssert.reverts( - utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("TKNTKN", () => { - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDeposits = new BN(0) - - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDeposits = new BN(0) - - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - async function getBalancesFromPriceTokenAndDepositToken () { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.other2.address) - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.other2.address) - - balanceSellerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.seller.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.seller.address) - - escrowBalanceFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.deployer.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.deployer.address) - - cashierPaymentLeft = await utils.contractBSNTokenPrice - .balanceOf(utils.contractCashier.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit - .balanceOf(utils.contractCashier.address) - } + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); - beforeEach(async () => { - await deployContracts() + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); - utils = UtilsBuilder.create() - .ERC20withPermit() - .TKNTKN() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - contractBSNTokenDeposit) + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); - const timestamp = await Utils.getCurrTimestamp() + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); - const supplyQty = 1 - const tokensToMint = - new BN(constants.seller_deposit).mul(new BN(supplyQty)) + await truffleAssert.reverts( + utils.redeem(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.seller.address, - tokensToMint) - await utils.mintTokens( - 'contractBSNTokenPrice', - users.other1.address, - constants.product_price) - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.other1.address, - constants.buyer_deposit) + await truffleAssert.reverts( + utils.refund(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + }); - tokenSupplyKey = await utils.createOrder( + it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { + voucherID = await utils.commitToBuy( + users.other1, users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - supplyQty - ) - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - const expectedSellerPrice = new BN(0) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - const expectedEscrowAmountPrice = new BN(0) - - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - await utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.other1.address - }) - - await utils.refund(voucherID, users.other2.address) - await utils.complain(voucherID, users.other2.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - await utils.safeTransfer721( + tokenSupplyKey + ); + + await truffleAssert.reverts( + utils.safeTransfer721( users.other1.address, users.other2.address, - voucherID, { - from: users.other1.address - }) - - await truffleAssert.reverts( - utils.redeem(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) - - await truffleAssert.reverts( - utils.refund(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) - - }) - - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - await truffleAssert.reverts( - utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - }) + voucherID, + { + from: users.attacker.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNETH", () => { - let balanceBuyerFromPayment = new BN(0) - let balanceSellerFromPayment = new BN(0) - let escrowBalanceFromPayment = new BN(0) + describe('TKNETH', () => { + let balanceBuyerFromPayment = new BN(0); + let balanceSellerFromPayment = new BN(0); + let escrowBalanceFromPayment = new BN(0); - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); beforeEach(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() @@ -3537,14 +4029,16 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - '') + '' + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); await utils.mintTokens( 'contractBSNTokenPrice', users.other1.address, - constants.product_price) + constants.product_price + ); tokenSupplyKey = await utils.createOrder( users.seller, @@ -3552,185 +4046,231 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_1 - ) - }) - - async function getBalancesPriceToken () { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.other2.address) - balanceSellerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.seller.address) - escrowBalanceFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.deployer.address) - cashierPaymentLeft = await utils.contractBSNTokenPrice - .balanceOf(utils.contractCashier.address) + ); + }); + + async function getBalancesPriceToken() { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.other2.address + ); + balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.seller.address + ); + escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.deployer.address + ); + cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf( + utils.contractCashier.address + ); } - it("Should update escrow amounts after transfer", async () => { - expectedBalanceInEscrow = new BN(constants.buyer_deposit) - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) + it('Should update escrow amounts after transfer', async () => { + expectedBalanceInEscrow = new BN(constants.buyer_deposit); + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); assert.isTrue( actualOldOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "Old owner balance from escrow does not match") + 'Old owner balance from escrow does not match' + ); assert.isTrue( actualNewOwnerBalanceFromEscrow.eq(ZERO), - "New owner balance from escrow does not match") + 'New owner balance from escrow does not match' + ); await utils.safeTransfer721( users.other1.address, users.other2.address, - voucherID, { - from: users.other1.address - }) + voucherID, + { + from: users.other1.address, + } + ); - actualOldOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other1.address) - actualNewOwnerBalanceFromEscrow = await contractCashier - .escrow(users.other2.address) + actualOldOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other1.address + ); + actualNewOwnerBalanceFromEscrow = await contractCashier.escrow( + users.other2.address + ); assert.isTrue( actualOldOwnerBalanceFromEscrow.eq(ZERO), - "Old owner balance from escrow does not match") + 'Old owner balance from escrow does not match' + ); assert.isTrue( actualNewOwnerBalanceFromEscrow.eq(expectedBalanceInEscrow), - "New owner balance from escrow does not match") - }) - - it("Should finalize 1 voucher to ensure payments are sent to the new owner", - async () => { - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - await utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.other1.address - }) - - await utils.refund(voucherID, users.other2.address) - await utils.complain(voucherID, users.other2.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await utils - .withdraw(voucherID, users.deployer.address) - - await getBalancesPriceToken() - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") - - // Deposits in ETH - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.other2.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("[NEGATIVE] Old owner should not be able to interact with the voucher", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) - - await utils.safeTransfer721( - users.other1.address, - users.other2.address, - voucherID, { - from: users.other1.address - }) + 'New owner balance from escrow does not match' + ); + }); + + it('Should finalize 1 voucher to ensure payments are sent to the new owner', async () => { + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + const expectedSellerPrice = new BN(0); + const expectedEscrowPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); - await truffleAssert.reverts( - utils.redeem(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); - await truffleAssert.reverts( - utils.refund(voucherID, users.other1.address), - truffleAssert.ErrorType.REVERT - ) - }) + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); - it("[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer", - async () => { - voucherID = await utils - .commitToBuy(users.other1, users.seller, tokenSupplyKey) + await utils.refund(voucherID, users.other2.address); + await utils.complain(voucherID, users.other2.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await utils.withdraw( + voucherID, + users.deployer.address + ); + + await getBalancesPriceToken(); + + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); - await truffleAssert.reverts( - utils.safeTransfer721( - users.other1.address, + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', users.other2.address, - voucherID, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) -}) + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); + + await utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.other1.address, + } + ); + + await truffleAssert.reverts( + utils.redeem(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + + await truffleAssert.reverts( + utils.refund(voucherID, users.other1.address), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { + voucherID = await utils.commitToBuy( + users.other1, + users.seller, + tokenSupplyKey + ); + + await truffleAssert.reverts( + utils.safeTransfer721( + users.other1.address, + users.other2.address, + voucherID, + { + from: users.attacker.address, + } + ), + truffleAssert.ErrorType.REVERT + ); + }); + }); + }); + }); +}); diff --git a/test/3_withdrawals.js b/test/3_withdrawals.js index dc4d77d3..d6eb93da 100644 --- a/test/3_withdrawals.js +++ b/test/3_withdrawals.js @@ -1,656 +1,2200 @@ -const chai = require('chai') -const truffleAssert = require('truffle-assertions') +const chai = require('chai'); +const truffleAssert = require('truffle-assertions'); -const constants = require("../testHelpers/constants") -const timemachine = require('../testHelpers/timemachine') -const Users = require('../testHelpers/users') -const UtilsBuilder = require('../testHelpers/utilsBuilder') -const Utils = require('../testHelpers/utils') +const constants = require('../testHelpers/constants'); +const timemachine = require('../testHelpers/timemachine'); +const Users = require('../testHelpers/users'); +const UtilsBuilder = require('../testHelpers/utilsBuilder'); +const Utils = require('../testHelpers/utils'); -const assert = chai.assert +const assert = chai.assert; -const BN = web3.utils.BN +const BN = web3.utils.BN; -const ERC1155ERC721 = artifacts.require("ERC1155ERC721") -const VoucherKernel = artifacts.require("VoucherKernel") -const Cashier = artifacts.require("Cashier") -const BosonTKN = artifacts.require("BosonTokenPrice") -const FundLimitsOracle = artifacts.require('FundLimitsOracle') +const ERC1155ERC721 = artifacts.require('ERC1155ERC721'); +const VoucherKernel = artifacts.require('VoucherKernel'); +const Cashier = artifacts.require('Cashier'); +const BosonTKN = artifacts.require('BosonTokenPrice'); +const FundLimitsOracle = artifacts.require('FundLimitsOracle'); -let utils +let utils; -let TOKEN_SUPPLY_ID +let TOKEN_SUPPLY_ID; -contract("Cashier withdrawals ", async addresses => { - const users = new Users(addresses) +contract('Cashier withdrawals ', async (addresses) => { + const users = new Users(addresses); let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit, - contractFundLimitsOracle + contractFundLimitsOracle; - const PAUSED_WITH_PERMIT = 1 - const PAUSED_LABEL = "[PAUSED]" + const PAUSED_WITH_PERMIT = 1; + const PAUSED_LABEL = '[PAUSED]'; let distributedAmounts = { buyerAmount: new BN(0), sellerAmount: new BN(0), - escrowAmount: new BN(0) - } + escrowAmount: new BN(0), + }; - async function deployContracts () { - const sixtySeconds = 60 + async function deployContracts() { + const sixtySeconds = 60; - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new() - contractVoucherKernel = - await VoucherKernel.new(contractERC1155ERC721.address) + contractFundLimitsOracle = await FundLimitsOracle.new(); + contractERC1155ERC721 = await ERC1155ERC721.new(); + contractVoucherKernel = await VoucherKernel.new( + contractERC1155ERC721.address + ); contractCashier = await Cashier.new( contractVoucherKernel.address, contractERC1155ERC721.address, - contractFundLimitsOracle.address) - contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC') - contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP') - - await contractERC1155ERC721 - .setApprovalForAll(contractVoucherKernel.address, 'true') - await contractERC1155ERC721 - .setVoucherKernelAddress(contractVoucherKernel.address) - await contractVoucherKernel - .setCashierAddress(contractCashier.address) - - await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenPrice.address, constants.TOKEN_LIMIT) - await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenDeposit.address, constants.TOKEN_LIMIT) - await contractFundLimitsOracle - .setETHLimit(constants.ETHER_LIMIT) - - await contractVoucherKernel.setComplainPeriod(sixtySeconds) - await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds) + contractFundLimitsOracle.address + ); + contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC'); + contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP'); + + await contractERC1155ERC721.setApprovalForAll( + contractVoucherKernel.address, + 'true' + ); + await contractERC1155ERC721.setVoucherKernelAddress( + contractVoucherKernel.address + ); + await contractVoucherKernel.setCashierAddress(contractCashier.address); + + await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenPrice.address, + constants.TOKEN_LIMIT + ); + await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenDeposit.address, + constants.TOKEN_LIMIT + ); + await contractFundLimitsOracle.setETHLimit(constants.ETHER_LIMIT); + + await contractVoucherKernel.setComplainPeriod(sixtySeconds); + await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds); + } + + // this functions is used after each interaction with tokens to clear + // balances + async function giveAwayToRandom() { + const balanceBuyerFromPayment = await contractBSNTokenPrice.balanceOf( + users.buyer.address + ); + const balanceBuyerFromDesosits = await contractBSNTokenDeposit.balanceOf( + users.buyer.address + ); + + const balanceSellerFromPayment = await contractBSNTokenPrice.balanceOf( + users.seller.address + ); + const balanceSellerFromDesosits = await contractBSNTokenDeposit.balanceOf( + users.seller.address + ); + + const escrowBalanceFromPayment = await contractBSNTokenPrice.balanceOf( + users.deployer.address + ); + const escrowBalanceFromDeposits = await contractBSNTokenDeposit.balanceOf( + users.deployer.address + ); + + await contractBSNTokenPrice.transfer( + users.other1.address, + balanceBuyerFromPayment, + { + from: users.buyer.address, + } + ); + await contractBSNTokenDeposit.transfer( + users.other1.address, + balanceBuyerFromDesosits, + { + from: users.buyer.address, + } + ); + await contractBSNTokenPrice.transfer( + users.other1.address, + balanceSellerFromPayment, + { + from: users.seller.address, + } + ); + await contractBSNTokenDeposit.transfer( + users.other1.address, + balanceSellerFromDesosits, + { + from: users.seller.address, + } + ); + await contractBSNTokenPrice.transfer( + users.other1.address, + escrowBalanceFromPayment, + { + from: users.deployer.address, + } + ); + await contractBSNTokenDeposit.transfer( + users.other1.address, + escrowBalanceFromDeposits, + { + from: users.deployer.address, + } + ); + } + + async function withdraw(utils, index, voucherID) { + if (index === 1) { + await utils.pause(users.deployer.address); + return await utils.withdrawWhenPaused(voucherID, users.seller.address); + } else { + return await utils.withdraw(voucherID, users.deployer.address); + } } - // this functions is used after each interaction with tokens to clear - // balances - async function giveAwayToRandom () { - const balanceBuyerFromPayment = await contractBSNTokenPrice - .balanceOf(users.buyer.address) - const balanceBuyerFromDesosits = await contractBSNTokenDeposit - .balanceOf(users.buyer.address) - - const balanceSellerFromPayment = await contractBSNTokenPrice - .balanceOf(users.seller.address) - const balanceSellerFromDesosits = await contractBSNTokenDeposit - .balanceOf(users.seller.address) - - const escrowBalanceFromPayment = await contractBSNTokenPrice - .balanceOf(users.deployer.address) - const escrowBalanceFromDeposits = await contractBSNTokenDeposit - .balanceOf(users.deployer.address) - - await contractBSNTokenPrice - .transfer( - users.other1.address, - balanceBuyerFromPayment, { - from: users.buyer.address - }) - await contractBSNTokenDeposit - .transfer( - users.other1.address, - balanceBuyerFromDesosits, { - from: users.buyer.address - }) - await contractBSNTokenPrice - .transfer( - users.other1.address, - balanceSellerFromPayment, { - from: users.seller.address - }) - await contractBSNTokenDeposit - .transfer( - users.other1.address, - balanceSellerFromDesosits, { - from: users.seller.address - }) - await contractBSNTokenPrice - .transfer( - users.other1.address, - escrowBalanceFromPayment, { - from: users.deployer.address - }) - await contractBSNTokenDeposit - .transfer( - users.other1.address, - escrowBalanceFromDeposits, { - from: users.deployer.address - }) - } + for (let i = 0; i <= PAUSED_WITH_PERMIT; i++) { + describe('Withdraw scenarios', async () => { + before(async () => { + await deployContracts(); + }); + + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0), + }; + + const isPaused = await contractCashier.paused(); + if (isPaused) { + await contractCashier.unpause(); + } + }); + + describe(`ETH - ETH${ + i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : '' + }`, async () => { + before(async () => { + utils = UtilsBuilder.create() + .ETHETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier + ); + + const timestamp = await Utils.getCurrTimestamp(); + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ); + }); + + it('COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))); + // 0.0125 + const expectedSellerAmount = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmount = new BN(constants.seller_deposit).div( + new BN(4) + ); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW', async () => { + // 0.3 + const expectedBuyerAmount = new BN(constants.product_price); + // 0 + const expectedSellerAmount = new BN(0); + // 0.09 + const expectedEscrowAmount = new BN(constants.seller_deposit).add( + new BN(constants.buyer_deposit) + ); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await timemachine.advanceTimeSeconds(60); + + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW', async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))); + // 0.025 + const expectedSellerAmount = new BN(constants.seller_deposit).div( + new BN(2) + ); + // 0 + const expectedEscrowAmount = new BN(0); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->REFUND->FINALIZE->WITHDRAW', async () => { + // 0.3 + const expectedBuyerAmount = new BN(constants.product_price); + // 0.05 + const expectedSellerAmount = new BN(constants.seller_deposit); + // 0.04 + const expectedEscrowAmount = new BN(constants.buyer_deposit); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->CANCEL->FINALIZE->WITHDRAW', async () => { + // 0.3 + 0.04 + 0.025 + const expectedBuyerAmount = new BN(constants.buyer_deposit) + .add(new BN(constants.product_price)) + .add(new BN(constants.seller_deposit).div(new BN(2))); + // 0.025 + const expectedSellerAmount = new BN(constants.seller_deposit).div( + new BN(2) + ); + // 0 + const expectedEscrowAmount = new BN(0); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->REDEEM->FINALIZE->WITHDRAW', async () => { + // 0.04 + const expectedBuyerAmount = new BN(constants.buyer_deposit); + // 0.35 + const expectedSellerAmount = new BN(constants.seller_deposit).add( + new BN(constants.product_price) + ); + // 0 + const expectedEscrowAmount = new BN(0); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW', async () => { + // 0.04 + const expectedBuyerAmount = new BN(constants.buyer_deposit); + // 0.3 + const expectedSellerAmount = new BN(constants.product_price); + // 0.05 + const expectedEscrowAmount = new BN(constants.seller_deposit); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + // 0.065 + const expectedBuyerAmount = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.3125 + const expectedSellerAmount = new BN(constants.product_price).add( + new BN(constants.seller_deposit).div(new BN(4)) + ); + // 0.0125 + const expectedEscrowAmount = new BN(constants.seller_deposit).div( + new BN(4) + ); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + + it('COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW', async () => { + // 0.065 + const expectedBuyerAmount = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.325 + const expectedSellerAmount = new BN(constants.product_price).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0 + const expectedEscrowAmount = new BN(0); + + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_to', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); + + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerAmount), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerAmount), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmount), + 'Escrow Amount is not as expected' + ); + }); + }); + + describe( + 'TKN - TKN [WITH PERMIT]' + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, + async () => { + let balanceBuyerFromPayment = new BN(0); + let balanceBuyerFromDeposits = new BN(0); + + let balanceSellerFromPayment = new BN(0); + let balanceSellerFromDeposits = new BN(0); + + let escrowBalanceFromPayment = new BN(0); + let escrowBalanceFromDeposits = new BN(0); + + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); + + async function getBalancesFromPriceTokenAndDepositToken() { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.buyer.address + ); + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.buyer.address + ); + + balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.seller.address + ); + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.seller.address + ); + + escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.deployer.address + ); + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.deployer.address + ); + + cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf( + utils.contractCashier.address + ); + cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf( + utils.contractCashier.address + ); + } + + beforeEach(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKNTKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit + ); + + const timestamp = await Utils.getCurrTimestamp(); + + const supplyQty = 1; + const tokensToMint = new BN(constants.seller_deposit).mul( + new BN(supplyQty) + ); + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMint + ); + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + constants.product_price + ); + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + constants.buyer_deposit + ); + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + supplyQty + ); + }); + + it('COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + const expectedSellerPrice = new BN(0); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); + const expectedEscrowAmountPrice = new BN(0); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + const expectedBuyerDeposit = new BN(0); + const expectedSellerPrice = new BN(0); + const expectedSellerDeposit = new BN(0); + // 0.09 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).add(new BN(constants.buyer_deposit)); + const expectedEscrowAmountPrice = new BN(0); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + const expectedSellerPrice = new BN(0); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); + const expectedEscrowAmountPrice = new BN(0); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REFUND->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + const expectedBuyerDeposit = new BN(0); + const expectedSellerPrice = new BN(0); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit); + const expectedEscrowAmountPrice = new BN(0); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + //Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + const expectedSellerPrice = new BN(0); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountPrice = new BN(0); + const expectedEscrowAmountDeposit = new BN(0); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + const expectedEscrowAmountDeposit = new BN(0); + const expectedEscrowAmountPrice = new BN(0); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + const expectedSellerDeposit = new BN(0); + const expectedEscrowAmountPrice = new BN(0); + // 0.05 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + const expectedEscrowAmountPrice = new BN(0); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.redeem(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountPrice = new BN(0); + const expectedEscrowAmountDeposit = new BN(0); + + await getBalancesFromPriceTokenAndDepositToken(); + + // Payments + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PriceTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), + 'Escrow did not get expected tokens from PriceTokenContract' + ); + + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0), + }; + + balanceBuyerFromPayment = new BN(0); + balanceBuyerFromDeposits = new BN(0); - async function withdraw (utils, index, voucherID) { - if (index === 1) { - await utils.pause(users.deployer.address) - return await utils.withdrawWhenPaused(voucherID, users.seller.address) - } else { - return await utils.withdraw(voucherID, users.deployer.address) - } - } + balanceSellerFromPayment = new BN(0); + balanceSellerFromDeposits = new BN(0); - for (let i = 0; i <= PAUSED_WITH_PERMIT; i++) { - describe('Withdraw scenarios', async () => { + escrowBalanceFromPayment = new BN(0); + escrowBalanceFromDeposits = new BN(0); - before(async () => { - await deployContracts() - }) + cashierPaymentLeft = new BN(0); + cashierDepositLeft = new BN(0); - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } + await giveAwayToRandom(); - const isPaused = await contractCashier.paused() - if (isPaused) { - await contractCashier.unpause() + const isPaused = await contractCashier.paused(); + if (isPaused) { + await contractCashier.unpause(); + } + }); } - }) + ); - describe(`ETH - ETH${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, + // Ignored due to deployment failure. + xdescribe( + 'TKN - TKN SAME [WITH PERMIT]' + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { - before(async () => { + let balanceBuyer = new BN(0); + let balanceSeller = new BN(0); + let escrowBalance = new BN(0); + let cashierBalance = new BN(0); + + async function getBalancesFromSameTokenContract() { + balanceBuyer = await utils.contractBSNTokenSAME.balanceOf( + users.buyer.address + ); + balanceSeller = await utils.contractBSNTokenSAME.balanceOf( + users.seller.address + ); + escrowBalance = await utils.contractBSNTokenSAME.balanceOf( + users.deployer.address + ); + cashierBalance = await utils.contractBSNTokenSAME.balanceOf( + utils.contractCashier.address + ); + } + + beforeEach(async () => { utils = UtilsBuilder.create() - .ETHETH() + .ERC20withPermit() + .TKNTKNSAME() .build( contractERC1155ERC721, contractVoucherKernel, - contractCashier) + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit + ); + + const timestamp = await Utils.getCurrTimestamp(); + + const supplyQty = 1; + const tokensToMintSeller = new BN(constants.seller_deposit).mul( + new BN(supplyQty) + ); + const tokensToMintBuyer = new BN(constants.product_price).add( + new BN(constants.buyer_deposit) + ); - const timestamp = await Utils.getCurrTimestamp() + await utils.mintTokens( + 'contractBSNTokenSAME', + users.seller.address, + tokensToMintSeller + ); + await utils.mintTokens( + 'contractBSNTokenSAME', + users.buyer.address, + tokensToMintBuyer + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_10) - }) - - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { - // 0.3 + 0.04 + 0.025 - const expectedBuyerAmount = - new BN(constants.buyer_deposit) - .add(new BN(constants.product_price)) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.0125 - const expectedSellerAmount = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmount = - new BN(constants.seller_deposit).div(new BN(4)) - - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) - const withdrawTx = await withdraw(utils, i, voucherID) - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) - - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", - async () => { - // 0.3 - const expectedBuyerAmount = new BN(constants.product_price) - // 0 - const expectedSellerAmount = new BN(0) - // 0.09 - const expectedEscrowAmount = - new BN(constants.seller_deposit) - .add(new BN(constants.buyer_deposit)) - - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", - async () => { - // 0.3 + 0.04 + 0.025 - const expectedBuyerAmount = - new BN(constants.buyer_deposit) - .add(new BN(constants.product_price)) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.025 - const expectedSellerAmount = - new BN(constants.seller_deposit).div(new BN(2)) - // 0 - const expectedEscrowAmount = new BN(0) - - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { + supplyQty + ); + }); + + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0), + }; + + balanceBuyer = new BN(0); + balanceSeller = new BN(0); + escrowBalance = new BN(0); + cashierBalance = new BN(0); + + await giveAwayToRandom(); + + const isPaused = await contractCashier.paused(); + if (isPaused) { + await contractCashier.unpause(); + } + }); + + it('COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + // 0.3 - const expectedBuyerAmount = new BN(constants.product_price) - // 0.05 - const expectedSellerAmount = new BN(constants.seller_deposit) - // 0.04 - const expectedEscrowAmount = new BN(constants.buyer_deposit) + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + const expectedSellerPrice = new BN(0); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); + const expectedEscrowAmountPrice = new BN(0); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + await getBalancesFromSameTokenContract(); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); - const withdrawTx = await withdraw(utils, i, voucherID) + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + const expectedBuyerDeposit = new BN(0); + const expectedSellerPrice = new BN(0); + const expectedSellerDeposit = new BN(0); + // 0.09 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).add(new BN(constants.buyer_deposit)); + const expectedEscrowAmountPrice = new BN(0); + + await getBalancesFromSameTokenContract(); assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - // 0.3 + 0.04 + 0.025 - const expectedBuyerAmount = - new BN(constants.buyer_deposit) - .add(new BN(constants.product_price)) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.025 - const expectedSellerAmount = + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( new BN(constants.seller_deposit).div(new BN(2)) - // 0 - const expectedEscrowAmount = new BN(0) + ); + const expectedSellerPrice = new BN(0); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); + const expectedEscrowAmountPrice = new BN(0); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.cancel(voucherID, users.seller.address) + await getBalancesFromSameTokenContract(); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); - const withdrawTx = await withdraw(utils, i, voucherID) + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REFUND->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + const expectedBuyerDeposit = new BN(0); + const expectedSellerPrice = new BN(0); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit); + const expectedEscrowAmountPrice = new BN(0); + + await getBalancesFromSameTokenContract(); assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - // 0.04 - const expectedBuyerAmount = new BN(constants.buyer_deposit) - // 0.35 - const expectedSellerAmount = - new BN(constants.seller_deposit) - .add(new BN(constants.product_price)) - // 0 - const expectedEscrowAmount = new BN(0) + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(voucherID, users.buyer.address) + it('COMMIT->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + const expectedSellerPrice = new BN(0); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountPrice = new BN(0); + const expectedEscrowAmountDeposit = new BN(0); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await getBalancesFromSameTokenContract(); + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); - const withdrawTx = await withdraw(utils, i, voucherID) + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + const expectedEscrowAmountDeposit = new BN(0); + const expectedEscrowAmountPrice = new BN(0); + await getBalancesFromSameTokenContract(); + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); + + // Cashier Should be Empty assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); // 0.04 - const expectedBuyerAmount = new BN(constants.buyer_deposit) + const expectedBuyerDeposit = new BN(constants.buyer_deposit); // 0.3 - const expectedSellerAmount = new BN(constants.product_price) + const expectedSellerPrice = new BN(constants.product_price); + const expectedSellerDeposit = new BN(0); + const expectedEscrowAmountPrice = new BN(0); // 0.05 - const expectedEscrowAmount = new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) + await getBalancesFromSameTokenContract(); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); - const withdrawTx = await withdraw(utils, i, voucherID) + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) - - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { - // 0.065 - const expectedBuyerAmount = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit) - .div(new BN(2))) - // 0.3125 - const expectedSellerAmount = - new BN(constants.product_price) - .add(new BN(constants.seller_deposit).div(new BN(4))) - // 0.0125 - const expectedEscrowAmount = - new BN(constants.seller_deposit).div(new BN(4)) - - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) - - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); // 0.065 - const expectedBuyerAmount = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.325 - const expectedSellerAmount = - new BN(constants.product_price) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0 - const expectedEscrowAmount = new BN(0) + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + const expectedEscrowAmountPrice = new BN(0); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); + + await getBalancesFromSameTokenContract(); + + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); + + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + + it('COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + + await utils.redeem(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountPrice = new BN(0); + const expectedEscrowAmountDeposit = new BN(0); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + await getBalancesFromSameTokenContract(); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + assert.isTrue( + balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), + 'Buyer did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), + 'Seller did not get expected tokens from SameTokenContract' + ); + assert.isTrue( + escrowBalance.eq( + expectedEscrowAmountPrice.add(expectedEscrowAmountDeposit) + ), + 'Escrow did not get expected tokens from SameTokenContract' + ); - const withdrawTx = await withdraw(utils, i, voucherID) + // Cashier Should be Empty + assert.isTrue( + cashierBalance.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_to', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerAmount), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerAmount), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmount), - 'Escrow Amount is not as expected') - }) - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + } + ); - describe("TKN - TKN [WITH PERMIT]" + - `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, + describe( + 'ETH - TKN [WITH PERMIT]' + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDeposits = new BN(0) - - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDeposits = new BN(0) - - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - async function getBalancesFromPriceTokenAndDepositToken () { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.buyer.address) - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.buyer.address) - - balanceSellerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.seller.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.seller.address) - - escrowBalanceFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.deployer.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.deployer.address) - - cashierPaymentLeft = await utils.contractBSNTokenPrice - .balanceOf(utils.contractCashier.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit - .balanceOf(utils.contractCashier.address) + let balanceBuyerFromPayment = new BN(0); + let balanceBuyerFromDeposits = new BN(0); + + let balanceSellerFromPayment = new BN(0); + let balanceSellerFromDeposits = new BN(0); + + let escrowBalanceFromPayment = new BN(0); + let escrowBalanceFromDeposits = new BN(0); + + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); + + async function getBalancesDepositToken() { + balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.buyer.address + ); + balanceSellerFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.seller.address + ); + escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit.balanceOf( + users.deployer.address + ); + cashierDepositLeft = await utils.contractBSNTokenDeposit.balanceOf( + utils.contractCashier.address + ); } beforeEach(async () => { utils = UtilsBuilder.create() .ERC20withPermit() - .TKNTKN() + .ETHTKN() .build( contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - const supplyQty = 1 - const tokensToMint = - new BN(constants.seller_deposit).mul(new BN(supplyQty)) + const supplyQty = 1; + const tokensToMint = new BN(constants.seller_deposit).mul( + new BN(supplyQty) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.seller.address, - tokensToMint) - await utils.mintTokens( - 'contractBSNTokenPrice', - users.buyer.address, - constants.product_price) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.buyer.address, - constants.buyer_deposit) + constants.buyer_deposit + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -658,2016 +2202,1297 @@ contract("Cashier withdrawals ", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, supplyQty - ) - }) - - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - const expectedSellerPrice = new BN(0) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", - async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(0) - // 0.09 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit) - .add(new BN(constants.buyer_deposit)) - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", - async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - const expectedSellerPrice = new BN(0) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { + ); + }); + + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0), + }; + + balanceBuyerFromPayment = new BN(0); + balanceBuyerFromDeposits = new BN(0); + + balanceSellerFromPayment = new BN(0); + balanceSellerFromDeposits = new BN(0); + + escrowBalanceFromPayment = new BN(0); + escrowBalanceFromDeposits = new BN(0); + + cashierPaymentLeft = new BN(0); + cashierDepositLeft = new BN(0); + + await giveAwayToRandom(); + + const isPaused = await contractCashier.paused(); + if (isPaused) { + await contractCashier.unpause(); + } + }); + + it('COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, users.buyer.address) + ); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - // 0.04 - const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) - const expectedEscrowAmountPrice = new BN(0) + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); - await getBalancesFromPriceTokenAndDepositToken() + await getBalancesDepositToken(); - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal(ev._payee, users.buyer.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedBuyerPrice)); - //Deposits + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + + // Deposits assert.isTrue( balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") + 'Buyer did not get expected tokens from ' + 'DepositTokenContract' + ); assert.isTrue( balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") + 'Seller did not get expected tokens from ' + + 'DepositTokenContract' + ); assert.isTrue( escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") + 'Escrow did not get expected tokens from ' + + 'DepositTokenContract' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { + it('COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) + ); - await utils.cancel(voucherID, users.seller.address) + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - const expectedSellerPrice = new BN(0) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) + const expectedBuyerPrice = new BN(constants.product_price); + const expectedBuyerDeposit = new BN(0); + const expectedSellerDeposit = new BN(0); + // 0.09 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).add(new BN(constants.buyer_deposit)); - await getBalancesFromPriceTokenAndDepositToken() + await getBalancesDepositToken(); - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal(ev._payee, users.buyer.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedBuyerPrice)); + + return true; + }, + 'Event LogWithdrawal was not emitted' + ); // Deposits assert.isTrue( balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") + 'Buyer did not get expected tokens from DepositTokenContract' + ); assert.isTrue( balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") + 'Seller did not get expected tokens from DepositTokenContract' + ); assert.isTrue( escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") + 'Escrow did not get expected tokens from DepositTokenContract' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { + it('COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) + ); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await utils.refund(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); - const withdrawTx = await withdraw(utils, i, voucherID) + await timemachine.advanceTimeSeconds(60); + + await utils.finalize(voucherID, users.deployer.address); + + const withdrawTx = await withdraw(utils, i, voucherID); - const expectedBuyerPrice = new BN(0) - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) + const expectedBuyerPrice = new BN(constants.product_price); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); - await getBalancesFromPriceTokenAndDepositToken() + await getBalancesDepositToken(); - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal(ev._payee, users.buyer.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedBuyerPrice)); + + return true; + }, + 'Event LogWithdrawal was not emitted' + ); // Deposits assert.isTrue( balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") + 'Buyer did not get expected tokens from ' + 'DepositTokenContract' + ); assert.isTrue( balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") + 'Seller did not get expected tokens from ' + + 'DepositTokenContract' + ); assert.isTrue( escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") + 'Escrow did not get expected tokens from ' + + 'DepositTokenContract' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", - async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - // 0.05 - const expectedEscrowAmountDeposit = new BN(constants.seller_deposit) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.3 - const expectedSellerPrice = - new BN(constants.product_price) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - const expectedEscrowAmountPrice = new BN(0) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", - async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesFromPriceTokenAndDepositToken() - - // Payments - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PriceTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PriceTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowAmountPrice), - "Escrow did not get expected tokens from PriceTokenContract") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyerFromPayment = new BN(0) - balanceBuyerFromDeposits = new BN(0) - - balanceSellerFromPayment = new BN(0) - balanceSellerFromDeposits = new BN(0) - - escrowBalanceFromPayment = new BN(0) - escrowBalanceFromDeposits = new BN(0) - - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) - - await giveAwayToRandom() - - const isPaused = await contractCashier.paused() - if (isPaused) { - await contractCashier.unpause() - } - }) - - }) - - // Ignored due to deployment failure. - xdescribe("TKN - TKN SAME [WITH PERMIT]" + - `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { - let balanceBuyer = new BN(0) - let balanceSeller = new BN(0) - let escrowBalance = new BN(0) - let cashierBalance = new BN(0) - - async function getBalancesFromSameTokenContract () { - balanceBuyer = await utils.contractBSNTokenSAME - .balanceOf(users.buyer.address) - balanceSeller = await utils.contractBSNTokenSAME - .balanceOf(users.seller.address) - escrowBalance = await utils.contractBSNTokenSAME - .balanceOf(users.deployer.address) - cashierBalance = await utils.contractBSNTokenSAME - .balanceOf(utils.contractCashier.address) - } - - beforeEach(async () => { - utils = UtilsBuilder.create() - .ERC20withPermit() - .TKNTKNSAME() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - contractBSNTokenDeposit) - - const timestamp = await Utils.getCurrTimestamp() - - const supplyQty = 1 - const tokensToMintSeller = - new BN(constants.seller_deposit).mul(new BN(supplyQty)) - const tokensToMintBuyer = - new BN(constants.product_price) - .add(new BN(constants.buyer_deposit)) - - await utils.mintTokens( - 'contractBSNTokenSAME', - users.seller.address, - tokensToMintSeller) - await utils.mintTokens( - 'contractBSNTokenSAME', - users.buyer.address, - tokensToMintBuyer) - - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - supplyQty - ) - }) - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } - - balanceBuyer = new BN(0) - balanceSeller = new BN(0) - escrowBalance = new BN(0) - cashierBalance = new BN(0) - - await giveAwayToRandom() + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - const isPaused = await contractCashier.paused() - if (isPaused) { - await contractCashier.unpause() - } - }) - - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REFUND->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) + ); + await utils.refund(voucherID, users.buyer.address); - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - const expectedSellerPrice = new BN(0) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - const expectedEscrowAmountPrice = new BN(0) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await getBalancesFromSameTokenContract() + const withdrawTx = await withdraw(utils, i, voucherID); - assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") - assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") - assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + const expectedBuyerDeposit = new BN(0); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit); - // Cashier Should be Empty - assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + await getBalancesDepositToken(); + // Payment should have been returned to buyer truffleAssert.eventEmitted( withdrawTx, - 'LogAmountDistribution', + 'LogWithdrawal', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", - async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - const expectedSellerDeposit = new BN(0) - // 0.09 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit) - .add(new BN(constants.buyer_deposit)) - const expectedEscrowAmountPrice = new BN(0) + assert.equal(ev._payee, users.buyer.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedBuyerPrice)); - await getBalancesFromSameTokenContract() + return true; + }, + 'Event LogWithdrawal was not emitted' + ); + // Deposits assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); // Cashier Should be Empty assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->CANCEL->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + ); - await timemachine.advanceTimeSeconds(60) + await utils.cancel(voucherID, users.seller.address); - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) + const expectedBuyerPrice = new BN(constants.product_price); // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - const expectedSellerPrice = new BN(0) - // 0.025 - const expectedSellerDeposit = + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) + ); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); + + await getBalancesDepositToken(); + + // Payment should have been returned to buyer + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal(ev._payee, users.buyer.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedBuyerPrice)); - await getBalancesFromSameTokenContract() + return true; + }, + 'Event LogWithdrawal was not emitted' + ); + // Deposits assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); // Cashier Should be Empty assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedBuyerDeposit = new BN(0) - const expectedSellerPrice = new BN(0) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - // 0.04 - const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) - const expectedEscrowAmountPrice = new BN(0) - - await getBalancesFromSameTokenContract() - - assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") - assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") - assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.cancel(voucherID, users.seller.address) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - const expectedSellerPrice = new BN(0) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesFromSameTokenContract() - - assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") - assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") - assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + it('COMMIT->REDEEM->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); - // Cashier Should be Empty - assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + const withdrawTx = await withdraw(utils, i, voucherID); - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + const expectedEscrowAmountDeposit = new BN(0); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await getBalancesDepositToken(); - const withdrawTx = await withdraw(utils, i, voucherID) + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + 'Incorrect Payee' + ); + assert.isTrue(ev._payment.eq(expectedSellerPrice)); - const expectedBuyerPrice = new BN(0) - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - const expectedEscrowAmountDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) - await getBalancesFromSameTokenContract() + return true; + }, + 'Event LogWithdrawal was not emitted' + ); - assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") - assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") - assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); - // Cashier Should be Empty - assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) + ); - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); - const expectedBuyerPrice = new BN(0) // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) + const expectedBuyerDeposit = new BN(constants.buyer_deposit); // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedSellerDeposit = new BN(0) - const expectedEscrowAmountPrice = new BN(0) + const expectedSellerPrice = new BN(constants.product_price); + const expectedSellerDeposit = new BN(0); // 0.05 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit) + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ); - await getBalancesFromSameTokenContract() + await getBalancesDepositToken(); + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + 'Incorrect Payee' + ); + assert.isTrue(ev._payment.eq(expectedSellerPrice)); + + return true; + }, + 'Event LogWithdrawal was not emitted' + ); + + // Deposits assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); // Cashier Should be Empty assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + ); + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); - const expectedBuyerPrice = new BN(0) // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); // 0.3 - const expectedSellerPrice = new BN(constants.product_price) + const expectedSellerPrice = new BN(constants.product_price); // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - const expectedEscrowAmountPrice = new BN(0) + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); + + await getBalancesDepositToken(); + + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + 'Incorrect Payee' + ); + assert.isTrue(ev._payment.eq(expectedSellerPrice)); - await getBalancesFromSameTokenContract() + return true; + }, + 'Event LogWithdrawal was not emitted' + ); + // Deposits assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); // Cashier Should be Empty assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - await utils.redeem(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + it('COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await utils.redeem(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); - const withdrawTx = await withdraw(utils, i, voucherID) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const expectedBuyerPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.3 - const expectedSellerPrice = - new BN(constants.product_price) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountPrice = new BN(0) - const expectedEscrowAmountDeposit = new BN(0) + const withdrawTx = await withdraw(utils, i, voucherID); - await getBalancesFromSameTokenContract() + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); - assert.isTrue( - balanceBuyer.eq(expectedBuyerPrice.add(expectedBuyerDeposit)), - "Buyer did not get expected tokens from SameTokenContract") - assert.isTrue( - balanceSeller.eq(expectedSellerPrice.add(expectedSellerDeposit)), - "Seller did not get expected tokens from SameTokenContract") - assert.isTrue( - escrowBalance.eq( - expectedEscrowAmountPrice - .add(expectedEscrowAmountDeposit)), - "Escrow did not get expected tokens from SameTokenContract") + await getBalancesDepositToken(); - // Cashier Should be Empty - assert.isTrue( - cashierBalance.eq(new BN(0)), - "Cashier Contract is not empty") + // Payment should have been sent to seller + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + assert.equal( + ev._payee, + users.seller.address, + 'Incorrect Payee' + ); + assert.isTrue(ev._payment.eq(expectedSellerPrice)); - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") + return true; + }, + 'Event LogWithdrawal was not emitted' + ); - }) + // Deposits + assert.isTrue( + balanceBuyerFromDeposits.eq(expectedBuyerDeposit), + 'Buyer did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + balanceSellerFromDeposits.eq(expectedSellerDeposit), + 'Seller did not get expected tokens from DepositTokenContract' + ); + assert.isTrue( + escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), + 'Escrow did not get expected tokens from DepositTokenContract' + ); - }) + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); - describe("ETH - TKN [WITH PERMIT]" + - `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { - let balanceBuyerFromPayment = new BN(0) - let balanceBuyerFromDeposits = new BN(0) + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); + } + ); - let balanceSellerFromPayment = new BN(0) - let balanceSellerFromDeposits = new BN(0) + describe( + 'TKN - ETH [WITH PERMIT]' + + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, + async () => { + let balanceBuyerFromPayment = new BN(0); + let balanceSellerFromPayment = new BN(0); + let escrowBalanceFromPayment = new BN(0); + + let cashierPaymentLeft = new BN(0); + let cashierDepositLeft = new BN(0); + + async function getBalancesPriceToken() { + balanceBuyerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.buyer.address + ); + balanceSellerFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.seller.address + ); + escrowBalanceFromPayment = await utils.contractBSNTokenPrice.balanceOf( + users.deployer.address + ); + cashierPaymentLeft = await utils.contractBSNTokenPrice.balanceOf( + utils.contractCashier.address + ); + } - let escrowBalanceFromPayment = new BN(0) - let escrowBalanceFromDeposits = new BN(0) + beforeEach(async () => { + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKNETH() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + '' + ); - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) + const timestamp = await Utils.getCurrTimestamp(); - async function getBalancesDepositToken () { - balanceBuyerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.buyer.address) - balanceSellerFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.seller.address) - escrowBalanceFromDeposits = await utils.contractBSNTokenDeposit - .balanceOf(users.deployer.address) - cashierDepositLeft = await utils.contractBSNTokenDeposit - .balanceOf(utils.contractCashier.address) - } + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + constants.product_price + ); - beforeEach(async () => { - utils = UtilsBuilder.create() - .ERC20withPermit() - .ETHTKN() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - contractBSNTokenDeposit) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); + }); - const timestamp = await Utils.getCurrTimestamp() + it('COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - const supplyQty = 1 - const tokensToMint = - new BN(constants.seller_deposit).mul(new BN(supplyQty)) + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); + await utils.finalize(voucherID, users.deployer.address); - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.seller.address, - tokensToMint) - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.buyer.address, - constants.buyer_deposit) + const withdrawTx = await withdraw(utils, i, voucherID); - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - supplyQty - ) - }) - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) - } + // 0.3 + const expectedBuyerPrice = new BN(constants.product_price); + const expectedSellerPrice = new BN(0); + const expectedEscrowPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); - balanceBuyerFromPayment = new BN(0) - balanceBuyerFromDeposits = new BN(0) + await getBalancesPriceToken(); - balanceSellerFromPayment = new BN(0) - balanceSellerFromDeposits = new BN(0) + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); - escrowBalanceFromPayment = new BN(0) - escrowBalanceFromDeposits = new BN(0) + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); - await giveAwayToRandom() + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); - const isPaused = await contractCashier.paused() - if (isPaused) { - await contractCashier.unpause() - } - }) + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) + const expectedBuyerPrice = new BN(constants.product_price); + const expectedSellerPrice = new BN(0); + const expectedEscrowPrice = new BN(0); + const expectedBuyerDeposit = new BN(0); + const expectedSellerDeposit = new BN(0); + // 0.09 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).add(new BN(constants.buyer_deposit)); - await getBalancesDepositToken() + await getBalancesPriceToken(); + // Payments in TKN // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); + + // Deposits in ETH truffleAssert.eventEmitted( withdrawTx, 'LogWithdrawal', (ev) => { - assert.equal( - ev._payee, + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', users.buyer.address, - "Incorrect Payee") - assert.isTrue( - ev._payment.eq(expectedBuyerPrice)) + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - return true - }, "Event LogAmountDistribution was not emitted") - - // Deposits assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from " + - "DepositTokenContract") + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from " + - "DepositTokenContract") + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from " + - "DepositTokenContract") + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) + ); + + await utils.refund(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) + await timemachine.advanceTimeSeconds(60); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedBuyerDeposit = new BN(0) - const expectedSellerDeposit = new BN(0) - // 0.09 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit) - .add(new BN(constants.buyer_deposit)) + const expectedBuyerPrice = new BN(constants.product_price); + const expectedSellerPrice = new BN(0); + const expectedEscrowPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); - await getBalancesDepositToken() + await getBalancesPriceToken(); + // Payments in TKN // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); + + // Deposits in ETH truffleAssert.eventEmitted( withdrawTx, 'LogWithdrawal', (ev) => { - assert.equal( - ev._payee, + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', users.buyer.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - // Deposits assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesDepositToken() - - // Payment should have been returned to buyer - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.buyer.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from " + - "DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from " + - "DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from " + - "DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedBuyerDeposit = new BN(0) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - // 0.04 - const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) - - await getBalancesDepositToken() - - // Payment should have been returned to buyer - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.buyer.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesDepositToken() - - // Payment should have been returned to buyer - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.buyer.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedBuyerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesDepositToken() - - // Payment should have been sent to seller - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.seller.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedSellerDeposit = new BN(0) - // 0.05 - const expectedEscrowAmountDeposit = new BN(constants.seller_deposit) - - await getBalancesDepositToken() - - // Payment should have been sent to seller - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.seller.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") - - // Deposits - assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") - assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") - assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REFUND->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) + const expectedBuyerPrice = new BN(constants.product_price); + const expectedSellerPrice = new BN(0); + const expectedEscrowPrice = new BN(0); + const expectedBuyerDeposit = new BN(0); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + // 0.04 + const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit); - await getBalancesDepositToken() + await getBalancesPriceToken(); - // Payment should have been sent to seller + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); + + // Deposits in ETH truffleAssert.eventEmitted( withdrawTx, 'LogWithdrawal', (ev) => { - assert.equal( - ev._payee, - users.seller.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - // Deposits assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->CANCEL->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) + ); - await utils.redeem(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + await utils.cancel(voucherID, users.seller.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - // 0.025 - const expectedSellerDeposit = + const expectedBuyerPrice = new BN(constants.product_price); + const expectedSellerPrice = new BN(0); + const expectedEscrowPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) + ); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); - await getBalancesDepositToken() + await getBalancesPriceToken(); - // Payment should have been sent to seller + // Payments in TKN + // Payment should have been returned to buyer + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); + + // Deposits in ETH truffleAssert.eventEmitted( withdrawTx, 'LogWithdrawal', (ev) => { - assert.equal( - ev._payee, - users.seller.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerPrice)) - - return true - }, "Event LogWithdrawal was not emitted") + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - // Deposits assert.isTrue( - balanceBuyerFromDeposits.eq(expectedBuyerDeposit), - "Buyer did not get expected tokens from DepositTokenContract") + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); assert.isTrue( - balanceSellerFromDeposits.eq(expectedSellerDeposit), - "Seller did not get expected tokens from DepositTokenContract") + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); assert.isTrue( - escrowBalanceFromDeposits.eq(expectedEscrowAmountDeposit), - "Escrow did not get expected tokens from DepositTokenContract") + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - }) - - describe("TKN - ETH [WITH PERMIT]" + - `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { - let balanceBuyerFromPayment = new BN(0) - let balanceSellerFromPayment = new BN(0) - let escrowBalanceFromPayment = new BN(0) - - let cashierPaymentLeft = new BN(0) - let cashierDepositLeft = new BN(0) - - async function getBalancesPriceToken () { - balanceBuyerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.buyer.address) - balanceSellerFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.seller.address) - escrowBalanceFromPayment = await utils.contractBSNTokenPrice - .balanceOf(users.deployer.address) - cashierPaymentLeft = await utils.contractBSNTokenPrice - .balanceOf(utils.contractCashier.address) - } - - beforeEach(async () => { - utils = UtilsBuilder.create() - .ERC20withPermit() - .TKNETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - '') - - const timestamp = await Utils.getCurrTimestamp() - - await utils.mintTokens( - 'contractBSNTokenPrice', - users.buyer.address, - constants.product_price) - - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1 - ) - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REFUND->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REDEEM->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) + ); + await utils.redeem(voucherID, users.buyer.address); - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); + const expectedBuyerPrice = new BN(0); // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) + const expectedSellerPrice = new BN(constants.product_price); + const expectedEscrowPrice = new BN(0); + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + // 0.05 + const expectedSellerDeposit = new BN(constants.seller_deposit); + const expectedEscrowAmountDeposit = new BN(0); - await getBalancesPriceToken() + await getBalancesPriceToken(); // Payments in TKN - // Payment should have been returned to buyer + // Payment should have been sent to seller assert.isTrue( balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") + 'Buyer did not get expected tokens from PaymentTokenContract' + ); assert.isTrue( balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") + 'Seller did not get expected tokens from PaymentTokenContract' + ); assert.isTrue( escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") + 'Escrow did not get expected tokens from PaymentTokenContract' + ); // Deposits in ETH truffleAssert.eventEmitted( @@ -2679,76 +3504,89 @@ contract("Cashier withdrawals ", async addresses => { distributedAmounts, '_payee', users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); assert.isTrue( distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') + 'Buyer Amount is not as expected' + ); assert.isTrue( distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') + 'Seller Amount is not as expected' + ); assert.isTrue( distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') + 'Escrow Amount is not as expected' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REFUND->COMPLAIN->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) + ); - await utils.refund(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); + const expectedBuyerPrice = new BN(0); // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(0) - const expectedSellerDeposit = new BN(0) - // 0.09 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit) - .add(new BN(constants.buyer_deposit)) + const expectedSellerPrice = new BN(constants.product_price); + const expectedEscrowPrice = new BN(0); + // 0.04 + const expectedBuyerDeposit = new BN(constants.buyer_deposit); + const expectedSellerDeposit = new BN(0); + // 0.05 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ); - await getBalancesPriceToken() + await getBalancesPriceToken(); // Payments in TKN - // Payment should have been returned to buyer + // Payment should have been sent to seller assert.isTrue( balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") + 'Buyer did not get expected tokens from PaymentTokenContract' + ); assert.isTrue( balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") + 'Seller did not get expected tokens from PaymentTokenContract' + ); assert.isTrue( escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") + 'Escrow did not get expected tokens from PaymentTokenContract' + ); // Deposits in ETH truffleAssert.eventEmitted( @@ -2760,479 +3598,189 @@ contract("Cashier withdrawals ", async addresses => { distributedAmounts, '_payee', users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); assert.isTrue( distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') + 'Buyer Amount is not as expected' + ); assert.isTrue( distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') + 'Seller Amount is not as expected' + ); assert.isTrue( distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') + 'Escrow Amount is not as expected' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("COMMIT->REFUND->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.refund(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesPriceToken() - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") - - // Deposits in ETH - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - - }) - - it("COMMIT->REFUND->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - await utils.refund(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - const expectedBuyerDeposit = new BN(0) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - // 0.04 - const expectedEscrowAmountDeposit = new BN(constants.buyer_deposit) - - await getBalancesPriceToken() - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") - - // Deposits in ETH - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.cancel(voucherID, users.seller.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - // 0.3 - const expectedBuyerPrice = new BN(constants.product_price) - const expectedSellerPrice = new BN(0) - const expectedEscrowPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesPriceToken() - - // Payments in TKN - // Payment should have been returned to buyer - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") - - // Deposits in ETH - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) - - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) - - const withdrawTx = await withdraw(utils, i, voucherID) - - const expectedBuyerPrice = new BN(0) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedEscrowPrice = new BN(0) - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - // 0.05 - const expectedSellerDeposit = new BN(constants.seller_deposit) - const expectedEscrowAmountDeposit = new BN(0) - - await getBalancesPriceToken() - - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") - - // Deposits in ETH - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") - - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') - - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") - - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - it("COMMIT->REDEEM->COMPLAIN->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) - - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) + it('COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW', async () => { + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(voucherID, users.buyer.address); + await utils.complain(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const withdrawTx = await withdraw(utils, i, voucherID) + const withdrawTx = await withdraw(utils, i, voucherID); - const expectedBuyerPrice = new BN(0) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedEscrowPrice = new BN(0) - // 0.04 - const expectedBuyerDeposit = new BN(constants.buyer_deposit) - const expectedSellerDeposit = new BN(0) - // 0.05 - const expectedEscrowAmountDeposit = new BN(constants.seller_deposit) + const expectedBuyerPrice = new BN(0); + // 0.3 + const expectedSellerPrice = new BN(constants.product_price); + const expectedEscrowPrice = new BN(0); + // 0.065 + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.0125 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(4) + ); + // 0.0125 + const expectedEscrowAmountDeposit = new BN( + constants.seller_deposit + ).div(new BN(4)); - await getBalancesPriceToken() + await getBalancesPriceToken(); - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") + // Payments in TKN + // Payment should have been sent to seller + assert.isTrue( + balanceBuyerFromPayment.eq(expectedBuyerPrice), + 'Buyer did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + balanceSellerFromPayment.eq(expectedSellerPrice), + 'Seller did not get expected tokens from PaymentTokenContract' + ); + assert.isTrue( + escrowBalanceFromPayment.eq(expectedEscrowPrice), + 'Escrow did not get expected tokens from PaymentTokenContract' + ); - // Deposits in ETH - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + // Deposits in ETH + truffleAssert.eventEmitted( + withdrawTx, + 'LogWithdrawal', + (ev) => { + utils.calcTotalAmountToRecipients( + ev, + distributedAmounts, + '_payee', + users.buyer.address, + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') + assert.isTrue( + distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), + 'Buyer Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.sellerAmount.eq(expectedSellerDeposit), + 'Seller Amount is not as expected' + ); + assert.isTrue( + distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), + 'Escrow Amount is not as expected' + ); - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") - assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + // Cashier Should be Empty + assert.isTrue( + cashierPaymentLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); + assert.isTrue( + cashierDepositLeft.eq(new BN(0)), + 'Cashier Contract is not empty' + ); - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + truffleAssert.eventEmitted( + withdrawTx, + 'LogAmountDistribution', + (ev) => { + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REDEEM->COMPLAIN->CANCEL->FINALIZE->WITHDRAW", - async () => { + it('COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW', async () => { const voucherID = await utils.commitToBuy( users.buyer, users.seller, TOKEN_SUPPLY_ID - ) - await utils.redeem(voucherID, users.buyer.address) - await utils.complain(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + ); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await utils.redeem(voucherID, users.buyer.address); + await utils.cancel(voucherID, users.seller.address); - const withdrawTx = await withdraw(utils, i, voucherID) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - const expectedBuyerPrice = new BN(0) + const withdrawTx = await withdraw(utils, i, voucherID); + + const expectedBuyerPrice = new BN(0); // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedEscrowPrice = new BN(0) + const expectedSellerPrice = new BN(constants.product_price); + const expectedEscrowPrice = new BN(0); // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.0125 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - // 0.0125 - const expectedEscrowAmountDeposit = - new BN(constants.seller_deposit).div(new BN(4)) - - await getBalancesPriceToken() + const expectedBuyerDeposit = new BN(constants.buyer_deposit).add( + new BN(constants.seller_deposit).div(new BN(2)) + ); + // 0.025 + const expectedSellerDeposit = new BN(constants.seller_deposit).div( + new BN(2) + ); + const expectedEscrowAmountDeposit = new BN(0); + await getBalancesPriceToken(); // Payments in TKN // Payment should have been sent to seller assert.isTrue( balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") + 'Buyer did not get expected tokens from PaymentTokenContract' + ); assert.isTrue( balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") + 'Seller did not get expected tokens from PaymentTokenContract' + ); assert.isTrue( escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") + 'Escrow did not get expected tokens from PaymentTokenContract' + ); // Deposits in ETH truffleAssert.eventEmitted( @@ -3240,220 +3788,472 @@ contract("Cashier withdrawals ", async addresses => { 'LogWithdrawal', (ev) => { utils.calcTotalAmountToRecipients( - ev, distributedAmounts, + ev, + distributedAmounts, '_payee', users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + users.seller.address + ); + return true; + }, + 'Amounts not distributed successfully' + ); assert.isTrue( distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') + 'Buyer Amount is not as expected' + ); assert.isTrue( distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') + 'Seller Amount is not as expected' + ); assert.isTrue( distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') + 'Escrow Amount is not as expected' + ); // Cashier Should be Empty assert.isTrue( cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); assert.isTrue( cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + 'Cashier Contract is not empty' + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) + return true; + }, + 'Event LogAmountDistribution was not emitted' + ); + }); - it("COMMIT->REDEEM->CANCEL->FINALIZE->WITHDRAW", async () => { - const voucherID = await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID - ) + afterEach(async () => { + distributedAmounts = { + buyerAmount: new BN(0), + sellerAmount: new BN(0), + escrowAmount: new BN(0), + }; - await utils.redeem(voucherID, users.buyer.address) - await utils.cancel(voucherID, users.seller.address) + balanceBuyerFromPayment = new BN(0); + balanceSellerFromPayment = new BN(0); + escrowBalanceFromPayment = new BN(0); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + cashierPaymentLeft = new BN(0); + cashierDepositLeft = new BN(0); - const withdrawTx = await withdraw(utils, i, voucherID) + await giveAwayToRandom(); + }); + } + ); + }); + } - const expectedBuyerPrice = new BN(0) - // 0.3 - const expectedSellerPrice = new BN(constants.product_price) - const expectedEscrowPrice = new BN(0) - // 0.065 - const expectedBuyerDeposit = - new BN(constants.buyer_deposit) - .add(new BN(constants.seller_deposit).div(new BN(2))) - // 0.025 - const expectedSellerDeposit = - new BN(constants.seller_deposit).div(new BN(2)) - const expectedEscrowAmountDeposit = new BN(0) + describe('[WHEN PAUSED] Seller withdraws deposit locked in escrow', async () => { + let remQty = 10; + let voucherToBuyBeforeBurn = 5; + let tokensToMintSeller, tokensToMintBuyer; - await getBalancesPriceToken() - // Payments in TKN - // Payment should have been sent to seller - assert.isTrue( - balanceBuyerFromPayment.eq(expectedBuyerPrice), - "Buyer did not get expected tokens from PaymentTokenContract") - assert.isTrue( - balanceSellerFromPayment.eq(expectedSellerPrice), - "Seller did not get expected tokens from PaymentTokenContract") - assert.isTrue( - escrowBalanceFromPayment.eq(expectedEscrowPrice), - "Escrow did not get expected tokens from PaymentTokenContract") + describe('ETH ETH', () => { + before(async () => { + await deployContracts(); + + utils = UtilsBuilder.create() + .ETHETH() + .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); + + const timestamp = await Utils.getCurrTimestamp(); + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ); + }); + + after(() => { + remQty = 10; + voucherToBuyBeforeBurn = 5; + }); + + it('[NEGATIVE] Should revert if called when contract is not paused', async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + + it('Should pause the contract', async () => { + // Does nothing in particular .. + // Buys 5 vouchers before pausing the contract so as to test if the + // locked seller deposit should be returned correctly + // Pauses contract as below tests are dependant to paused contract + + for (let i = 0; i < voucherToBuyBeforeBurn; i++) { + await utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID); + remQty--; + } + + await contractCashier.pause(); + }); + + it('[NEGATIVE] should revert if not called from the seller', async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.attacker.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + + it( + 'Seller should be able to withdraw deposits for the ' + + 'remaining QTY in Token Supply', + async () => { + let withdrawTx = await contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, + { + from: users.seller.address, + } + ); + + const expectedSellerDeposit = new BN(constants.seller_deposit).mul( + new BN(remQty) + ); - // Deposits in ETH truffleAssert.eventEmitted( withdrawTx, 'LogWithdrawal', (ev) => { - utils.calcTotalAmountToRecipients( - ev, - distributedAmounts, - '_payee', - users.buyer.address, - users.seller.address) - return true - }, "Amounts not distributed successfully") + assert.equal(ev._payee, users.seller.address, 'Incorrect Payee'); + assert.isTrue(ev._payment.eq(expectedSellerDeposit)); - assert.isTrue( - distributedAmounts.buyerAmount.eq(expectedBuyerDeposit), - 'Buyer Amount is not as expected') - assert.isTrue( - distributedAmounts.sellerAmount.eq(expectedSellerDeposit), - 'Seller Amount is not as expected') - assert.isTrue( - distributedAmounts.escrowAmount.eq(expectedEscrowAmountDeposit), - 'Escrow Amount is not as expected') + return true; + }, + 'Event LogWithdrawal was not emitted' + ); + } + ); + + it( + 'Escrow should have correct balance after burning the ' + + 'rest of the supply', + async () => { + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(voucherToBuyBeforeBurn) + ); + const escrowAmount = await contractCashier.getEscrowAmount( + users.seller.address + ); - // Cashier Should be Empty - assert.isTrue( - cashierPaymentLeft.eq(new BN(0)), - "Cashier Contract is not empty") assert.isTrue( - cashierDepositLeft.eq(new BN(0)), - "Cashier Contract is not empty") + escrowAmount.eq(expectedBalance), + 'Escrow amount is incorrect' + ); + } + ); + + it('Remaining QTY for Token Supply should be ZERO', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + TOKEN_SUPPLY_ID, + users.seller.address + ); + + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + 'Escrow amount is incorrect' + ); + }); + + it( + '[NEGATIVE] Buyer should not be able to commit to buy ' + + 'anything from the burnt supply', + async () => { + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ); + } + ); - truffleAssert.eventEmitted( - withdrawTx, - 'LogAmountDistribution', - (ev) => { - return true - }, "Event LogAmountDistribution was not emitted") - }) - - afterEach(async () => { - distributedAmounts = { - buyerAmount: new BN(0), - sellerAmount: new BN(0), - escrowAmount: new BN(0) + it( + '[NEGATIVE] Seller should not be able withdraw its deposit ' + + 'for the Token Supply twice', + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), + truffleAssert.ErrorType.REVERT + ); + } + ); + }); + + describe('[WITH PERMIT]', () => { + describe('ETHTKN', () => { + before(async () => { + await deployContracts(); + utils = UtilsBuilder.create() + .ERC20withPermit() + .ETHTKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit + ); + + const timestamp = await Utils.getCurrTimestamp(); + + tokensToMintSeller = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_10) + ); + tokensToMintBuyer = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); + + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMintSeller + ); + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMintBuyer + ); + + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ); + }); + + after(() => { + remQty = 10; + voucherToBuyBeforeBurn = 5; + }); + + it('[NEGATIVE] Should revert if called when contract is not paused', async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + + it('Should pause the contract', async () => { + // Does nothing in particular .. + // Buys 5 vouchers before pausing the contract so as to test if + // the locked seller deposit should be returned correctly + // Pauses contract as below tests are dependant to paused contract + + for (let i = 0; i < voucherToBuyBeforeBurn; i++) { + await utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID); + remQty--; } - balanceBuyerFromPayment = new BN(0) - balanceSellerFromPayment = new BN(0) - escrowBalanceFromPayment = new BN(0) + await contractCashier.pause(); + }); + + it('[NEGATIVE] should revert if not called from the seller', async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.attacker.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + + it( + 'Seller should be able to withdraw deposits for the ' + + 'remaining QTY in Token Supply', + async () => { + let withdrawTx = await contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, + { + from: users.seller.address, + } + ); + const expectedSellerDeposit = new BN(constants.seller_deposit).mul( + new BN(remQty) + ); + const internalTx = await truffleAssert.createTransactionResult( + contractBSNTokenDeposit, + withdrawTx.tx + ); + + truffleAssert.eventEmitted( + internalTx, + 'Transfer', + (ev) => { + assert.equal(ev.to, users.seller.address, 'Incorrect Payee'); + assert.isTrue(ev.value.eq(expectedSellerDeposit)); - cashierPaymentLeft = new BN(0) - cashierDepositLeft = new BN(0) + return true; + }, + 'Event Transfer was not emitted' + ); + } + ); - await giveAwayToRandom() - }) - }) + it( + 'Escrow should have correct balance after burning the ' + + 'rest of the supply', + async () => { + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(voucherToBuyBeforeBurn) + ); + const escrowAmount = await contractBSNTokenDeposit.balanceOf( + users.seller.address + ); - }) - } + assert.isTrue( + escrowAmount.eq(expectedBalance), + 'Escrow amount is incorrect' + ); + } + ); - describe("[WHEN PAUSED] Seller withdraws deposit locked in escrow", - async () => { - let remQty = 10 - let voucherToBuyBeforeBurn = 5 - let tokensToMintSeller, tokensToMintBuyer + it('Remaining QTY for Token Supply should be ZERO', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + TOKEN_SUPPLY_ID, + users.seller.address + ); - describe("ETH ETH", () => { - before(async () => { - await deployContracts() + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + 'Escrow amount is incorrect' + ); + }); + + it( + '[NEGATIVE] Buyer should not be able to commit to buy ' + + 'anything from the burnt supply', + async () => { + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ); + } + ); + + it( + '[NEGATIVE] Seller should not be able withdraw its ' + + 'deposit for the Token Supply twice', + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), + truffleAssert.ErrorType.REVERT + ); + } + ); + }); + describe('TKNETH', () => { + before(async () => { + await deployContracts(); utils = UtilsBuilder.create() - .ETHETH() + .ERC20withPermit() + .TKNETH() .build( contractERC1155ERC721, contractVoucherKernel, - contractCashier) + contractCashier, + contractBSNTokenPrice, + '' + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); + + tokensToMintBuyer = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); + + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMintBuyer + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_10) - }) + constants.QTY_10 + ); + }); after(() => { - remQty = 10 - voucherToBuyBeforeBurn = 5 - }) + remQty = 10; + voucherToBuyBeforeBurn = 5; + }); - it("[NEGATIVE] Should revert if called when contract is not paused", + it( + '[NEGATIVE] Should revert if called when contract is ' + 'not paused', async () => { await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("Should pause the contract", async () => { + it('Should pause the contract', async () => { // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if the - // locked seller deposit should be returned correctly + // Buys 5 vouchers before pausing the contract so as to test if + // the locked seller deposit should be returned correctly // Pauses contract as below tests are dependant to paused contract for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - remQty-- + await utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID); + remQty--; } - await contractCashier.pause() - }) - - it("[NEGATIVE] should revert if not called from the seller", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Seller should be able to withdraw deposits for the " + - "remaining QTY in Token Supply", + await contractCashier.pause(); + }); + + it('[NEGATIVE] should revert if not called from the seller', async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.attacker.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + + it( + 'Seller should be able to withdraw deposits for the ' + + 'remaining QTY in Token Supply', async () => { - let withdrawTx = await contractCashier - .withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }) - - const expectedSellerDeposit = - new BN(constants.seller_deposit).mul(new BN(remQty)) + let withdrawTx = await contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, + { + from: users.seller.address, + } + ); + const expectedSellerDeposit = new BN(constants.seller_deposit).mul( + new BN(remQty) + ); truffleAssert.eventEmitted( withdrawTx, @@ -3462,525 +4262,246 @@ contract("Cashier withdrawals ", async addresses => { assert.equal( ev._payee, users.seller.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerDeposit)) - - return true - }, "Event LogWithdrawal was not emitted") - }) + 'Incorrect Payee' + ); + assert.isTrue(ev._payment.eq(expectedSellerDeposit)); + + return true; + }, + 'Event LogWithdrawal was not emitted' + ); + } + ); - it("Escrow should have correct balance after burning the " + - "rest of the supply", + it( + 'Escrow should have correct balance after burning the ' + + 'rest of the supply', async () => { - const expectedBalance = - new BN(constants.seller_deposit) - .mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractCashier - .getEscrowAmount(users.seller.address) + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(voucherToBuyBeforeBurn) + ); + const escrowAmount = await contractCashier.getEscrowAmount( + users.seller.address + ); assert.isTrue( escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) - - it("Remaining QTY for Token Supply should be ZERO", - async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) + 'Escrow amount is incorrect' + ); + } + ); - assert.isTrue( - remainingQtyInContract.eq(new BN(0)), - "Escrow amount is incorrect") - }) + it('Remaining QTY for Token Supply should be ZERO', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + TOKEN_SUPPLY_ID, + users.seller.address + ); - it("[NEGATIVE] Buyer should not be able to commit to buy " + - "anything from the burnt supply", + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + 'Escrow amount is incorrect' + ); + }); + + it( + '[NEGATIVE] Buyer should not be able to commit to buy ' + + 'anything from the burnt supply', async () => { await truffleAssert.reverts( utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] Seller should not be able withdraw its deposit " + - "for the Token Supply twice", + it( + '[NEGATIVE] Seller should not be able withdraw its ' + + 'deposit for the Token Supply twice', async () => { await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("[WITH PERMIT]", () => { - describe("ETHTKN", () => { - before(async () => { - await deployContracts() - utils = UtilsBuilder.create() - .ERC20withPermit() - .ETHTKN() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - contractBSNTokenDeposit) + ); + } + ); + }); - const timestamp = await Utils.getCurrTimestamp() + describe('TKNTKN', () => { + before(async () => { + await deployContracts(); + utils = UtilsBuilder.create() + .ERC20withPermit() + .TKNTKN() + .build( + contractERC1155ERC721, + contractVoucherKernel, + contractCashier, + contractBSNTokenPrice, + contractBSNTokenDeposit + ); - tokensToMintSeller = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_10)) - tokensToMintBuyer = - new BN(constants.product_price).mul(new BN(constants.QTY_10)) + const timestamp = await Utils.getCurrTimestamp(); - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.seller.address, - tokensToMintSeller) - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.buyer.address, - tokensToMintBuyer) + tokensToMintSeller = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_10) + ); + tokensToMintBuyer = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_10) - }) - - after(() => { - remQty = 10 - voucherToBuyBeforeBurn = 5 - }) - - it("[NEGATIVE] Should revert if called when contract is not paused", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should pause the contract", async () => { - // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if - // the locked seller deposit should be returned correctly - // Pauses contract as below tests are dependant to paused contract - - for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID) - remQty-- - } + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.seller.address, + tokensToMintSeller + ); + await utils.mintTokens( + 'contractBSNTokenPrice', + users.buyer.address, + tokensToMintBuyer + ); + await utils.mintTokens( + 'contractBSNTokenDeposit', + users.buyer.address, + tokensToMintBuyer + ); - await contractCashier.pause() - }) - - it("[NEGATIVE] should revert if not called from the seller", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Seller should be able to withdraw deposits for the " + - "remaining QTY in Token Supply", - async () => { - let withdrawTx = await contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }) - const expectedSellerDeposit = - new BN(constants.seller_deposit).mul(new BN(remQty)) - const internalTx = await truffleAssert - .createTransactionResult( - contractBSNTokenDeposit, - withdrawTx.tx) - - truffleAssert.eventEmitted( - internalTx, - 'Transfer', - (ev) => { - assert.equal( - ev.to, users.seller.address, "Incorrect Payee") - assert.isTrue(ev.value.eq(expectedSellerDeposit)) - - return true - }, "Event Transfer was not emitted") - }) - - it("Escrow should have correct balance after burning the " + - "rest of the supply", - async () => { - const expectedBalance = - new BN(constants.seller_deposit) - .mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractBSNTokenDeposit - .balanceOf(users.seller.address) - - assert.isTrue( - escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) - - it("Remaining QTY for Token Supply should be ZERO", - async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) - - assert.isTrue( - remainingQtyInContract.eq(new BN(0)), - "Escrow amount is incorrect") - }) - - it("[NEGATIVE] Buyer should not be able to commit to buy " + - "anything from the burnt supply", - async () => { - await truffleAssert.reverts( - utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Seller should not be able withdraw its " + - "deposit for the Token Supply twice", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKNETH", () => { - before(async () => { - await deployContracts() - utils = UtilsBuilder.create() - .ERC20withPermit() - .TKNETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - '') + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ); + }); - const timestamp = await Utils.getCurrTimestamp() + after(() => { + remQty = 10; + voucherToBuyBeforeBurn = 5; + }); - tokensToMintBuyer = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + it( + '[NEGATIVE] Should revert if called when contract ' + 'is not paused', + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), + truffleAssert.ErrorType.REVERT + ); + } + ); - await utils.mintTokens( - 'contractBSNTokenPrice', - users.buyer.address, - tokensToMintBuyer) + it('Should pause the contract', async () => { + // Does nothing in particular .. + // Buys 5 vouchers before pausing the contract so as to test if + // the locked seller deposit should be returned correctly + // Pauses contract as below tests are dependant to paused contract - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_10 - ) - }) - - after(() => { - remQty = 10 - voucherToBuyBeforeBurn = 5 - }) - - it("[NEGATIVE] Should revert if called when contract is " + - "not paused", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should pause the contract", async () => { - // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if - // the locked seller deposit should be returned correctly - // Pauses contract as below tests are dependant to paused contract - - for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID) - remQty-- - } + for (let i = 0; i < voucherToBuyBeforeBurn; i++) { + await utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID); + remQty--; + } - await contractCashier.pause() - }) - - it("[NEGATIVE] should revert if not called from the seller", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Seller should be able to withdraw deposits for the " + - "remaining QTY in Token Supply", - async () => { - let withdrawTx = await contractCashier - .withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }) - const expectedSellerDeposit = - new BN(constants.seller_deposit).mul(new BN(remQty)) - - truffleAssert.eventEmitted( - withdrawTx, - 'LogWithdrawal', - (ev) => { - assert.equal( - ev._payee, - users.seller.address, - "Incorrect Payee") - assert.isTrue(ev._payment.eq(expectedSellerDeposit)) - - return true - }, "Event LogWithdrawal was not emitted") - }) - - it("Escrow should have correct balance after burning the " + - "rest of the supply", - async () => { - const expectedBalance = - new BN(constants.seller_deposit) - .mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractCashier - .getEscrowAmount(users.seller.address) - - assert.isTrue( - escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) - - it("Remaining QTY for Token Supply should be ZERO", - async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) - - assert.isTrue( - remainingQtyInContract.eq(new BN(0)), - "Escrow amount is incorrect") - }) - - it("[NEGATIVE] Buyer should not be able to commit to buy " + - "anything from the burnt supply", - async () => { - await truffleAssert.reverts( - utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Seller should not be able withdraw its " + - "deposit for the Token Supply twice", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - }) - - describe("TKNTKN", () => { - before(async () => { - await deployContracts() - utils = UtilsBuilder.create() - .ERC20withPermit() - .TKNTKN() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier, - contractBSNTokenPrice, - contractBSNTokenDeposit) + await contractCashier.pause(); + }); + + it('[NEGATIVE] should revert if not called from the seller', async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.attacker.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + + it( + 'Seller should be able to withdraw deposits for the ' + + 'remaining QTY in Token Supply', + async () => { + let withdrawTx = await contractCashier.withdrawDeposits( + TOKEN_SUPPLY_ID, + { + from: users.seller.address, + } + ); + const expectedSellerDeposit = new BN(constants.seller_deposit).mul( + new BN(remQty) + ); + const internalTx = await truffleAssert.createTransactionResult( + contractBSNTokenDeposit, + withdrawTx.tx + ); + + truffleAssert.eventEmitted( + internalTx, + 'Transfer', + (ev) => { + assert.equal(ev.to, users.seller.address, 'Incorrect Payee'); + assert.isTrue(ev.value.eq(expectedSellerDeposit)); - const timestamp = await Utils.getCurrTimestamp() + return true; + }, + 'Event Transfer was not emitted' + ); + } + ); - tokensToMintSeller = - new BN(constants.seller_deposit).mul(new BN(constants.QTY_10)) - tokensToMintBuyer = - new BN(constants.product_price).mul(new BN(constants.QTY_10)) + it( + 'Escrow should have correct balance after burning the ' + + 'rest of the supply', + async () => { + const expectedBalance = new BN(constants.seller_deposit).mul( + new BN(voucherToBuyBeforeBurn) + ); + const escrowAmount = await contractBSNTokenDeposit.balanceOf( + users.seller.address + ); - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.seller.address, - tokensToMintSeller) - await utils.mintTokens( - 'contractBSNTokenPrice', - users.buyer.address, - tokensToMintBuyer) - await utils.mintTokens( - 'contractBSNTokenDeposit', - users.buyer.address, - tokensToMintBuyer) + assert.isTrue( + escrowAmount.eq(expectedBalance), + 'Escrow amount is incorrect' + ); + } + ); - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_10 - ) - }) - - after(() => { - remQty = 10 - voucherToBuyBeforeBurn = 5 - }) - - it("[NEGATIVE] Should revert if called when contract " + - "is not paused", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Should pause the contract", async () => { - // Does nothing in particular .. - // Buys 5 vouchers before pausing the contract so as to test if - // the locked seller deposit should be returned correctly - // Pauses contract as below tests are dependant to paused contract - - for (let i = 0; i < voucherToBuyBeforeBurn; i++) { - await utils.commitToBuy( - users.buyer, - users.seller, - TOKEN_SUPPLY_ID) - remQty-- - } + it('Remaining QTY for Token Supply should be ZERO', async () => { + let remainingQtyInContract = await contractVoucherKernel.getRemQtyForSupply( + TOKEN_SUPPLY_ID, + users.seller.address + ); + + assert.isTrue( + remainingQtyInContract.eq(new BN(0)), + 'Escrow amount is incorrect' + ); + }); + + it( + '[NEGATIVE] Buyer should not be able to commit to buy ' + + 'anything from the burnt supply', + async () => { + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ); + } + ); - await contractCashier.pause() - }) - - it("[NEGATIVE] should revert if not called from the seller", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - - it("Seller should be able to withdraw deposits for the " + - "remaining QTY in Token Supply", - async () => { - let withdrawTx = await contractCashier - .withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }) - const expectedSellerDeposit = - new BN(constants.seller_deposit).mul(new BN(remQty)) - const internalTx = await truffleAssert - .createTransactionResult( - contractBSNTokenDeposit, - withdrawTx.tx) - - truffleAssert.eventEmitted( - internalTx, - 'Transfer', - (ev) => { - assert.equal( - ev.to, - users.seller.address, - "Incorrect Payee") - assert.isTrue(ev.value.eq(expectedSellerDeposit)) - - return true - }, "Event Transfer was not emitted") - }) - - it("Escrow should have correct balance after burning the " + - "rest of the supply", - async () => { - const expectedBalance = - new BN(constants.seller_deposit) - .mul(new BN(voucherToBuyBeforeBurn)) - const escrowAmount = await contractBSNTokenDeposit - .balanceOf(users.seller.address) - - assert.isTrue( - escrowAmount.eq(expectedBalance), - "Escrow amount is incorrect") - }) - - it("Remaining QTY for Token Supply should be ZERO", - async () => { - let remainingQtyInContract = await contractVoucherKernel - .getRemQtyForSupply(TOKEN_SUPPLY_ID, users.seller.address) - - assert.isTrue( - remainingQtyInContract.eq(new BN(0)), - "Escrow amount is incorrect") - }) - - it("[NEGATIVE] Buyer should not be able to commit to buy " + - "anything from the burnt supply", - async () => { - await truffleAssert.reverts( - utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Seller should not be able withdraw its deposit " + - "for the Token Supply twice", - async () => { - await truffleAssert.reverts( - contractCashier.withdrawDeposits( - TOKEN_SUPPLY_ID, { - from: users.seller.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) -}) + it( + '[NEGATIVE] Seller should not be able withdraw its deposit ' + + 'for the Token Supply twice', + async () => { + await truffleAssert.reverts( + contractCashier.withdrawDeposits(TOKEN_SUPPLY_ID, { + from: users.seller.address, + }), + truffleAssert.ErrorType.REVERT + ); + } + ); + }); + }); + }); +}); diff --git a/test/4_Boson_Token.js b/test/4_Boson_Token.js index cb248f0e..4d008177 100644 --- a/test/4_Boson_Token.js +++ b/test/4_Boson_Token.js @@ -1,94 +1,100 @@ -const truffleAssert = require('truffle-assertions') -const ethers = require('ethers') -const { assert } = require('chai') -const { ecsign } = require('ethereumjs-util') +const truffleAssert = require('truffle-assertions'); +const ethers = require('ethers'); +const {assert} = require('chai'); +const {ecsign} = require('ethereumjs-util'); -const constants = require('../testHelpers/constants') -const Users = require('../testHelpers/users') -const { toWei, getApprovalDigest } = require('../testHelpers/permitUtils') +const constants = require('../testHelpers/constants'); +const Users = require('../testHelpers/users'); +const {toWei, getApprovalDigest} = require('../testHelpers/permitUtils'); -const BosonToken = artifacts.require("BosonTokenPrice") +const BosonToken = artifacts.require('BosonTokenPrice'); -contract('Boson token', addresses => { - const users = new Users(addresses) +contract('Boson token', (addresses) => { + const users = new Users(addresses); - let BosonTokenContract, - bosonContractAddress + let BosonTokenContract, bosonContractAddress; beforeEach(async () => { - BosonTokenContract = await BosonToken.new('BOSON TOKEN', 'BSNT') - bosonContractAddress = BosonTokenContract.address - }) + BosonTokenContract = await BosonToken.new('BOSON TOKEN', 'BSNT'); + bosonContractAddress = BosonTokenContract.address; + }); describe('Boson Token', async () => { - const ADMIN_ROLE = - ethers.utils.keccak256(ethers.utils.toUtf8Bytes("ADMIN_ROLE")) - const MINTER_ROLE = - ethers.utils.keccak256(ethers.utils.toUtf8Bytes("MINTER_ROLE")) - - it("Only Deployer Should have admin and minter rights initially ", - async () => { - const buyerIsAdmin = await BosonTokenContract - .hasRole(ADMIN_ROLE, users.buyer.address) - const buyerIsMinter = await BosonTokenContract - .hasRole(MINTER_ROLE, users.buyer.address) - const deployerIsAdmin = await BosonTokenContract - .hasRole(ADMIN_ROLE, users.deployer.address) - const deployerIsMinter = await BosonTokenContract - .hasRole(MINTER_ROLE, users.deployer.address) - - assert.isTrue(deployerIsAdmin) - assert.isTrue(deployerIsMinter) - - assert.isFalse(buyerIsAdmin) - assert.isFalse(buyerIsMinter) - }) - - it("should revert if unauthorized address tries to mint tokens ", - async () => { - await truffleAssert.reverts( - BosonTokenContract.mint( - users.seller.address, - 1000, { - from: users.attacker.address - })) - }) + const ADMIN_ROLE = ethers.utils.keccak256( + ethers.utils.toUtf8Bytes('ADMIN_ROLE') + ); + const MINTER_ROLE = ethers.utils.keccak256( + ethers.utils.toUtf8Bytes('MINTER_ROLE') + ); + + it('Only Deployer Should have admin and minter rights initially ', async () => { + const buyerIsAdmin = await BosonTokenContract.hasRole( + ADMIN_ROLE, + users.buyer.address + ); + const buyerIsMinter = await BosonTokenContract.hasRole( + MINTER_ROLE, + users.buyer.address + ); + const deployerIsAdmin = await BosonTokenContract.hasRole( + ADMIN_ROLE, + users.deployer.address + ); + const deployerIsMinter = await BosonTokenContract.hasRole( + MINTER_ROLE, + users.deployer.address + ); + + assert.isTrue(deployerIsAdmin); + assert.isTrue(deployerIsMinter); + + assert.isFalse(buyerIsAdmin); + assert.isFalse(buyerIsMinter); + }); + + it('should revert if unauthorized address tries to mint tokens ', async () => { + await truffleAssert.reverts( + BosonTokenContract.mint(users.seller.address, 1000, { + from: users.attacker.address, + }) + ); + }); - it("should grant minter role to address", - async () => { - await BosonTokenContract - .grantMinterRole(users.buyer.address) + it('should grant minter role to address', async () => { + await BosonTokenContract.grantMinterRole(users.buyer.address); - const buyerIsMinter = await BosonTokenContract - .hasRole(MINTER_ROLE, users.buyer.address) + const buyerIsMinter = await BosonTokenContract.hasRole( + MINTER_ROLE, + users.buyer.address + ); - assert.isTrue(buyerIsMinter) - }) + assert.isTrue(buyerIsMinter); + }); - it("should mint tokens after minter role is granted", async () => { - const tokensToMint = 1000 - let addressBalance = await BosonTokenContract - .balanceOf(users.other2.address) + it('should mint tokens after minter role is granted', async () => { + const tokensToMint = 1000; + let addressBalance = await BosonTokenContract.balanceOf( + users.other2.address + ); - assert.equal(addressBalance, 0, - 'address has more tokens than expected') + assert.equal(addressBalance, 0, 'address has more tokens than expected'); - await BosonTokenContract.mint(users.other2.address, 1000) + await BosonTokenContract.mint(users.other2.address, 1000); - addressBalance = await BosonTokenContract - .balanceOf(users.other2.address) + addressBalance = await BosonTokenContract.balanceOf(users.other2.address); assert.equal( addressBalance, tokensToMint, - "minted tokens do not correspond to address balance") - }) - - describe("[PERMIT]", async () => { - it("Should approve successfully", async () => { - const balanceToApprove = 1200 - const nonce = await BosonTokenContract.nonces(users.buyer.address) - const deadline = toWei(1) + 'minted tokens do not correspond to address balance' + ); + }); + + describe('[PERMIT]', async () => { + it('Should approve successfully', async () => { + const balanceToApprove = 1200; + const nonce = await BosonTokenContract.nonces(users.buyer.address); + const deadline = toWei(1); const digest = await getApprovalDigest( BosonTokenContract, users.buyer.address, @@ -96,34 +102,40 @@ contract('Boson token', addresses => { balanceToApprove, nonce, deadline - ) + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); await BosonTokenContract.permit( users.buyer.address, bosonContractAddress, balanceToApprove, deadline, - v, r, s, - { from: users.buyer.address } - ) + v, + r, + s, + {from: users.buyer.address} + ); - const tokenAllowanceFromBuyer = await BosonTokenContract - .allowance(users.buyer.address, bosonContractAddress) + const tokenAllowanceFromBuyer = await BosonTokenContract.allowance( + users.buyer.address, + bosonContractAddress + ); assert.equal( tokenAllowanceFromBuyer, balanceToApprove, - "Allowance does not equal the amount provided!") - }) - - it("should revert if incorrect nonce is provided", async () => { - const balanceToApprove = 1200 - const nonce = 7000000 - const deadline = toWei(1) + 'Allowance does not equal the amount provided!' + ); + }); + + it('should revert if incorrect nonce is provided', async () => { + const balanceToApprove = 1200; + const nonce = 7000000; + const deadline = toWei(1); const digest = await getApprovalDigest( BosonTokenContract, users.buyer.address, @@ -131,85 +143,101 @@ contract('Boson token', addresses => { balanceToApprove, nonce, deadline - ) + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - await truffleAssert.reverts(BosonTokenContract.permit( - users.buyer.address, - bosonContractAddress, - balanceToApprove, - deadline, - v, r, s, - { from: users.buyer.address } - ), truffleAssert.ErrorType.REVERT) - }) - - it("should revert if incorrect balance is provided", - async () => { - const balanceToApprove = 1200 - const incorrectBalance = 1500 - const nonce = await BosonTokenContract.nonces(users.buyer.address) - const deadline = toWei(1) - const digest = await getApprovalDigest( - BosonTokenContract, + await truffleAssert.reverts( + BosonTokenContract.permit( users.buyer.address, bosonContractAddress, balanceToApprove, - nonce, - deadline - ) + deadline, + v, + r, + s, + {from: users.buyer.address} + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('should revert if incorrect balance is provided', async () => { + const balanceToApprove = 1200; + const incorrectBalance = 1500; + const nonce = await BosonTokenContract.nonces(users.buyer.address); + const deadline = toWei(1); + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + bosonContractAddress, + balanceToApprove, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - await truffleAssert.reverts(BosonTokenContract.permit( + await truffleAssert.reverts( + BosonTokenContract.permit( users.buyer.address, bosonContractAddress, incorrectBalance, deadline, - v, r, s, - { from: users.buyer.address } - ), truffleAssert.ErrorType.REVERT) - }) - - it("should revert if incorrect recipient is provided", - async () => { - const incorrectAddress = addresses[6] - const balanceToApprove = 1200 - const nonce = await BosonTokenContract.nonces(users.buyer.address) - const deadline = toWei(1) - const digest = await getApprovalDigest( - BosonTokenContract, - users.buyer.address, - bosonContractAddress, - balanceToApprove, - nonce, - deadline - ) + v, + r, + s, + {from: users.buyer.address} + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('should revert if incorrect recipient is provided', async () => { + const incorrectAddress = addresses[6]; + const balanceToApprove = 1200; + const nonce = await BosonTokenContract.nonces(users.buyer.address); + const deadline = toWei(1); + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + bosonContractAddress, + balanceToApprove, + nonce, + deadline + ); - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - await truffleAssert.reverts(BosonTokenContract.permit( + await truffleAssert.reverts( + BosonTokenContract.permit( users.buyer.address, incorrectAddress, balanceToApprove, deadline, - v, r, s, - { from: users.buyer.address } - ), truffleAssert.ErrorType.REVERT) - }) - - it("should revert if owner is incorrect", async () => { - const incorrectSender = users.other1.address - const balanceToApprove = 1200 - const nonce = await BosonTokenContract.nonces(users.buyer.address) - const deadline = toWei(1) + v, + r, + s, + {from: users.buyer.address} + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('should revert if owner is incorrect', async () => { + const incorrectSender = users.other1.address; + const balanceToApprove = 1200; + const nonce = await BosonTokenContract.nonces(users.buyer.address); + const deadline = toWei(1); const digest = await getApprovalDigest( BosonTokenContract, users.buyer.address, @@ -217,92 +245,100 @@ contract('Boson token', addresses => { balanceToApprove, nonce, deadline - ) + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) - - await truffleAssert.reverts(BosonTokenContract.permit( - incorrectSender, - bosonContractAddress, - balanceToApprove, - deadline, - v, r, s, - { from: users.buyer.address } - ), truffleAssert.ErrorType.REVERT) - }) - - it("Should transfer tokens on behalf of the buyer", - async () => { - // Buyer has 1000 preminted tokens - const tokensToMint = 1000 - await BosonTokenContract.mint( - users.buyer.address, - tokensToMint, { - from: users.deployer.address - }) - const balanceToApprove = 200 - const tokensToSend = 200 - - const nonce = await BosonTokenContract.nonces(users.buyer.address) - const deadline = toWei(1) - const digest = await getApprovalDigest( - BosonTokenContract, - users.buyer.address, - users.deployer.address, - balanceToApprove, - nonce, - deadline - ) - - const { v, r, s } = ecsign( - Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - await BosonTokenContract.permit( - users.buyer.address, - users.deployer.address, + await truffleAssert.reverts( + BosonTokenContract.permit( + incorrectSender, + bosonContractAddress, balanceToApprove, deadline, - v, r, s, - { from: users.buyer.address } - ) + v, + r, + s, + {from: users.buyer.address} + ), + truffleAssert.ErrorType.REVERT + ); + }); + + it('Should transfer tokens on behalf of the buyer', async () => { + // Buyer has 1000 preminted tokens + const tokensToMint = 1000; + await BosonTokenContract.mint(users.buyer.address, tokensToMint, { + from: users.deployer.address, + }); + const balanceToApprove = 200; + const tokensToSend = 200; + + const nonce = await BosonTokenContract.nonces(users.buyer.address); + const deadline = toWei(1); + const digest = await getApprovalDigest( + BosonTokenContract, + users.buyer.address, + users.deployer.address, + balanceToApprove, + nonce, + deadline + ); - let sellerBalance = await BosonTokenContract - .balanceOf(users.seller.address) - assert.equal(sellerBalance.toString(), 0, - 'Seller has funds') + const {v, r, s} = ecsign( + Buffer.from(digest.slice(2), 'hex'), + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); - await BosonTokenContract.transferFrom( - users.buyer.address, - users.seller.address, - tokensToSend, { - from: users.deployer.address - }) + await BosonTokenContract.permit( + users.buyer.address, + users.deployer.address, + balanceToApprove, + deadline, + v, + r, + s, + {from: users.buyer.address} + ); + + let sellerBalance = await BosonTokenContract.balanceOf( + users.seller.address + ); + assert.equal(sellerBalance.toString(), 0, 'Seller has funds'); + + await BosonTokenContract.transferFrom( + users.buyer.address, + users.seller.address, + tokensToSend, + { + from: users.deployer.address, + } + ); - sellerBalance = await BosonTokenContract - .balanceOf(users.seller.address) + sellerBalance = await BosonTokenContract.balanceOf( + users.seller.address + ); - assert.equal( - sellerBalance.toString(), - tokensToSend, - 'Seller has different amount of tokens') - }) + assert.equal( + sellerBalance.toString(), + tokensToSend, + 'Seller has different amount of tokens' + ); + }); - it("Should revert if attacker tries to transfer", async () => { + it('Should revert if attacker tries to transfer', async () => { // Buyer has 1000 preminted tokens - const tokensToMint = 1000 - await BosonTokenContract.mint( - users.buyer.address, - tokensToMint, { - from: users.deployer.address - }) - const balanceToApprove = 200 - const tokensToSend = 200 - - const nonce = await BosonTokenContract.nonces(users.buyer.address) - const deadline = toWei(1) + const tokensToMint = 1000; + await BosonTokenContract.mint(users.buyer.address, tokensToMint, { + from: users.deployer.address, + }); + const balanceToApprove = 200; + const tokensToSend = 200; + + const nonce = await BosonTokenContract.nonces(users.buyer.address); + const deadline = toWei(1); const digest = await getApprovalDigest( BosonTokenContract, users.buyer.address, @@ -310,73 +346,80 @@ contract('Boson token', addresses => { balanceToApprove, nonce, deadline - ) + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(users.buyer.privateKey.slice(2), 'hex')) + Buffer.from(users.buyer.privateKey.slice(2), 'hex') + ); await BosonTokenContract.permit( users.buyer.address, users.deployer.address, balanceToApprove, deadline, - v, r, s, - { from: users.buyer.address } - ) + v, + r, + s, + {from: users.buyer.address} + ); await truffleAssert.reverts( BosonTokenContract.transferFrom( users.buyer.address, users.seller.address, - tokensToSend, { - from: users.attacker.address - })) - }) - }) + tokensToSend, + { + from: users.attacker.address, + } + ) + ); + }); + }); - describe("[OWNERSHIP]", async () => { - it("Deployer should be owner initially", async () => { - const owner = await BosonTokenContract.owner() + describe('[OWNERSHIP]', async () => { + it('Deployer should be owner initially', async () => { + const owner = await BosonTokenContract.owner(); - assert.equal( - owner, - users.deployer.address, - "Deployer is not an owner") - }) + assert.equal(owner, users.deployer.address, 'Deployer is not an owner'); + }); - it("Should transfer ownership", async () => { - await BosonTokenContract.transferOwnership(users.other1.address) - const newOwner = await BosonTokenContract.owner() + it('Should transfer ownership', async () => { + await BosonTokenContract.transferOwnership(users.other1.address); + const newOwner = await BosonTokenContract.owner(); assert.equal( newOwner, users.other1.address, - "ownership has not been transferred") - }) + 'ownership has not been transferred' + ); + }); - it("Should renounce ownership", async () => { - const owner = await BosonTokenContract.owner() + it('Should renounce ownership', async () => { + const owner = await BosonTokenContract.owner(); - await BosonTokenContract.renounceOwnership({ from: owner }) + await BosonTokenContract.renounceOwnership({from: owner}); - const newOwner = await BosonTokenContract.owner() + const newOwner = await BosonTokenContract.owner(); assert.equal( newOwner, constants.ZERO_ADDRESS, - "ownership has not been renounced") - }) + 'ownership has not been renounced' + ); + }); - it("[NEGATIVE] Should revert if calling a function which is " + - "allowed only from owner", + it( + '[NEGATIVE] Should revert if calling a function which is ' + + 'allowed only from owner', async () => { await truffleAssert.reverts( - BosonTokenContract.grantMinterRole( - users.buyer.address, { - from: users.attacker.address - })) - }) - }) - }) -}) + BosonTokenContract.grantMinterRole(users.buyer.address, { + from: users.attacker.address, + }) + ); + } + ); + }); + }); +}); diff --git a/test/5_pausing_contracts.js b/test/5_pausing_contracts.js index 7cf91e26..418f380b 100644 --- a/test/5_pausing_contracts.js +++ b/test/5_pausing_contracts.js @@ -1,152 +1,157 @@ -const { assert } = require('chai') -const truffleAssert = require('truffle-assertions') +const {assert} = require('chai'); +const truffleAssert = require('truffle-assertions'); -const constants = require("../testHelpers/constants") -const timemachine = require('../testHelpers/timemachine') -const Users = require('../testHelpers/users') -const UtilsBuilder = require('../testHelpers/utilsBuilder') -const Utils = require('../testHelpers/utils') +const constants = require('../testHelpers/constants'); +const timemachine = require('../testHelpers/timemachine'); +const Users = require('../testHelpers/users'); +const UtilsBuilder = require('../testHelpers/utilsBuilder'); +const Utils = require('../testHelpers/utils'); -const ERC1155ERC721 = artifacts.require("ERC1155ERC721") -const VoucherKernel = artifacts.require("VoucherKernel") -const Cashier = artifacts.require("Cashier") -const BosonTKN = artifacts.require("BosonTokenPrice") -const FundLimitsOracle = artifacts.require('FundLimitsOracle') +const ERC1155ERC721 = artifacts.require('ERC1155ERC721'); +const VoucherKernel = artifacts.require('VoucherKernel'); +const Cashier = artifacts.require('Cashier'); +const BosonTKN = artifacts.require('BosonTokenPrice'); +const FundLimitsOracle = artifacts.require('FundLimitsOracle'); -const BN = web3.utils.BN -let utils +const BN = web3.utils.BN; +let utils; -let TOKEN_SUPPLY_ID -let VOUCHER_ID +let TOKEN_SUPPLY_ID; +let VOUCHER_ID; -contract("Cashier && VK", async addresses => { - const users = new Users(addresses) +contract('Cashier && VK', async (addresses) => { + const users = new Users(addresses); - let Attacker = users.attacker + let Attacker = users.attacker; let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit, - contractFundLimitsOracle - let tokensToMint - let timestamp + contractFundLimitsOracle; + let tokensToMint; + let timestamp; - async function deployContracts () { - const sixtySeconds = 60 + async function deployContracts() { + const sixtySeconds = 60; - contractFundLimitsOracle = await FundLimitsOracle.new() - contractERC1155ERC721 = await ERC1155ERC721.new() + contractFundLimitsOracle = await FundLimitsOracle.new(); + contractERC1155ERC721 = await ERC1155ERC721.new(); contractVoucherKernel = await VoucherKernel.new( - contractERC1155ERC721.address) + contractERC1155ERC721.address + ); contractCashier = await Cashier.new( contractVoucherKernel.address, contractERC1155ERC721.address, - contractFundLimitsOracle.address) - contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC') - contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP') - - await contractERC1155ERC721 - .setApprovalForAll(contractVoucherKernel.address, 'true') - await contractERC1155ERC721 - .setVoucherKernelAddress(contractVoucherKernel.address) - await contractVoucherKernel - .setCashierAddress(contractCashier.address) - - await contractVoucherKernel.setComplainPeriod(sixtySeconds) - await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds) - - await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenPrice.address, constants.TOKEN_LIMIT) - await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenDeposit.address, constants.TOKEN_LIMIT) - await contractFundLimitsOracle - .setETHLimit(constants.ETHER_LIMIT) + contractFundLimitsOracle.address + ); + contractBSNTokenPrice = await BosonTKN.new('BosonTokenPrice', 'BPRC'); + contractBSNTokenDeposit = await BosonTKN.new('BosonTokenDeposit', 'BDEP'); + + await contractERC1155ERC721.setApprovalForAll( + contractVoucherKernel.address, + 'true' + ); + await contractERC1155ERC721.setVoucherKernelAddress( + contractVoucherKernel.address + ); + await contractVoucherKernel.setCashierAddress(contractCashier.address); + + await contractVoucherKernel.setComplainPeriod(sixtySeconds); + await contractVoucherKernel.setCancelFaultPeriod(sixtySeconds); + + await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenPrice.address, + constants.TOKEN_LIMIT + ); + await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenDeposit.address, + constants.TOKEN_LIMIT + ); + await contractFundLimitsOracle.setETHLimit(constants.ETHER_LIMIT); utils = UtilsBuilder.create() .ETHETH() - .build( - contractERC1155ERC721, - contractVoucherKernel, - contractCashier) + .build(contractERC1155ERC721, contractVoucherKernel, contractCashier); - timestamp = await Utils.getCurrTimestamp() + timestamp = await Utils.getCurrTimestamp(); } describe('Pausing Scenarios', function () { - describe("CASHIER", () => { - describe("COMMON PAUSING", () => { + describe('CASHIER', () => { + describe('COMMON PAUSING', () => { before(async () => { - await deployContracts() - }) + await deployContracts(); + }); - it("Should not be paused on deployment", async () => { - const isPaused = await contractCashier.paused() + it('Should not be paused on deployment', async () => { + const isPaused = await contractCashier.paused(); - assert.isFalse(isPaused) - }) + assert.isFalse(isPaused); + }); - it("Owner should pause the contract", async () => { - await contractCashier.pause() + it('Owner should pause the contract', async () => { + await contractCashier.pause(); - const isPaused = await contractCashier.paused() + const isPaused = await contractCashier.paused(); - assert.isTrue(isPaused) - }) + assert.isTrue(isPaused); + }); - it("Owner should unpause the contract", async () => { - await contractCashier.pause() - await contractCashier.unpause() + it('Owner should unpause the contract', async () => { + await contractCashier.pause(); + await contractCashier.unpause(); - const isPaused = await contractCashier.paused() + const isPaused = await contractCashier.paused(); - assert.isFalse(isPaused) - }) + assert.isFalse(isPaused); + }); - it("[NEGATIVE] Attacker should not be able to pause the contract", - async () => { - await truffleAssert.reverts( - contractCashier.pause({ from: Attacker.address }), - truffleAssert.ErrorType.REVERT - ) - }) + it('[NEGATIVE] Attacker should not be able to pause the contract', async () => { + await truffleAssert.reverts( + contractCashier.pause({from: Attacker.address}), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Attacker should not be able to unpause the contract", - async () => { - await contractCashier.pause() + it('[NEGATIVE] Attacker should not be able to unpause the contract', async () => { + await contractCashier.pause(); - await truffleAssert.reverts( - contractCashier.unpause({ from: Attacker.address }), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + contractCashier.unpause({from: Attacker.address}), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("ETHETH", () => { + describe('ETHETH', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, - contractCashier) + contractCashier + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_10) - }) + constants.QTY_10 + ); + }); - it("[NEGATIVE] Should not create voucher supply when " + - "contract is paused", + it( + '[NEGATIVE] Should not create voucher supply when ' + + 'contract is paused', async () => { - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.createOrder( @@ -154,223 +159,270 @@ contract("Cashier && VK", async addresses => { timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1), + constants.QTY_1 + ), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("Should create voucher supply when contract is unpaused", - async () => { - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + it('Should create voucher supply when contract is unpaused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) + assert.isNotEmpty(TOKEN_SUPPLY_ID); + }); - it("[NEGATIVE] Should not create voucherID from Buyer when paused", - async () => { - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + it('[NEGATIVE] Should not create voucherID from Buyer when paused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process withdrawals when paused", - async () => { - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + it('[NEGATIVE] Should not process withdrawals when paused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.withdraw(voucherID, users.deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("withdrawWhenPaused - Buyer should be able to withdraw " + - "funds when paused", + it( + 'withdrawWhenPaused - Buyer should be able to withdraw ' + + 'funds when paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.buyer.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.buyer.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Buyer should not be ' + + 'able to withdraw funds when not paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); const voucherID = await utils.commitToBuy( users.buyer, users.seller, - TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.buyer.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("withdrawWhenPaused - Seller should be able to withdraw " + - "funds when paused", + it( + 'withdrawWhenPaused - Seller should be able to withdraw ' + + 'funds when paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.seller.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.seller.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Seller should not be ' + + 'able to withdraw funds when not paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.seller.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + - "able to withdraw funds when paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not be ' + + 'able to withdraw funds when paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + - "able to withdraw funds when not paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not be ' + + 'able to withdraw funds when not paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + } + ); + }); - describe("[WITH PERMIT]", () => { - describe("ETHTKN", () => { + describe('[WITH PERMIT]', () => { + describe('ETHTKN', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() @@ -380,35 +432,40 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - tokensToMint = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.seller.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.buyer.address, - tokensToMint) + tokensToMint + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_10) - }) + constants.QTY_10 + ); + }); - it("[NEGATIVE] Should not create voucher supply when " + - "contract is paused", + it( + '[NEGATIVE] Should not create voucher supply when ' + + 'contract is paused', async () => { - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.createOrder( @@ -416,225 +473,273 @@ contract("Cashier && VK", async addresses => { timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1), + constants.QTY_1 + ), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("Should create voucher supply when contract is unpaused", - async () => { - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + it('Should create voucher supply when contract is unpaused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) + assert.isNotEmpty(TOKEN_SUPPLY_ID); + }); - it("[NEGATIVE] Should not create voucherID from Buyer " + - "when paused", + it( + '[NEGATIVE] Should not create voucherID from Buyer ' + + 'when paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] Should not process withdrawals when paused", - async () => { - TOKEN_SUPPLY_ID = await utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + it('[NEGATIVE] Should not process withdrawals when paused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.withdraw(voucherID, users.deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("withdrawWhenPaused - Buyer should be able to " + - "withdraw funds when paused", + it( + 'withdrawWhenPaused - Buyer should be able to ' + + 'withdraw funds when paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.buyer.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.buyer.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Buyer should not be ' + + 'able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.buyer.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("withdrawWhenPaused - Seller should be able to " + - "withdraw funds when paused", + it( + 'withdrawWhenPaused - Seller should be able to ' + + 'withdraw funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.seller.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.seller.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Seller should not be ' + + 'able to withdraw funds when not paused', async () => { TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.seller.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + - "able to withdraw funds when paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not be ' + + 'able to withdraw funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not " + - "be able to withdraw funds when not paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not ' + + 'be able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + } + ); + }); - describe("TKNETH", () => { + describe('TKNETH', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() .TKNETH() @@ -643,18 +748,20 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - '') + '' + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - tokensToMint = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenPrice', users.buyer.address, - tokensToMint) + tokensToMint + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -662,242 +769,288 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) - }) - - it("[NEGATIVE] Should not create voucher supply when " + - "contract is paused", async () => { - await contractCashier.pause() - - await truffleAssert.reverts( - utils.createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1), - truffleAssert.ErrorType.REVERT - ) - }) + ); + }); - it("Should create voucher supply when contract is unpaused", + it( + '[NEGATIVE] Should not create voucher supply when ' + + 'contract is paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( + await contractCashier.pause(); + + await truffleAssert.reverts( + utils.createOrder( users.seller, timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1) + constants.QTY_1 + ), + truffleAssert.ErrorType.REVERT + ); + } + ); + + it('Should create voucher supply when contract is unpaused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) + assert.isNotEmpty(TOKEN_SUPPLY_ID); + }); - it("[NEGATIVE] Should not create voucherID from Buyer " + - "when paused", + it( + '[NEGATIVE] Should not create voucherID from Buyer ' + + 'when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] Should not process withdrawals when paused", - async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + it('[NEGATIVE] Should not process withdrawals when paused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.withdraw(voucherID, users.deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("withdrawWhenPaused - Buyer should be able to withdraw " + - "funds when paused", + it( + 'withdrawWhenPaused - Buyer should be able to withdraw ' + + 'funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.buyer.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.buyer.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Buyer should not be ' + + 'able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.buyer.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("withdrawWhenPaused - Seller should be able to withdraw " + - "funds when paused", + it( + 'withdrawWhenPaused - Seller should be able to withdraw ' + + 'funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.seller.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.seller.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Seller should not be ' + + 'able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.seller.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + - "able to withdraw funds when paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not be ' + + 'able to withdraw funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not " + - "be able to withdraw funds when not paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not ' + + 'be able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) - }) + ); + } + ); + }); - describe("TKNTKN", () => { + describe('TKNTKN', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() .TKNTKN() @@ -906,33 +1059,38 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - tokensToMint = - new BN(constants.seller_deposit) - .mul(new BN(constants.QTY_10)) - tokensToMint = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + tokensToMint = new BN(constants.seller_deposit).mul( + new BN(constants.QTY_10) + ); + tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.seller.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenPrice', users.buyer.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.buyer.address, - tokensToMint) - }) + tokensToMint + ); + }); - it("[NEGATIVE] Should not create voucher supply when " + - "contract is paused", + it( + '[NEGATIVE] Should not create voucher supply when ' + + 'contract is paused', async () => { - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.createOrder( @@ -940,357 +1098,403 @@ contract("Cashier && VK", async addresses => { timestamp, timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, - constants.QTY_1), + constants.QTY_1 + ), truffleAssert.ErrorType.REVERT - ) - }) - - it("Should create voucher supply when contract is unpaused", - async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) - - assert.isNotEmpty(TOKEN_SUPPLY_ID) - }) + ); + } + ); - it("[NEGATIVE] Should not create voucherID from Buyer when paused", - async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + it('Should create voucher supply when contract is unpaused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - await contractCashier.pause() + assert.isNotEmpty(TOKEN_SUPPLY_ID); + }); - await truffleAssert.reverts( - utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), - truffleAssert.ErrorType.REVERT - ) - }) + it('[NEGATIVE] Should not create voucherID from Buyer when paused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - it("[NEGATIVE] Should not process withdrawals when paused", - async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + await contractCashier.pause(); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + await truffleAssert.reverts( + utils.commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Should not process withdrawals when paused', async () => { + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await contractCashier.pause() + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await truffleAssert.reverts( - utils.withdraw(voucherID, users.deployer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await contractCashier.pause(); - it("withdrawWhenPaused - Buyer should be able to withdraw " + - "funds when paused", + await truffleAssert.reverts( + utils.withdraw(voucherID, users.deployer.address), + truffleAssert.ErrorType.REVERT + ); + }); + + it( + 'withdrawWhenPaused - Buyer should be able to withdraw ' + + 'funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.buyer.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.buyer.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Buyer should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Buyer should not be ' + + 'able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.buyer.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("withdrawWhenPaused - Seller should be able to withdraw " + - "funds when paused", + it( + 'withdrawWhenPaused - Seller should be able to withdraw ' + + 'funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() - const withdrawTx = await utils - .withdrawWhenPaused(voucherID, users.seller.address) + await contractCashier.pause(); + const withdrawTx = await utils.withdrawWhenPaused( + voucherID, + users.seller.address + ); truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', (ev) => { - return true - }, "Amounts not distributed successfully") - }) - - it("[NEGATIVE] withdrawWhenPaused - Seller should not be " + - "able to withdraw funds when not paused", + return true; + }, + 'Amounts not distributed successfully' + ); + } + ); + + it( + '[NEGATIVE] withdrawWhenPaused - Seller should not be ' + + 'able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, users.seller.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + - "able to withdraw funds when paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not be ' + + 'able to withdraw funds when paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); - await contractCashier.pause() + await contractCashier.pause(); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) + ); + } + ); - it("[NEGATIVE] withdrawWhenPaused - Attacker should not be " + - "able to withdraw funds when not paused", + it( + '[NEGATIVE] withdrawWhenPaused - Attacker should not be ' + + 'able to withdraw funds when not paused', async () => { - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_1) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_1 + ); - const voucherID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.refund(voucherID, users.buyer.address) + const voucherID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.refund(voucherID, users.buyer.address); - await timemachine.advanceTimeSeconds(60) - await utils.finalize(voucherID, users.deployer.address) + await timemachine.advanceTimeSeconds(60); + await utils.finalize(voucherID, users.deployer.address); await truffleAssert.reverts( utils.withdrawWhenPaused(voucherID, Attacker.address), truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) - - describe("VOUCHER KERNEL", () => { - describe("COMMON PAUSING", () => { + ); + } + ); + }); + }); + }); + + describe('VOUCHER KERNEL', () => { + describe('COMMON PAUSING', () => { before(async () => { - await deployContracts() - }) - - it("Should not be paused on deployment", async () => { - const isPaused = await contractVoucherKernel.paused() - assert.isFalse(isPaused) - }) - - it("Should be paused from cashier", async () => { - await contractCashier.pause() - - const isPaused = await contractVoucherKernel.paused() - assert.isTrue(isPaused) - }) - - it("Should be unpaused from cashier", async () => { - await contractCashier.pause() - await contractCashier.unpause() - - const isPaused = await contractVoucherKernel.paused() - assert.isFalse(isPaused) - }) - - it("[NEGATIVE] Pause should not be called directly", - async () => { - await truffleAssert.reverts( - contractVoucherKernel.pause(), - truffleAssert.ErrorType.REVERT - ) - }) - - it("[NEGATIVE] Pause should not be called directly", - async () => { - await truffleAssert.reverts( - contractVoucherKernel.unpause(), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("ETHETH", () => { + await deployContracts(); + }); + + it('Should not be paused on deployment', async () => { + const isPaused = await contractVoucherKernel.paused(); + assert.isFalse(isPaused); + }); + + it('Should be paused from cashier', async () => { + await contractCashier.pause(); + + const isPaused = await contractVoucherKernel.paused(); + assert.isTrue(isPaused); + }); + + it('Should be unpaused from cashier', async () => { + await contractCashier.pause(); + await contractCashier.unpause(); + + const isPaused = await contractVoucherKernel.paused(); + assert.isFalse(isPaused); + }); + + it('[NEGATIVE] Pause should not be called directly', async () => { + await truffleAssert.reverts( + contractVoucherKernel.pause(), + truffleAssert.ErrorType.REVERT + ); + }); + + it('[NEGATIVE] Pause should not be called directly', async () => { + await truffleAssert.reverts( + contractVoucherKernel.unpause(), + truffleAssert.ErrorType.REVERT + ); + }); + }); + + describe('ETHETH', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ETHETH() .build( contractERC1155ERC721, contractVoucherKernel, - contractCashier) + contractCashier + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_10) - }) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ); + }); - it("[NEGATIVE] Should not process refund when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process refund when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process complain when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process complain when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await utils.refund(VOUCHER_ID, users.buyer.address) + await utils.refund(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process redeem when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process redeem when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process cancel when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process cancel when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await utils.redeem(VOUCHER_ID, users.buyer.address) + await utils.redeem(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, users.seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("[WITH PERMIT]", () => { - describe("ETHTKN", () => { + describe('[WITH PERMIT]', () => { + describe('ETHTKN', () => { before(async () => { - await deployContracts() - await deployContracts() - utils = UtilsBuilder - .create() + await deployContracts(); + await deployContracts(); + utils = UtilsBuilder.create() .ERC20withPermit() .ETHTKN() .build( @@ -1298,91 +1502,102 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - tokensToMint = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.seller.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.buyer.address, - tokensToMint) + tokensToMint + ); - TOKEN_SUPPLY_ID = await utils - .createOrder( - users.seller, - timestamp, - timestamp + constants.SECONDS_IN_DAY, - constants.seller_deposit, - constants.QTY_10) - }) + TOKEN_SUPPLY_ID = await utils.createOrder( + users.seller, + timestamp, + timestamp + constants.SECONDS_IN_DAY, + constants.seller_deposit, + constants.QTY_10 + ); + }); - it("[NEGATIVE] Should not process refund when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process refund when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process complain when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process complain when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await utils.refund(VOUCHER_ID, users.buyer.address) + await utils.refund(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process redeem when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process redeem when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process cancel when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(VOUCHER_ID, users.buyer.address) + it('[NEGATIVE] Should not process cancel when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, users.seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNETH", () => { + describe('TKNETH', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() .TKNETH() @@ -1391,18 +1606,20 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - '') + '' + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - tokensToMint = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenPrice', users.buyer.address, - tokensToMint) + tokensToMint + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -1410,68 +1627,76 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) - }) + ); + }); - it("[NEGATIVE] Should not process refund when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process refund when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process complain when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process complain when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await utils.refund(VOUCHER_ID, users.buyer.address) + await utils.refund(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process redeem when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process redeem when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process cancel when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(VOUCHER_ID, users.buyer.address) + it('[NEGATIVE] Should not process cancel when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, users.seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); - describe("TKNTKN", () => { + describe('TKNTKN', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() .TKNTKN() @@ -1480,26 +1705,30 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - tokensToMint = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.seller.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenPrice', users.buyer.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenDeposit', users.buyer.address, - tokensToMint) + tokensToMint + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -1507,69 +1736,77 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) - }) + ); + }); - it("[NEGATIVE] Should not process refund when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process refund when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process complain when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process complain when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await utils.refund(VOUCHER_ID, users.buyer.address) + await utils.refund(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process redeem when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process redeem when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process cancel when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(VOUCHER_ID, users.buyer.address) + it('[NEGATIVE] Should not process cancel when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, users.seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); // Ignored due to deployment failure. - xdescribe("TKNTKNSAME", () => { + xdescribe('TKNTKNSAME', () => { before(async () => { - await deployContracts() + await deployContracts(); utils = UtilsBuilder.create() .ERC20withPermit() .TKNTKNSAME() @@ -1578,22 +1815,25 @@ contract("Cashier && VK", async addresses => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit) + contractBSNTokenDeposit + ); - const timestamp = await Utils.getCurrTimestamp() + const timestamp = await Utils.getCurrTimestamp(); - tokensToMint = - new BN(constants.product_price) - .mul(new BN(constants.QTY_10)) + tokensToMint = new BN(constants.product_price).mul( + new BN(constants.QTY_10) + ); await utils.mintTokens( 'contractBSNTokenSAME', users.seller.address, - tokensToMint) + tokensToMint + ); await utils.mintTokens( 'contractBSNTokenSAME', users.buyer.address, - tokensToMint) + tokensToMint + ); TOKEN_SUPPLY_ID = await utils.createOrder( users.seller, @@ -1601,72 +1841,80 @@ contract("Cashier && VK", async addresses => { timestamp + constants.SECONDS_IN_DAY, constants.seller_deposit, constants.QTY_10 - ) - }) + ); + }); - it("[NEGATIVE] Should not process refund when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process refund when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.refund(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.refund(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process complain when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process complain when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await utils.refund(VOUCHER_ID, users.buyer.address) + await utils.refund(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.complain(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.complain(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process redeem when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) + it('[NEGATIVE] Should not process redeem when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.redeem(VOUCHER_ID, users.buyer.address), - truffleAssert.ErrorType.REVERT - ) - }) + await truffleAssert.reverts( + utils.redeem(VOUCHER_ID, users.buyer.address), + truffleAssert.ErrorType.REVERT + ); + }); - it("[NEGATIVE] Should not process cancel when paused", - async () => { - VOUCHER_ID = await utils - .commitToBuy(users.buyer, users.seller, TOKEN_SUPPLY_ID) - await utils.redeem(VOUCHER_ID, users.buyer.address) + it('[NEGATIVE] Should not process cancel when paused', async () => { + VOUCHER_ID = await utils.commitToBuy( + users.buyer, + users.seller, + TOKEN_SUPPLY_ID + ); + await utils.redeem(VOUCHER_ID, users.buyer.address); - await contractCashier.pause() + await contractCashier.pause(); - await truffleAssert.reverts( - utils.cancel(VOUCHER_ID, users.seller.address), - truffleAssert.ErrorType.REVERT - ) - }) - }) - }) - }) + await truffleAssert.reverts( + utils.cancel(VOUCHER_ID, users.seller.address), + truffleAssert.ErrorType.REVERT + ); + }); + }); + }); + }); afterEach(async () => { - const isPaused = await contractCashier.paused() + const isPaused = await contractCashier.paused(); if (isPaused) { - await contractCashier.unpause() + await contractCashier.unpause(); } - }) - }) -}) + }); + }); +}); diff --git a/test/6_fundLimits.js b/test/6_fundLimits.js index 20420ea4..ceda586a 100644 --- a/test/6_fundLimits.js +++ b/test/6_fundLimits.js @@ -1,151 +1,165 @@ -const { assert } = require("chai") -const truffleAssert = require('truffle-assertions') +const {assert} = require('chai'); +const truffleAssert = require('truffle-assertions'); -const constants = require("../testHelpers/constants") -const Users = require('../testHelpers/users') -const Utils = require('../testHelpers/utils') +const constants = require('../testHelpers/constants'); +const Users = require('../testHelpers/users'); +const Utils = require('../testHelpers/utils'); -const ERC1155ERC721 = artifacts.require("ERC1155ERC721") -const VoucherKernel = artifacts.require("VoucherKernel") -const Cashier = artifacts.require("Cashier") -const BosonToken = artifacts.require('BosonTokenPrice') -const FundLimitsOracle = artifacts.require('FundLimitsOracle') +const ERC1155ERC721 = artifacts.require('ERC1155ERC721'); +const VoucherKernel = artifacts.require('VoucherKernel'); +const Cashier = artifacts.require('Cashier'); +const BosonToken = artifacts.require('BosonTokenPrice'); +const FundLimitsOracle = artifacts.require('FundLimitsOracle'); -contract("FundLimitsOracle", async addresses => { - const users = new Users(addresses) +contract('FundLimitsOracle', async (addresses) => { + const users = new Users(addresses); let contractERC1155ERC721, contractVoucherKernel, contractCashier, contractBSNTokenPrice, contractBSNTokenDeposit, - contractFundLimitsOracle - let expectedLimit + contractFundLimitsOracle; + let expectedLimit; - const FIVE_ETHERS = (5 * 10 ** 18).toString() - const FIVE_TOKENS = (5 * 10 ** 16).toString() + const FIVE_ETHERS = (5 * 10 ** 18).toString(); + const FIVE_TOKENS = (5 * 10 ** 16).toString(); - async function deployContracts () { - const timestamp = await Utils.getCurrTimestamp() + async function deployContracts() { + const timestamp = await Utils.getCurrTimestamp(); - constants.PROMISE_VALID_FROM = timestamp - constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY + constants.PROMISE_VALID_FROM = timestamp; + constants.PROMISE_VALID_TO = timestamp + 2 * constants.SECONDS_IN_DAY; - contractFundLimitsOracle = await FundLimitsOracle.new() + contractFundLimitsOracle = await FundLimitsOracle.new(); - contractERC1155ERC721 = await ERC1155ERC721.new() + contractERC1155ERC721 = await ERC1155ERC721.new(); contractVoucherKernel = await VoucherKernel.new( - contractERC1155ERC721.address) + contractERC1155ERC721.address + ); contractCashier = await Cashier.new( contractVoucherKernel.address, contractERC1155ERC721.address, - contractFundLimitsOracle.address) + contractFundLimitsOracle.address + ); - contractBSNTokenPrice = await BosonToken.new("BosonTokenPrice", "BPRC") - contractBSNTokenDeposit = await BosonToken.new("BosonTokenDeposit", "BDEP") + contractBSNTokenPrice = await BosonToken.new('BosonTokenPrice', 'BPRC'); + contractBSNTokenDeposit = await BosonToken.new('BosonTokenDeposit', 'BDEP'); - await contractERC1155ERC721 - .setApprovalForAll(contractVoucherKernel.address, 'true') - await contractERC1155ERC721 - .setVoucherKernelAddress(contractVoucherKernel.address) - await contractVoucherKernel - .setCashierAddress(contractCashier.address) + await contractERC1155ERC721.setApprovalForAll( + contractVoucherKernel.address, + 'true' + ); + await contractERC1155ERC721.setVoucherKernelAddress( + contractVoucherKernel.address + ); + await contractVoucherKernel.setCashierAddress(contractCashier.address); } describe('FundLimitsOracle interaction', () => { before(async () => { - await deployContracts() - }) + await deployContracts(); + }); - describe("ETH", () => { - it("Should have set ETH Limit initially to 1 ETH", async () => { - const ONE_ETH = (10 ** 18).toString() + describe('ETH', () => { + it('Should have set ETH Limit initially to 1 ETH', async () => { + const ONE_ETH = (10 ** 18).toString(); - const ethLimit = await contractFundLimitsOracle.getETHLimit() + const ethLimit = await contractFundLimitsOracle.getETHLimit(); assert.equal( ethLimit.toString(), ONE_ETH, - "ETH Limit not set properly") - }) + 'ETH Limit not set properly' + ); + }); - it("Owner should change ETH Limit", async () => { - await contractFundLimitsOracle.setETHLimit(FIVE_ETHERS) + it('Owner should change ETH Limit', async () => { + await contractFundLimitsOracle.setETHLimit(FIVE_ETHERS); - expectedLimit = await contractFundLimitsOracle.getETHLimit() + expectedLimit = await contractFundLimitsOracle.getETHLimit(); assert.equal( expectedLimit.toString(), FIVE_ETHERS, - "ETH Limit not correctly set") - }) + 'ETH Limit not correctly set' + ); + }); - it("Should emit LogETHLimitChanged", async () => { - const setLimitTx = await contractFundLimitsOracle - .setETHLimit(FIVE_ETHERS) + it('Should emit LogETHLimitChanged', async () => { + const setLimitTx = await contractFundLimitsOracle.setETHLimit( + FIVE_ETHERS + ); truffleAssert.eventEmitted( setLimitTx, 'LogETHLimitChanged', (ev) => { - return ev._triggeredBy === users.deployer.address + return ev._triggeredBy === users.deployer.address; }, - "LogETHLimitChanged was not emitted" - ) - }) - - it("[NEGATIVE] Should revert if attacker tries to change ETH Limit", - async () => { - await truffleAssert.reverts( - contractFundLimitsOracle.setETHLimit( - FIVE_ETHERS, { - from: users.attacker.address - }), - truffleAssert.ErrorType.REVERT - ) - }) - }) - - describe("Token", () => { - it("Owner should set Token Limit", async () => { - await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenPrice.address, FIVE_TOKENS) - - expectedLimit = await contractFundLimitsOracle - .getTokenLimit(contractBSNTokenPrice.address) + 'LogETHLimitChanged was not emitted' + ); + }); + + it('[NEGATIVE] Should revert if attacker tries to change ETH Limit', async () => { + await truffleAssert.reverts( + contractFundLimitsOracle.setETHLimit(FIVE_ETHERS, { + from: users.attacker.address, + }), + truffleAssert.ErrorType.REVERT + ); + }); + }); + + describe('Token', () => { + it('Owner should set Token Limit', async () => { + await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenPrice.address, + FIVE_TOKENS + ); + + expectedLimit = await contractFundLimitsOracle.getTokenLimit( + contractBSNTokenPrice.address + ); assert.equal( expectedLimit.toString(), FIVE_TOKENS, - "ETH Limit not correctly set") - }) + 'ETH Limit not correctly set' + ); + }); - it("Should emit LogTokenLimitChanged", async () => { - const setLimitTx = await contractFundLimitsOracle - .setTokenLimit(contractBSNTokenPrice.address, FIVE_TOKENS) + it('Should emit LogTokenLimitChanged', async () => { + const setLimitTx = await contractFundLimitsOracle.setTokenLimit( + contractBSNTokenPrice.address, + FIVE_TOKENS + ); truffleAssert.eventEmitted( setLimitTx, 'LogTokenLimitChanged', - ev => { - return ev._triggeredBy === users.deployer.address + (ev) => { + return ev._triggeredBy === users.deployer.address; }, - "LogETHLimitChanged was not emitted" - ) - }) + 'LogETHLimitChanged was not emitted' + ); + }); - it("[NEGATIVE] Should revert if attacker tries to change " + - "Token Limit", + it( + '[NEGATIVE] Should revert if attacker tries to change ' + 'Token Limit', async () => { await truffleAssert.reverts( contractFundLimitsOracle.setTokenLimit( contractBSNTokenPrice.address, - FIVE_TOKENS, { - from: users.attacker.address - }), + FIVE_TOKENS, + { + from: users.attacker.address, + } + ), truffleAssert.ErrorType.REVERT - ) - }) - }) - }) -}) \ No newline at end of file + ); + } + ); + }); + }); +}); diff --git a/testHelpers/constants.js b/testHelpers/constants.js index 9a94a92c..65453fc9 100644 --- a/testHelpers/constants.js +++ b/testHelpers/constants.js @@ -1,51 +1,51 @@ // common -const SECONDS_IN_DAY = 86400 -const ZERO_ADDRESS = "0x0000000000000000000000000000000000000000" +const SECONDS_IN_DAY = 86400; +const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; // asset -const ASSET_VERSION = "0x3132" -const ASSET_TITLE = "Dragon wizard hat" -const ASSET_TITLE2 = "T-shirt dragons" -const ASSET_TITLE3 = "T-shirt goblins" -const ASSET_PIN1 = "I3DESK" -const ASSET_PIN2 = "QBSOS" -const ASSET_QR1 = "XYZ12" -const ASSET_QR2 = "QWY43" -const ASSET_DESCRIPTION = "mighty wizard hat, universal size" -const CATEGORY1 = "entertainment.games.swag" -const CATEGORY2 = "entertainment.games.shield" +const ASSET_VERSION = '0x3132'; +const ASSET_TITLE = 'Dragon wizard hat'; +const ASSET_TITLE2 = 'T-shirt dragons'; +const ASSET_TITLE3 = 'T-shirt goblins'; +const ASSET_PIN1 = 'I3DESK'; +const ASSET_PIN2 = 'QBSOS'; +const ASSET_QR1 = 'XYZ12'; +const ASSET_QR2 = 'QWY43'; +const ASSET_DESCRIPTION = 'mighty wizard hat, universal size'; +const CATEGORY1 = 'entertainment.games.swag'; +const CATEGORY2 = 'entertainment.games.shield'; // promise -const PROMISE_VALID_FROM = '' // evaluated based on the current block timestamp -const PROMISE_VALID_TO = '' // evaluated based on the PROMISE_VALID_FROM + 2 * SECONDS_IN_DAY -const PROMISE_PRICE1 = 10 -const PROMISE_PRICE2 = 21 -const PROMISE_DEPOSITSE1 = 1 -const PROMISE_DEPOSITSE2 = 5 -const PROMISE_DEPOSITBU1 = 1 -const PROMISE_DEPOSITBU2 = 2 -const PROMISE_CHALLENGE_PERIOD = 8 -const PROMISE_CANCELORFAULT_PERIOD = 8 +const PROMISE_VALID_FROM = ''; // evaluated based on the current block timestamp +const PROMISE_VALID_TO = ''; // evaluated based on the PROMISE_VALID_FROM + 2 * SECONDS_IN_DAY +const PROMISE_PRICE1 = 10; +const PROMISE_PRICE2 = 21; +const PROMISE_DEPOSITSE1 = 1; +const PROMISE_DEPOSITSE2 = 5; +const PROMISE_DEPOSITBU1 = 1; +const PROMISE_DEPOSITBU2 = 2; +const PROMISE_CHALLENGE_PERIOD = 8; +const PROMISE_CANCELORFAULT_PERIOD = 8; // order -const ORDER_QUANTITY1 = 1 -const ORDER_QUANTITY2 = 1 +const ORDER_QUANTITY1 = 1; +const ORDER_QUANTITY2 = 1; -const buyer_deposit = '40000000000000000' // 0.04 -const buyer_incorrect_deposit = '4000000000000000' // 0.004 -const seller_deposit = '50000000000000000' // 0.05 -const product_price = '300000000000000000' // 0.3 -const incorrect_product_price = '30000000000000000' // 0.03 -const QTY_10 = 10 -const QTY_20 = 20 -const QTY_1 = 1 +const buyer_deposit = '40000000000000000'; // 0.04 +const buyer_incorrect_deposit = '4000000000000000'; // 0.004 +const seller_deposit = '50000000000000000'; // 0.05 +const product_price = '300000000000000000'; // 0.3 +const incorrect_product_price = '30000000000000000'; // 0.03 +const QTY_10 = 10; +const QTY_20 = 20; +const QTY_1 = 1; // fund limits -const ETHER_LIMIT = (5 * 10 ** 18).toString() -const ABOVE_ETH_LIMIT = (10 * 10 ** 18).toString() +const ETHER_LIMIT = (5 * 10 ** 18).toString(); +const ABOVE_ETH_LIMIT = (10 * 10 ** 18).toString(); -const TOKEN_LIMIT = (5 * 10 ** 18).toString() -const ABOVE_TOKEN_LIMIT = (10 * 10 ** 18).toString() +const TOKEN_LIMIT = (5 * 10 ** 18).toString(); +const ABOVE_TOKEN_LIMIT = (10 * 10 ** 18).toString(); module.exports = { ASSET_VERSION, @@ -84,5 +84,5 @@ module.exports = { ETHER_LIMIT, ABOVE_ETH_LIMIT, TOKEN_LIMIT, - ABOVE_TOKEN_LIMIT -} \ No newline at end of file + ABOVE_TOKEN_LIMIT, +}; diff --git a/testHelpers/permitUtils.js b/testHelpers/permitUtils.js index 8d89b745..0072c54a 100644 --- a/testHelpers/permitUtils.js +++ b/testHelpers/permitUtils.js @@ -4,24 +4,25 @@ const { toUtf8Bytes, solidityPack, AbiCoder, - Interface -} = require('ethers').utils + Interface, +} = require('ethers').utils; const PERMIT_TYPEHASH = keccak256( toUtf8Bytes( 'Permit(' + - 'address owner,' + - 'address spender,' + - 'uint256 value,' + - 'uint256 nonce,' + - 'uint256 deadline)') -) + 'address owner,' + + 'address spender,' + + 'uint256 value,' + + 'uint256 nonce,' + + 'uint256 deadline)' + ) +); const toWei = (value) => { - return value + '0'.repeat(18) -} + return value + '0'.repeat(18); +}; -async function getApprovalDigest ( +async function getApprovalDigest( token, owner, spender, @@ -29,75 +30,69 @@ async function getApprovalDigest ( nonce, deadline ) { - - const name = await token.name() - const DOMAIN_SEPARATOR = getDomainSeparator(name, token.address) + const name = await token.name(); + const DOMAIN_SEPARATOR = getDomainSeparator(name, token.address); return keccak256( solidityPack( - [ 'bytes1', 'bytes1', 'bytes32', 'bytes32' ], + ['bytes1', 'bytes1', 'bytes32', 'bytes32'], [ '0x19', '0x01', DOMAIN_SEPARATOR, keccak256( defaultAbiCoder.encode( - [ - 'bytes32', - 'address', - 'address', - 'uint256', - 'uint256', - 'uint256' - ], + ['bytes32', 'address', 'address', 'uint256', 'uint256', 'uint256'], [ PERMIT_TYPEHASH, owner, spender, value.toString(), nonce.toString(), - deadline + deadline, ] ) - ) + ), ] ) - ) + ); } -function getDomainSeparator (name, tokenAddress) { +function getDomainSeparator(name, tokenAddress) { return keccak256( defaultAbiCoder.encode( - [ 'bytes32', 'bytes32', 'bytes32', 'uint256', 'address' ], + ['bytes32', 'bytes32', 'bytes32', 'uint256', 'address'], [ - keccak256(toUtf8Bytes( - 'EIP712Domain(' + - 'string name,' + - 'string version,' + - 'uint256 chainId,' + - 'address verifyingContract)')), + keccak256( + toUtf8Bytes( + 'EIP712Domain(' + + 'string name,' + + 'string version,' + + 'uint256 chainId,' + + 'address verifyingContract)' + ) + ), keccak256(toUtf8Bytes(name)), keccak256(toUtf8Bytes('1')), 1, - tokenAddress + tokenAddress, ] ) - ) + ); } -async function getEncodedTopic (receipt, abi, eventName) { - const interface = new Interface(abi) +async function getEncodedTopic(receipt, abi, eventName) { + const interface = new Interface(abi); for (const log in receipt.logs) { - const topics = receipt.logs[log].topics + const topics = receipt.logs[log].topics; for (const index in topics) { - - const encodedTopic = topics[index] + const encodedTopic = topics[index]; try { // CHECK IF TOPIC CORRESPONDS TO THE EVENT GIVEN TO FN - let event = await interface.getEvent(encodedTopic) + let event = await interface.getEvent(encodedTopic); - if (event.name === eventName) return encodedTopic + if (event.name === eventName) return encodedTopic; } catch (error) { // breaks silently as we do not need to do anything if the there is not // such an event @@ -105,18 +100,17 @@ async function getEncodedTopic (receipt, abi, eventName) { } } - return '' + return ''; } -async function decodeData (receipt, encodedTopic, paramsArr) { - const decoder = new AbiCoder() +async function decodeData(receipt, encodedTopic, paramsArr) { + const decoder = new AbiCoder(); - const encodedData = receipt - .logs - .filter(e => e.topics.includes(encodedTopic))[0] - .data + const encodedData = receipt.logs.filter((e) => + e.topics.includes(encodedTopic) + )[0].data; - return decoder.decode(paramsArr, encodedData) + return decoder.decode(paramsArr, encodedData); } module.exports = { @@ -124,5 +118,5 @@ module.exports = { toWei, getApprovalDigest, getEncodedTopic, - decodeData -} \ No newline at end of file + decodeData, +}; diff --git a/testHelpers/timemachine.js b/testHelpers/timemachine.js index 00a6fbf8..5642812e 100644 --- a/testHelpers/timemachine.js +++ b/testHelpers/timemachine.js @@ -1,55 +1,71 @@ -function advanceTimeBlocks (_blocks) { +function advanceTimeBlocks(_blocks) { return new Promise(function (resolve) { - web3.currentProvider.send({ - jsonrpc: "2.0", - method: "evm_mine", - params: [ _blocks ], - id: new Date().getTime() - }, resolve) - }) + web3.currentProvider.send( + { + jsonrpc: '2.0', + method: 'evm_mine', + params: [_blocks], + id: new Date().getTime(), + }, + resolve + ); + }); } -function advanceTimeSeconds (_seconds) { +function advanceTimeSeconds(_seconds) { return new Promise(function (resolve) { - web3.currentProvider.send({ - jsonrpc: "2.0", - method: "evm_increaseTime", - params: [ _seconds ], - id: new Date().getTime() - }, resolve) - }) + web3.currentProvider.send( + { + jsonrpc: '2.0', + method: 'evm_increaseTime', + params: [_seconds], + id: new Date().getTime(), + }, + resolve + ); + }); } -function takeSnapshot () { +function takeSnapshot() { return new Promise((resolve, reject) => { - web3.currentProvider.send({ - jsonrpc: '2.0', - method: 'evm_snapshot', - id: new Date().getTime() - }, (err, snapshotId) => { - if (err) { return reject(err) } - return resolve(snapshotId) - }) - }) + web3.currentProvider.send( + { + jsonrpc: '2.0', + method: 'evm_snapshot', + id: new Date().getTime(), + }, + (err, snapshotId) => { + if (err) { + return reject(err); + } + return resolve(snapshotId); + } + ); + }); } -function revertToSnapShot (id) { +function revertToSnapShot(id) { return new Promise((resolve, reject) => { - web3.currentProvider.send({ - jsonrpc: '2.0', - method: 'evm_revert', - params: [ id ], - id: new Date().getTime() - }, (err, result) => { - if (err) { return reject(err) } - return resolve(result) - }) - }) + web3.currentProvider.send( + { + jsonrpc: '2.0', + method: 'evm_revert', + params: [id], + id: new Date().getTime(), + }, + (err, result) => { + if (err) { + return reject(err); + } + return resolve(result); + } + ); + }); } Object.assign(exports, { advanceTimeBlocks, advanceTimeSeconds, takeSnapshot, - revertToSnapShot -}) + revertToSnapShot, +}); diff --git a/testHelpers/users.js b/testHelpers/users.js index f6614a32..c52b2357 100644 --- a/testHelpers/users.js +++ b/testHelpers/users.js @@ -1,27 +1,27 @@ -const fs = require('fs') +const fs = require('fs'); const defaultPrivateKeys = { - "0xd9995bae12fee327256ffec1e3184d492bd94c31": - "0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8", - "0xd4fa489eacc52ba59438993f37be9fcc20090e39": - "0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f", - "0x760bf27cd45036a6c486802d30b5d90cffbe31fe": - "0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2", - "0x56a32fff5e5a8b40d6a21538579fb8922df5258c": - "0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a", - "0xfec44e15328b7d1d8885a8226b0858964358f1d6": - "0x823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2", - "0xda8a06f1c910cab18ad187be1faa2b8606c2ec86": - "0xd6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3", - "0x8199de05654e9afa5c081bce38f140082c9a7733": - "0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a", - "0x28bf45680ca598708e5cdacc1414fcac04a3f1ed": - "0xf41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25", - "0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a": - "0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543", - "0x87e0ED760fb316eeb94Bd9cF23D1d2BE87aCe3d8": - "0xfac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186", -} + '0xd9995bae12fee327256ffec1e3184d492bd94c31': + '0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8', + '0xd4fa489eacc52ba59438993f37be9fcc20090e39': + '0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f', + '0x760bf27cd45036a6c486802d30b5d90cffbe31fe': + '0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2', + '0x56a32fff5e5a8b40d6a21538579fb8922df5258c': + '0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a', + '0xfec44e15328b7d1d8885a8226b0858964358f1d6': + '0x823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2', + '0xda8a06f1c910cab18ad187be1faa2b8606c2ec86': + '0xd6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3', + '0x8199de05654e9afa5c081bce38f140082c9a7733': + '0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a', + '0x28bf45680ca598708e5cdacc1414fcac04a3f1ed': + '0xf41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25', + '0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a': + '0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543', + '0x87e0ED760fb316eeb94Bd9cF23D1d2BE87aCe3d8': + '0xfac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186', +}; const userIndices = { deployer: 0, @@ -29,60 +29,63 @@ const userIndices = { buyer: 2, attacker: 3, other1: 4, - other2: 5 -} + other2: 5, +}; -const loadPrivateKeys = accountKeysFile => { - let privateKeys = defaultPrivateKeys +const loadPrivateKeys = (accountKeysFile) => { + let privateKeys = defaultPrivateKeys; - if(accountKeysFile) { - const accountKeysRaw = fs.readFileSync(accountKeysFile) - const accountKeysJs = JSON.parse(accountKeysRaw) + if (accountKeysFile) { + const accountKeysRaw = fs.readFileSync(accountKeysFile); + const accountKeysJs = JSON.parse(accountKeysRaw); privateKeys = Object.fromEntries( - Object.entries(accountKeysJs["private_keys"]) - .map(entry => [entry[0], `0x${entry[1]}`])) + Object.entries(accountKeysJs['private_keys']).map((entry) => [ + entry[0], + `0x${entry[1]}`, + ]) + ); } - return privateKeys -} + return privateKeys; +}; class Users { constructor(addresses) { - this.addresses = addresses - this.privateKeys = loadPrivateKeys(process.env.ACCOUNT_KEYS_FILE) + this.addresses = addresses; + this.privateKeys = loadPrivateKeys(process.env.ACCOUNT_KEYS_FILE); } getAccountAtIndex(index) { - const address = this.addresses[index] - const privateKey = this.privateKeys[address.toLowerCase()] + const address = this.addresses[index]; + const privateKey = this.privateKeys[address.toLowerCase()]; - return { address, privateKey } + return {address, privateKey}; } get deployer() { - return this.getAccountAtIndex(userIndices.deployer) + return this.getAccountAtIndex(userIndices.deployer); } get seller() { - return this.getAccountAtIndex(userIndices.seller) + return this.getAccountAtIndex(userIndices.seller); } get buyer() { - return this.getAccountAtIndex(userIndices.buyer) + return this.getAccountAtIndex(userIndices.buyer); } get attacker() { - return this.getAccountAtIndex(userIndices.attacker) + return this.getAccountAtIndex(userIndices.attacker); } get other1() { - return this.getAccountAtIndex(userIndices.other1) + return this.getAccountAtIndex(userIndices.other1); } get other2() { - return this.getAccountAtIndex(userIndices.other2) + return this.getAccountAtIndex(userIndices.other2); } } -module.exports = Users +module.exports = Users; diff --git a/testHelpers/utils.js b/testHelpers/utils.js index 3857bce7..46848f47 100644 --- a/testHelpers/utils.js +++ b/testHelpers/utils.js @@ -1,61 +1,71 @@ -const helpers = require('./constants') -const BN = web3.utils.BN -const truffleAssert = require('truffle-assertions') +const helpers = require('./constants'); +const BN = web3.utils.BN; +const truffleAssert = require('truffle-assertions'); -const { ecsign } = require('ethereumjs-util') +const {ecsign} = require('ethereumjs-util'); -const { - toWei, - getApprovalDigest -} = require('../testHelpers/permitUtils') +const {toWei, getApprovalDigest} = require('../testHelpers/permitUtils'); class Utils { - constructor () { - this.createOrder = '' - this.commitToBuy = '' - this.deadline = toWei(1) + constructor() { + this.createOrder = ''; + this.commitToBuy = ''; + this.deadline = toWei(1); } - setContracts ( - erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit + setContracts( + erc1155721, + voucherKernel, + cashier, + bsnTokenPrice, + bsnTokenDeposit ) { - this.contractERC1155ERC721 = erc1155721 - this.contractVoucherKernel = voucherKernel - this.contractCashier = cashier - this.contractBSNTokenPrice = bsnTokenPrice - this.contractBSNTokenDeposit = bsnTokenDeposit - this.contractBSNTokenSAME = bsnTokenPrice + this.contractERC1155ERC721 = erc1155721; + this.contractVoucherKernel = voucherKernel; + this.contractCashier = cashier; + this.contractBSNTokenPrice = bsnTokenPrice; + this.contractBSNTokenDeposit = bsnTokenDeposit; + this.contractBSNTokenSAME = bsnTokenPrice; } - async requestCreateOrderETHETH ( - seller, from, to, sellerDeposit, qty, returnTx = false + async requestCreateOrderETHETH( + seller, + from, + to, + sellerDeposit, + qty, + returnTx = false ) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) + const txValue = new BN(sellerDeposit).mul(new BN(qty)); let txOrder = await this.contractCashier.requestCreateOrderETHETH( - [ from, + [ + from, to, helpers.product_price, sellerDeposit, helpers.buyer_deposit, - qty ], + qty, + ], { from: seller.address, - value: txValue + value: txValue, } - ) + ); - return returnTx ? - txOrder : - (txOrder.logs[0].args._tokenIdSupply).toString() + return returnTx ? txOrder : txOrder.logs[0].args._tokenIdSupply.toString(); } - async requestCreateOrderETHTKNSameWithPermit ( - seller, from, to, sellerDeposit, qty + async requestCreateOrderETHTKNSameWithPermit( + seller, + from, + to, + sellerDeposit, + qty ) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) + const txValue = new BN(sellerDeposit).mul(new BN(qty)); - const nonce = await this.contractBSNTokenSAME.nonces(seller.address) + const nonce = await this.contractBSNTokenSAME.nonces(seller.address); const digest = await getApprovalDigest( this.contractBSNTokenSAME, @@ -64,41 +74,47 @@ class Utils { txValue, nonce, this.deadline - ) + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.privateKey.slice(2), 'hex')) - - let txOrder = await this.contractCashier - .requestCreateOrderTKNTKNWithPermit( - this.contractBSNTokenSAME.address, - this.contractBSNTokenSAME.address, - txValue, - this.deadline, - v, r, s, - [ - from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty - ], - { - from: seller.address - } - ) + Buffer.from(seller.privateKey.slice(2), 'hex') + ); - return (txOrder.logs[0].args._tokenIdSupply).toString() + let txOrder = await this.contractCashier.requestCreateOrderTKNTKNWithPermit( + this.contractBSNTokenSAME.address, + this.contractBSNTokenSAME.address, + txValue, + this.deadline, + v, + r, + s, + [ + from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty, + ], + { + from: seller.address, + } + ); + + return txOrder.logs[0].args._tokenIdSupply.toString(); } - async requestCreateOrderTKNTKNWithPermit ( - seller, from, to, sellerDeposit, qty + async requestCreateOrderTKNTKNWithPermit( + seller, + from, + to, + sellerDeposit, + qty ) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) + const txValue = new BN(sellerDeposit).mul(new BN(qty)); - const nonce = await this.contractBSNTokenDeposit.nonces(seller.address) + const nonce = await this.contractBSNTokenDeposit.nonces(seller.address); const digest = await getApprovalDigest( this.contractBSNTokenDeposit, @@ -107,40 +123,47 @@ class Utils { txValue, nonce, this.deadline - ) + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.privateKey.slice(2), 'hex')) - - let txOrder = await this.contractCashier - .requestCreateOrderTKNTKNWithPermit( - this.contractBSNTokenPrice.address, - this.contractBSNTokenDeposit.address, - txValue, - this.deadline, - v, r, s, - [ - from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty - ], - { - from: seller.address - } - ) + Buffer.from(seller.privateKey.slice(2), 'hex') + ); + + let txOrder = await this.contractCashier.requestCreateOrderTKNTKNWithPermit( + this.contractBSNTokenPrice.address, + this.contractBSNTokenDeposit.address, + txValue, + this.deadline, + v, + r, + s, + [ + from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty, + ], + { + from: seller.address, + } + ); - return (txOrder.logs[0].args._tokenIdSupply).toString() + return txOrder.logs[0].args._tokenIdSupply.toString(); } - async requestCreateOrderETHTKNWithPermit ( - seller, from, to, sellerDeposit, qty, returnTx = false + async requestCreateOrderETHTKNWithPermit( + seller, + from, + to, + sellerDeposit, + qty, + returnTx = false ) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) - const nonce = await this.contractBSNTokenDeposit.nonces(seller.address) + const txValue = new BN(sellerDeposit).mul(new BN(qty)); + const nonce = await this.contractBSNTokenDeposit.nonces(seller.address); const digest = await getApprovalDigest( this.contractBSNTokenDeposit, @@ -149,40 +172,38 @@ class Utils { txValue, nonce, this.deadline - ) + ); - const { v, r, s } = ecsign( + const {v, r, s} = ecsign( Buffer.from(digest.slice(2), 'hex'), - Buffer.from(seller.privateKey.slice(2), 'hex')) - - let txOrder = await this.contractCashier - .requestCreateOrderETHTKNWithPermit( - this.contractBSNTokenDeposit.address, - txValue, - this.deadline, - v, r, s, - [ - from, - to, - helpers.product_price, - sellerDeposit, - helpers.buyer_deposit, - qty - ], - { - from: seller.address - } - ) + Buffer.from(seller.privateKey.slice(2), 'hex') + ); - return returnTx ? - txOrder : - (txOrder.logs[0].args._tokenIdSupply).toString() + let txOrder = await this.contractCashier.requestCreateOrderETHTKNWithPermit( + this.contractBSNTokenDeposit.address, + txValue, + this.deadline, + v, + r, + s, + [ + from, + to, + helpers.product_price, + sellerDeposit, + helpers.buyer_deposit, + qty, + ], + { + from: seller.address, + } + ); + + return returnTx ? txOrder : txOrder.logs[0].args._tokenIdSupply.toString(); } - async requestCreateOrderTKNETH ( - seller, from, to, sellerDeposit, qty - ) { - const txValue = new BN(sellerDeposit).mul(new BN(qty)) + async requestCreateOrderTKNETH(seller, from, to, sellerDeposit, qty) { + const txValue = new BN(sellerDeposit).mul(new BN(qty)); let txOrder = await this.contractCashier.requestCreateOrderTKNETH( this.contractBSNTokenPrice.address, @@ -192,21 +213,22 @@ class Utils { helpers.product_price, sellerDeposit, helpers.buyer_deposit, - qty + qty, ], { from: seller.address, - value: txValue + value: txValue, } - ) + ); - return (txOrder.logs[0].args._tokenIdSupply).toString() + return txOrder.logs[0].args._tokenIdSupply.toString(); } - async commitToBuyTKNTKNWithPermit (buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit) - .add(new BN(helpers.product_price)) - const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address) + async commitToBuyTKNTKNWithPermit(buyer, seller, tokenSupplyId) { + const txValue = new BN(helpers.buyer_deposit).add( + new BN(helpers.product_price) + ); + const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address); const digestDeposit = await getApprovalDigest( this.contractBSNTokenDeposit, @@ -215,17 +237,18 @@ class Utils { helpers.buyer_deposit, nonce1, this.deadline - ) + ); let VRS_DEPOSIT = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.privateKey.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex') + ); - let vDeposit = VRS_DEPOSIT.v - let rDeposit = VRS_DEPOSIT.r - let sDeposit = VRS_DEPOSIT.s + let vDeposit = VRS_DEPOSIT.v; + let rDeposit = VRS_DEPOSIT.r; + let sDeposit = VRS_DEPOSIT.s; - const nonce2 = await this.contractBSNTokenPrice.nonces(buyer.address) + const nonce2 = await this.contractBSNTokenPrice.nonces(buyer.address); const digestPrice = await getApprovalDigest( this.contractBSNTokenPrice, @@ -234,41 +257,50 @@ class Utils { helpers.product_price, nonce2, this.deadline - ) + ); let VRS_PRICE = ecsign( Buffer.from(digestPrice.slice(2), 'hex'), - Buffer.from(buyer.privateKey.slice(2), 'hex')) - - let vPrice = VRS_PRICE.v - let rPrice = VRS_PRICE.r - let sPrice = VRS_PRICE.s - - let CommitTx = await this.contractCashier - .requestVoucherTKNTKNWithPermit( - tokenSupplyId, - seller.address, - txValue, - this.deadline, - vPrice, rPrice, sPrice, - vDeposit, rDeposit, sDeposit, - { from: buyer.address }) - - let nestedValue = - (await truffleAssert - .createTransactionResult(this.contractVoucherKernel, CommitTx.tx)) - .logs - - let filtered = nestedValue - .filter(e => e.event === 'LogVoucherDelivered')[0] - - return filtered.returnValues['_tokenIdVoucher'] + Buffer.from(buyer.privateKey.slice(2), 'hex') + ); + + let vPrice = VRS_PRICE.v; + let rPrice = VRS_PRICE.r; + let sPrice = VRS_PRICE.s; + + let CommitTx = await this.contractCashier.requestVoucherTKNTKNWithPermit( + tokenSupplyId, + seller.address, + txValue, + this.deadline, + vPrice, + rPrice, + sPrice, + vDeposit, + rDeposit, + sDeposit, + {from: buyer.address} + ); + + let nestedValue = ( + await truffleAssert.createTransactionResult( + this.contractVoucherKernel, + CommitTx.tx + ) + ).logs; + + let filtered = nestedValue.filter( + (e) => e.event === 'LogVoucherDelivered' + )[0]; + + return filtered.returnValues['_tokenIdVoucher']; } - async commitToBuyETHTKNSameWithPermit (buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit) - .add(new BN(helpers.product_price)) - const nonce = await this.contractBSNTokenSAME.nonces(buyer.address) + async commitToBuyETHTKNSameWithPermit(buyer, seller, tokenSupplyId) { + const txValue = new BN(helpers.buyer_deposit).add( + new BN(helpers.product_price) + ); + const nonce = await this.contractBSNTokenSAME.nonces(buyer.address); const digestTxValue = await getApprovalDigest( this.contractBSNTokenSAME, @@ -277,38 +309,44 @@ class Utils { txValue, nonce, this.deadline - ) + ); let VRS_TX_VALUE = ecsign( Buffer.from(digestTxValue.slice(2), 'hex'), - Buffer.from(buyer.privateKey.slice(2), 'hex')) - - let v = VRS_TX_VALUE.v - let r = VRS_TX_VALUE.r - let s = VRS_TX_VALUE.s - - let CommitTx = await this.contractCashier - .requestVoucherETHTKNSameWithPermit( - tokenSupplyId, - seller.address, - txValue, - this.deadline, - v, r, s, - { from: buyer.address }) - - let nestedValue = - (await truffleAssert - .createTransactionResult(this.contractVoucherKernel, CommitTx.tx)) - .logs - - let filtered = nestedValue - .filter(e => e.event === 'LogVoucherDelivered')[0] - - return filtered.returnValues['_tokenIdVoucher'] + Buffer.from(buyer.privateKey.slice(2), 'hex') + ); + + let v = VRS_TX_VALUE.v; + let r = VRS_TX_VALUE.r; + let s = VRS_TX_VALUE.s; + + let CommitTx = await this.contractCashier.requestVoucherETHTKNSameWithPermit( + tokenSupplyId, + seller.address, + txValue, + this.deadline, + v, + r, + s, + {from: buyer.address} + ); + + let nestedValue = ( + await truffleAssert.createTransactionResult( + this.contractVoucherKernel, + CommitTx.tx + ) + ).logs; + + let filtered = nestedValue.filter( + (e) => e.event === 'LogVoucherDelivered' + )[0]; + + return filtered.returnValues['_tokenIdVoucher']; } - async commitToBuyETHTKNWithPermit (buyer, seller, tokenSupplyId) { - const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address) + async commitToBuyETHTKNWithPermit(buyer, seller, tokenSupplyId) { + const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address); const digestDeposit = await getApprovalDigest( this.contractBSNTokenDeposit, @@ -317,59 +355,68 @@ class Utils { helpers.buyer_deposit, nonce1, this.deadline - ) + ); - let { v, r, s } = ecsign( + let {v, r, s} = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.privateKey.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex') + ); - let txOrder = await this.contractCashier - .requestVoucherETHTKNWithPermit( - tokenSupplyId, - seller.address, - helpers.buyer_deposit, - this.deadline, - v, r, s, - { from: buyer.address, value: helpers.product_price.toString() } + let txOrder = await this.contractCashier.requestVoucherETHTKNWithPermit( + tokenSupplyId, + seller.address, + helpers.buyer_deposit, + this.deadline, + v, + r, + s, + {from: buyer.address, value: helpers.product_price.toString()} + ); + + let nestedValue = ( + await truffleAssert.createTransactionResult( + this.contractVoucherKernel, + txOrder.tx ) + ).logs; - let nestedValue = - (await truffleAssert - .createTransactionResult(this.contractVoucherKernel, txOrder.tx)) - .logs - - let filtered = nestedValue - .filter(e => e.event === 'LogVoucherDelivered')[0] + let filtered = nestedValue.filter( + (e) => e.event === 'LogVoucherDelivered' + )[0]; - return filtered.returnValues['_tokenIdVoucher'] + return filtered.returnValues['_tokenIdVoucher']; } - async commitToBuyETHETH (buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit) - .add(new BN(helpers.product_price)) + async commitToBuyETHETH(buyer, seller, tokenSupplyId) { + const txValue = new BN(helpers.buyer_deposit).add( + new BN(helpers.product_price) + ); - let CommitTx = await this.contractCashier - .requestVoucherETHETH( - tokenSupplyId, - seller.address, - { - from: buyer.address, - value: txValue.toString() - }) + let CommitTx = await this.contractCashier.requestVoucherETHETH( + tokenSupplyId, + seller.address, + { + from: buyer.address, + value: txValue.toString(), + } + ); - let nestedValue = - (await truffleAssert - .createTransactionResult(this.contractVoucherKernel, CommitTx.tx)) - .logs + let nestedValue = ( + await truffleAssert.createTransactionResult( + this.contractVoucherKernel, + CommitTx.tx + ) + ).logs; - let filtered = nestedValue - .filter(e => e.event === 'LogVoucherDelivered')[0] + let filtered = nestedValue.filter( + (e) => e.event === 'LogVoucherDelivered' + )[0]; - return filtered.returnValues['_tokenIdVoucher'] + return filtered.returnValues['_tokenIdVoucher']; } - async commitToBuyTKNETHWithPermit (buyer, seller, tokenSupplyId) { - const nonce1 = await this.contractBSNTokenPrice.nonces(buyer.address) + async commitToBuyTKNETHWithPermit(buyer, seller, tokenSupplyId) { + const nonce1 = await this.contractBSNTokenPrice.nonces(buyer.address); const digestDeposit = await getApprovalDigest( this.contractBSNTokenPrice, @@ -378,112 +425,109 @@ class Utils { helpers.product_price, nonce1, this.deadline - ) + ); - let { v, r, s } = ecsign( + let {v, r, s} = ecsign( Buffer.from(digestDeposit.slice(2), 'hex'), - Buffer.from(buyer.privateKey.slice(2), 'hex')) + Buffer.from(buyer.privateKey.slice(2), 'hex') + ); - let txOrder = await this.contractCashier - .requestVoucherTKNETHWithPermit( - tokenSupplyId, - seller.address, - helpers.product_price, - this.deadline, - v, r, s, - { from: buyer.address, value: helpers.buyer_deposit } + let txOrder = await this.contractCashier.requestVoucherTKNETHWithPermit( + tokenSupplyId, + seller.address, + helpers.product_price, + this.deadline, + v, + r, + s, + {from: buyer.address, value: helpers.buyer_deposit} + ); + + let nestedValue = ( + await truffleAssert.createTransactionResult( + this.contractVoucherKernel, + txOrder.tx ) + ).logs; - let nestedValue = - (await truffleAssert - .createTransactionResult(this.contractVoucherKernel, txOrder.tx)) - .logs + let filtered = nestedValue.filter( + (e) => e.event === 'LogVoucherDelivered' + )[0]; - let filtered = nestedValue - .filter(e => e.event === 'LogVoucherDelivered')[0] - - return filtered.returnValues['_tokenIdVoucher'] + return filtered.returnValues['_tokenIdVoucher']; } - async refund (voucherID, buyer) { - await this.contractVoucherKernel - .refund(voucherID, { from: buyer }) + async refund(voucherID, buyer) { + await this.contractVoucherKernel.refund(voucherID, {from: buyer}); } - async redeem (voucherID, buyer) { - await this.contractVoucherKernel - .redeem(voucherID, { from: buyer }) + async redeem(voucherID, buyer) { + await this.contractVoucherKernel.redeem(voucherID, {from: buyer}); } - async complain (voucherID, buyer) { - await this.contractVoucherKernel - .complain(voucherID, { from: buyer }) + async complain(voucherID, buyer) { + await this.contractVoucherKernel.complain(voucherID, {from: buyer}); } - async cancel (voucherID, seller) { - await this.contractVoucherKernel - .cancelOrFault(voucherID, { from: seller }) + async cancel(voucherID, seller) { + await this.contractVoucherKernel.cancelOrFault(voucherID, {from: seller}); } - async finalize (voucherID, deployer) { - await this.contractVoucherKernel - .triggerFinalizeVoucher(voucherID, { from: deployer }) + async finalize(voucherID, deployer) { + await this.contractVoucherKernel.triggerFinalizeVoucher(voucherID, { + from: deployer, + }); } - async withdraw (voucherID, deployer) { - const tx = await this.contractCashier - .withdraw(voucherID, { from: deployer }) + async withdraw(voucherID, deployer) { + const tx = await this.contractCashier.withdraw(voucherID, {from: deployer}); - console.log('GAS USED: ', tx.receipt.gasUsed) + console.log('GAS USED: ', tx.receipt.gasUsed); - return tx + return tx; } - async withdrawWhenPaused (voucherID, executor) { - const tx = await this.contractCashier - .withdrawWhenPaused(voucherID, { from: executor }) + async withdrawWhenPaused(voucherID, executor) { + const tx = await this.contractCashier.withdrawWhenPaused(voucherID, { + from: executor, + }); - console.log('GAS USED: ', tx.receipt.gasUsed) + console.log('GAS USED: ', tx.receipt.gasUsed); - return tx + return tx; } - async pause (deployer) { - await this.contractCashier.pause({ from: deployer }) + async pause(deployer) { + await this.contractCashier.pause({from: deployer}); } - async safeTransfer721 ( - oldVoucherOwner, newVoucherOwner, voucherID, from - ) { - const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') + async safeTransfer721(oldVoucherOwner, newVoucherOwner, voucherID, from) { + const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0'); - const methodSignature = 'safeTransferFrom(' + - 'address,' + - 'address,' + - 'uint256,' + - 'bytes)' - const method = this.contractERC1155ERC721.methods[methodSignature] + const methodSignature = + 'safeTransferFrom(' + 'address,' + 'address,' + 'uint256,' + 'bytes)'; + const method = this.contractERC1155ERC721.methods[methodSignature]; return await method( oldVoucherOwner, newVoucherOwner, voucherID, arbitraryBytes, - from) + from + ); } - async safeTransfer1155 ( - oldSupplyOwner, newSupplyOwner, supplyID, qty, from - ) { - const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') + async safeTransfer1155(oldSupplyOwner, newSupplyOwner, supplyID, qty, from) { + const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0'); - const methodSignature = 'safeTransferFrom(' + + const methodSignature = + 'safeTransferFrom(' + 'address,' + 'address,' + 'uint256,' + 'uint256,' + - 'bytes)' - const method = this.contractERC1155ERC721.methods[methodSignature] + 'bytes)'; + const method = this.contractERC1155ERC721.methods[methodSignature]; return await method( oldSupplyOwner, @@ -491,21 +535,27 @@ class Utils { supplyID, qty, arbitraryBytes, - from) + from + ); } - async safeBatchTransfer1155 ( - oldSupplyOwner, newSupplyOwner, supplyIDs, values, from + async safeBatchTransfer1155( + oldSupplyOwner, + newSupplyOwner, + supplyIDs, + values, + from ) { - const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0') + const arbitraryBytes = web3.utils.fromAscii('0x0').padEnd(66, '0'); - const methodSignature = 'safeBatchTransferFrom(' + + const methodSignature = + 'safeBatchTransferFrom(' + 'address,' + 'address,' + 'uint256[],' + 'uint256[],' + - 'bytes)' - const method = this.contractERC1155ERC721.methods[methodSignature] + 'bytes)'; + const method = this.contractERC1155ERC721.methods[methodSignature]; return await method( oldSupplyOwner, @@ -513,37 +563,42 @@ class Utils { supplyIDs, values, arbitraryBytes, - from) + from + ); } - calcTotalAmountToRecipients ( - event, distributionAmounts, recipient, buyer, seller + calcTotalAmountToRecipients( + event, + distributionAmounts, + recipient, + buyer, + seller ) { if (event[recipient] === buyer) { - distributionAmounts.buyerAmount = - new BN(distributionAmounts.buyerAmount.toString()) - .add(new BN(event._payment.toString())) + distributionAmounts.buyerAmount = new BN( + distributionAmounts.buyerAmount.toString() + ).add(new BN(event._payment.toString())); } else if (event[recipient] === seller) { - distributionAmounts.sellerAmount = - new BN(distributionAmounts.sellerAmount.toString()) - .add(new BN(event._payment.toString())) + distributionAmounts.sellerAmount = new BN( + distributionAmounts.sellerAmount.toString() + ).add(new BN(event._payment.toString())); } else { - distributionAmounts.escrowAmount = - new BN(distributionAmounts.escrowAmount.toString()) - .add(new BN(event._payment.toString())) + distributionAmounts.escrowAmount = new BN( + distributionAmounts.escrowAmount.toString() + ).add(new BN(event._payment.toString())); } } - async mintTokens (tokenContract, to, value) { - await this[tokenContract].mint(to, value) + async mintTokens(tokenContract, to, value) { + await this[tokenContract].mint(to, value); } - static async getCurrTimestamp () { - let blockNumber = await web3.eth.getBlockNumber() - let block = await web3.eth.getBlock(blockNumber) + static async getCurrTimestamp() { + let blockNumber = await web3.eth.getBlockNumber(); + let block = await web3.eth.getBlock(blockNumber); - return block.timestamp + return block.timestamp; } } -module.exports = Utils +module.exports = Utils; diff --git a/testHelpers/utilsBuilder.js b/testHelpers/utilsBuilder.js index 60fa77f5..d46d090e 100644 --- a/testHelpers/utilsBuilder.js +++ b/testHelpers/utilsBuilder.js @@ -1,81 +1,70 @@ // @ts-nocheck -const Utils = require('./utils') +const Utils = require('./utils'); class UtilsBuilder { - constructor () { - this.utils = new Utils() + constructor() { + this.utils = new Utils(); } - static create () { - return new UtilsBuilder() - }; + static create() { + return new UtilsBuilder(); + } - ETHETH () { - this.utils.createOrder = - this.utils.requestCreateOrderETHETH - this.utils.commitToBuy = - this.utils.commitToBuyETHETH + ETHETH() { + this.utils.createOrder = this.utils.requestCreateOrderETHETH; + this.utils.commitToBuy = this.utils.commitToBuyETHETH; - return this + return this; } - ERC20withPermit () { - this.ETHTKN = this.ETHTKNWithPermit - this.TKNTKN = this.TKNTKNWithPermit - this.TKNETH = this.TKNETHWithPermit - this.TKNTKNSAME = this.TKNTKNSameWithPermit + ERC20withPermit() { + this.ETHTKN = this.ETHTKNWithPermit; + this.TKNTKN = this.TKNTKNWithPermit; + this.TKNETH = this.TKNETHWithPermit; + this.TKNTKNSAME = this.TKNTKNSameWithPermit; - return this + return this; } - build ( - erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit - ) { + build(erc1155721, voucherKernel, cashier, bsnTokenPrice, bsnTokenDeposit) { this.utils.setContracts( erc1155721, voucherKernel, cashier, bsnTokenPrice, - bsnTokenDeposit) + bsnTokenDeposit + ); - return this.utils + return this.utils; } - ETHTKNWithPermit () { - this.utils.createOrder = - this.utils.requestCreateOrderETHTKNWithPermit - this.utils.commitToBuy = - this.utils.commitToBuyETHTKNWithPermit + ETHTKNWithPermit() { + this.utils.createOrder = this.utils.requestCreateOrderETHTKNWithPermit; + this.utils.commitToBuy = this.utils.commitToBuyETHTKNWithPermit; - return this + return this; } - TKNTKNWithPermit () { - this.utils.createOrder = - this.utils.requestCreateOrderTKNTKNWithPermit - this.utils.commitToBuy = - this.utils.commitToBuyTKNTKNWithPermit + TKNTKNWithPermit() { + this.utils.createOrder = this.utils.requestCreateOrderTKNTKNWithPermit; + this.utils.commitToBuy = this.utils.commitToBuyTKNTKNWithPermit; - return this + return this; } - TKNTKNSameWithPermit () { - this.utils.createOrder = - this.utils.requestCreateOrderETHTKNSameWithPermit - this.utils.commitToBuy = - this.utils.commitToBuyETHTKNSameWithPermit + TKNTKNSameWithPermit() { + this.utils.createOrder = this.utils.requestCreateOrderETHTKNSameWithPermit; + this.utils.commitToBuy = this.utils.commitToBuyETHTKNSameWithPermit; - return this + return this; } - TKNETHWithPermit () { - this.utils.createOrder = - this.utils.requestCreateOrderTKNETH - this.utils.commitToBuy = - this.utils.commitToBuyTKNETHWithPermit + TKNETHWithPermit() { + this.utils.createOrder = this.utils.requestCreateOrderTKNETH; + this.utils.commitToBuy = this.utils.commitToBuyTKNETHWithPermit; - return this + return this; } } -module.exports = UtilsBuilder +module.exports = UtilsBuilder; diff --git a/testUserInteractions/buyer_complain.js b/testUserInteractions/buyer_complain.js index c47855b5..bf2f4d5d 100644 --- a/testUserInteractions/buyer_complain.js +++ b/testUserInteractions/buyer_complain.js @@ -1,42 +1,51 @@ -const VoucherKernel = require("../build/VoucherKernel.json"); +const VoucherKernel = require('../build/VoucherKernel.json'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { VOUCHER_ID, BUYER_SECRET, contracts } = require('./config'); -const accountBuyer = new ethers.Wallet(BUYER_SECRET, provider); - -(async() => { - let voucherKernelContract_Buyer = new ethers.Contract(contracts.VoucherKernelContractAddress, VoucherKernel.abi, accountBuyer) - - const tokenIdVoucher = VOUCHER_ID - - let txOrder = await voucherKernelContract_Buyer.complain( - tokenIdVoucher, {gasLimit: '4000000'}); - - const receipt = await txOrder.wait() - - let parsedEvent = await findEventByName(receipt, 'LogVoucherComplain', '_tokenIdVoucher') - console.log('parsedEvent'); - console.log(parsedEvent); - +const {VOUCHER_ID, BUYER_SECRET, contracts} = require('./config'); +const accountBuyer = new ethers.Wallet(BUYER_SECRET, provider); + +(async () => { + let voucherKernelContract_Buyer = new ethers.Contract( + contracts.VoucherKernelContractAddress, + VoucherKernel.abi, + accountBuyer + ); + + const tokenIdVoucher = VOUCHER_ID; + + let txOrder = await voucherKernelContract_Buyer.complain(tokenIdVoucher, { + gasLimit: '4000000', + }); + + const receipt = await txOrder.wait(); + + let parsedEvent = await findEventByName( + receipt, + 'LogVoucherComplain', + '_tokenIdVoucher' + ); + console.log('parsedEvent'); + console.log(parsedEvent); })(); async function findEventByName(txReceipt, eventName, ...eventFields) { + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] - - const resultObj = { - txHash: txReceipt.transactionHash - } + const resultObj = { + txHash: txReceipt.transactionHash, + }; - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - return resultObj - } + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + return resultObj; } + } } /** @@ -45,4 +54,4 @@ async function findEventByName(txReceipt, eventName, ...eventFields) { '0xa00ae1284ad381e1aa2e172be82ca1c16968ea3cb25dec0ab67abd4cac7311c8', _tokenIdVoucher: '57896044618658097711785492504343953957600687722625682194895881280247472062467' } - */ \ No newline at end of file + */ diff --git a/testUserInteractions/buyer_redeem.js b/testUserInteractions/buyer_redeem.js index d84dce56..118fe5a8 100644 --- a/testUserInteractions/buyer_redeem.js +++ b/testUserInteractions/buyer_redeem.js @@ -1,42 +1,53 @@ -const VoucherKernel = require("../build/VoucherKernel.json"); +const VoucherKernel = require('../build/VoucherKernel.json'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { VOUCHER_ID, BUYER_SECRET, contracts } = require('./config'); -const accountBuyer = new ethers.Wallet(BUYER_SECRET, provider); - -(async() => { - let voucherKernelContract_Buyer = new ethers.Contract(contracts.VoucherKernelContractAddress, VoucherKernel.abi, accountBuyer) - - const tokenIdVoucher = VOUCHER_ID - - let txOrder = await voucherKernelContract_Buyer.redeem( - tokenIdVoucher, {gasLimit: '4000000'}); - - const receipt = await txOrder.wait() - - let parsedEvent = await findEventByName(receipt, 'LogVoucherRedeemed', '_tokenIdVoucher', '_holder', '_promiseId') - console.log('parsedEvent'); - console.log(parsedEvent); - +const {VOUCHER_ID, BUYER_SECRET, contracts} = require('./config'); +const accountBuyer = new ethers.Wallet(BUYER_SECRET, provider); + +(async () => { + let voucherKernelContract_Buyer = new ethers.Contract( + contracts.VoucherKernelContractAddress, + VoucherKernel.abi, + accountBuyer + ); + + const tokenIdVoucher = VOUCHER_ID; + + let txOrder = await voucherKernelContract_Buyer.redeem(tokenIdVoucher, { + gasLimit: '4000000', + }); + + const receipt = await txOrder.wait(); + + let parsedEvent = await findEventByName( + receipt, + 'LogVoucherRedeemed', + '_tokenIdVoucher', + '_holder', + '_promiseId' + ); + console.log('parsedEvent'); + console.log(parsedEvent); })(); async function findEventByName(txReceipt, eventName, ...eventFields) { + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] - - const resultObj = { - txHash: txReceipt.transactionHash - } + const resultObj = { + txHash: txReceipt.transactionHash, + }; - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - return resultObj - } + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + return resultObj; } + } } /** @@ -48,4 +59,4 @@ async function findEventByName(txReceipt, eventName, ...eventFields) { _holder: '0xd4Fa489Eacc52BA59438993f37Be9fcC20090E39', _promiseId: '0x201fb46fee4d1db3d3256ffd44a7be8d4035bbf504cb8413393d3bc891e849d4' } - */ \ No newline at end of file + */ diff --git a/testUserInteractions/buyer_refund.js b/testUserInteractions/buyer_refund.js index 0a897632..95cc7ca2 100644 --- a/testUserInteractions/buyer_refund.js +++ b/testUserInteractions/buyer_refund.js @@ -1,41 +1,49 @@ -const VoucherKernel = require("../build/VoucherKernel.json"); +const VoucherKernel = require('../build/VoucherKernel.json'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { VOUCHER_ID, BUYER_SECRET, contracts } = require('./config'); +const {VOUCHER_ID, BUYER_SECRET, contracts} = require('./config'); const accountBuyer = new ethers.Wallet(BUYER_SECRET, provider); - -(async() => { - let voucherKernelContract_Buyer = new ethers.Contract(contracts.VoucherKernelContractAddress, VoucherKernel.abi, accountBuyer) - - let txOrder = await voucherKernelContract_Buyer.refund( - VOUCHER_ID, {gasLimit: '4000000'}); - - const receipt = await txOrder.wait() - - let parsedEvent = await findEventByName(receipt, 'LogVoucherRefunded', '_tokenIdVoucher') - console.log('parsedEvent'); - console.log(parsedEvent); - +(async () => { + let voucherKernelContract_Buyer = new ethers.Contract( + contracts.VoucherKernelContractAddress, + VoucherKernel.abi, + accountBuyer + ); + + let txOrder = await voucherKernelContract_Buyer.refund(VOUCHER_ID, { + gasLimit: '4000000', + }); + + const receipt = await txOrder.wait(); + + let parsedEvent = await findEventByName( + receipt, + 'LogVoucherRefunded', + '_tokenIdVoucher' + ); + console.log('parsedEvent'); + console.log(parsedEvent); })(); async function findEventByName(txReceipt, eventName, ...eventFields) { - - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] - - const resultObj = { - txHash: txReceipt.transactionHash - } - - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - return resultObj - } + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; + + const resultObj = { + txHash: txReceipt.transactionHash, + }; + + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + return resultObj; } + } } /** @@ -43,4 +51,4 @@ async function findEventByName(txReceipt, eventName, ...eventFields) { '0x8cd2840d6a2e2b9cf7995380256bb28606cd520aa345a1a61359ace0a31e1d5c', _tokenIdVoucher: '57896044618658097711785492504343953957600687722625682194895881280247472062467' } - */ \ No newline at end of file + */ diff --git a/testUserInteractions/buyer_requestVoucher.js b/testUserInteractions/buyer_requestVoucher.js index 20c77795..5d55730d 100644 --- a/testUserInteractions/buyer_requestVoucher.js +++ b/testUserInteractions/buyer_requestVoucher.js @@ -1,53 +1,69 @@ -const Cashier = require("../build/Cashier.json"); -const helpers = require('../testHelpers/constants') +const Cashier = require('../build/Cashier.json'); +const helpers = require('../testHelpers/constants'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { SELLER_PUBLIC, BUYER_SECRET, contracts, TOKEN_SUPPLY_ID } = require('./config'); -const accountBuyer = new ethers.Wallet(BUYER_SECRET, provider); - +const { + SELLER_PUBLIC, + BUYER_SECRET, + contracts, + TOKEN_SUPPLY_ID, +} = require('./config'); +const accountBuyer = new ethers.Wallet(BUYER_SECRET, provider); (async () => { + let cashierContract_Buyer = new ethers.Contract( + contracts.CashierContractAddress, + Cashier.abi, + accountBuyer + ); - let cashierContract_Buyer = new ethers.Contract(contracts.CashierContractAddress, Cashier.abi, accountBuyer) - - const tokenSupplyKey = TOKEN_SUPPLY_ID - - const buyerDeposit = helpers.buyer_deposit; - const price = helpers.product_price; - const txValue = ethers.BigNumber.from(buyerDeposit).add(ethers.BigNumber.from(price)) + const tokenSupplyKey = TOKEN_SUPPLY_ID; + const buyerDeposit = helpers.buyer_deposit; + const price = helpers.product_price; + const txValue = ethers.BigNumber.from(buyerDeposit).add( + ethers.BigNumber.from(price) + ); - let txOrder = await cashierContract_Buyer.requestVoucher( - tokenSupplyKey, - SELLER_PUBLIC, - { value: txValue.toString()} - ); + let txOrder = await cashierContract_Buyer.requestVoucher( + tokenSupplyKey, + SELLER_PUBLIC, + {value: txValue.toString()} + ); - const receipt = await txOrder.wait() - - let parsedEvent = await findEventByName(receipt, 'LogVoucherDelivered', '_tokenIdSupply', '_tokenIdVoucher', '_issuer', '_holder', '_promiseId') - console.log('parsedEvent'); - console.log(parsedEvent); + const receipt = await txOrder.wait(); + let parsedEvent = await findEventByName( + receipt, + 'LogVoucherDelivered', + '_tokenIdSupply', + '_tokenIdVoucher', + '_issuer', + '_holder', + '_promiseId' + ); + console.log('parsedEvent'); + console.log(parsedEvent); })(); async function findEventByName(txReceipt, eventName, ...eventFields) { + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] - - const resultObj = { - txHash: txReceipt.transactionHash - } + const resultObj = { + txHash: txReceipt.transactionHash, + }; - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - return resultObj - } + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + return resultObj; } + } } /** @@ -61,4 +77,4 @@ async function findEventByName(txReceipt, eventName, ...eventFields) { '0x3c654b884252d1ea1fa50c47718de4a4868587631708d184b5f157da15ed2889', txHash: '0xa2acb1af433d4a4bde65e84e69c92817b3d8c37c81b19f7e1b42c3025b31d20b' } - */ \ No newline at end of file + */ diff --git a/testUserInteractions/config.js b/testUserInteractions/config.js index f95066e6..393e071c 100644 --- a/testUserInteractions/config.js +++ b/testUserInteractions/config.js @@ -1,19 +1,17 @@ module.exports = { - TOKEN_SUPPLY_ID: "token supply id", - VOUCHER_ID: "voucher id", - contracts: { - TokenContractAddress: 'token contract address', - VoucherKernelContractAddress: 'voucher kernel contract address', - CashierContractAddress: 'cashier contract address' - }, - DEPLOYER_PUBLIC: 'deployer public key', - DEPLOYER_SECRET: 'deployer secret key', - BUYER_PUBLIC: 'buyer public key', - BUYER_SECRET: 'buyer secret key', - SELLER_PUBLIC: 'seller public key', - SELLER_SECRET: 'seller secret key', - DB_VOUCHER_TO_MODIFY: "", // this is if you would like to manipulate some record in a local DB. The voucher you are editing must be with the same price, buyer deposit and seller deposit! - SEND_TO_DB: false -} - - + TOKEN_SUPPLY_ID: 'token supply id', + VOUCHER_ID: 'voucher id', + contracts: { + TokenContractAddress: 'token contract address', + VoucherKernelContractAddress: 'voucher kernel contract address', + CashierContractAddress: 'cashier contract address', + }, + DEPLOYER_PUBLIC: 'deployer public key', + DEPLOYER_SECRET: 'deployer secret key', + BUYER_PUBLIC: 'buyer public key', + BUYER_SECRET: 'buyer secret key', + SELLER_PUBLIC: 'seller public key', + SELLER_SECRET: 'seller secret key', + DB_VOUCHER_TO_MODIFY: '', // this is if you would like to manipulate some record in a local DB. The voucher you are editing must be with the same price, buyer deposit and seller deposit! + SEND_TO_DB: false, +}; diff --git a/testUserInteractions/deploy.js b/testUserInteractions/deploy.js index 01a0abf0..aa9302a4 100644 --- a/testUserInteractions/deploy.js +++ b/testUserInteractions/deploy.js @@ -1,31 +1,56 @@ -const ERC1155ERC721 = require("../build/ERC1155ERC721.json"); -const VoucherKernel = require("../build/VoucherKernel.json"); -const Cashier = require("../build/Cashier.json"); +const ERC1155ERC721 = require('../build/ERC1155ERC721.json'); +const VoucherKernel = require('../build/VoucherKernel.json'); +const Cashier = require('../build/Cashier.json'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { DEPLOYER_SECRET, SELLER_SECRET} = require('./config') -const deployer = new ethers.Wallet(DEPLOYER_SECRET, provider); -const accountSeller = new ethers.Wallet(SELLER_SECRET, provider); +const {DEPLOYER_SECRET, SELLER_SECRET} = require('./config'); +const deployer = new ethers.Wallet(DEPLOYER_SECRET, provider); +const accountSeller = new ethers.Wallet(SELLER_SECRET, provider); (async () => { - const ERC1155_Factory = new ethers.ContractFactory(ERC1155ERC721.abi, ERC1155ERC721.bytecode, deployer) - const VoucherKernel_Factory = new ethers.ContractFactory(VoucherKernel.abi, VoucherKernel.bytecode, deployer) - const Cashier_Factory = new ethers.ContractFactory(Cashier.abi, Cashier.bytecode, deployer) - - const TokenContract = await ERC1155_Factory.deploy(); - const TokenContractSeller = await new ethers.Contract(TokenContract.address, ERC1155ERC721.abi, accountSeller); - const VoucherKernelContract = await VoucherKernel_Factory.deploy(TokenContract.address); - const CashierContract = await Cashier_Factory.deploy(VoucherKernelContract.address); + const ERC1155_Factory = new ethers.ContractFactory( + ERC1155ERC721.abi, + ERC1155ERC721.bytecode, + deployer + ); + const VoucherKernel_Factory = new ethers.ContractFactory( + VoucherKernel.abi, + VoucherKernel.bytecode, + deployer + ); + const Cashier_Factory = new ethers.ContractFactory( + Cashier.abi, + Cashier.bytecode, + deployer + ); - await TokenContract.setApprovalForAll(VoucherKernelContract.address, 'true'); - await TokenContractSeller.setApprovalForAll(VoucherKernelContract.address, 'true'); - await TokenContract.setVoucherKernelAddress(VoucherKernelContract.address); - await VoucherKernelContract.setCashierAddress(CashierContract.address); + const TokenContract = await ERC1155_Factory.deploy(); + const TokenContractSeller = await new ethers.Contract( + TokenContract.address, + ERC1155ERC721.abi, + accountSeller + ); + const VoucherKernelContract = await VoucherKernel_Factory.deploy( + TokenContract.address + ); + const CashierContract = await Cashier_Factory.deploy( + VoucherKernelContract.address + ); + await TokenContract.setApprovalForAll(VoucherKernelContract.address, 'true'); + await TokenContractSeller.setApprovalForAll( + VoucherKernelContract.address, + 'true' + ); + await TokenContract.setVoucherKernelAddress(VoucherKernelContract.address); + await VoucherKernelContract.setCashierAddress(CashierContract.address); - console.log('Token Contract Address: ', TokenContract.address); - console.log('Voucher Kernel Contract Address: ', VoucherKernelContract.address); - console.log('Cashier Contract Address: ', CashierContract.address); -})() + console.log('Token Contract Address: ', TokenContract.address); + console.log( + 'Voucher Kernel Contract Address: ', + VoucherKernelContract.address + ); + console.log('Cashier Contract Address: ', CashierContract.address); +})(); diff --git a/testUserInteractions/finalize.js b/testUserInteractions/finalize.js index bc5a5388..ea3171c1 100644 --- a/testUserInteractions/finalize.js +++ b/testUserInteractions/finalize.js @@ -1,64 +1,85 @@ -const VoucherKernel = require("../build/VoucherKernel.json"); +const VoucherKernel = require('../build/VoucherKernel.json'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { SELLER_SECRET, VOUCHER_ID, - DB_VOUCHER_TO_MODIFY, contracts, SEND_TO_DB } = require('./config'); +const { + SELLER_SECRET, + VOUCHER_ID, + DB_VOUCHER_TO_MODIFY, + contracts, + SEND_TO_DB, +} = require('./config'); -const seller = new ethers.Wallet(SELLER_SECRET, provider); +const seller = new ethers.Wallet(SELLER_SECRET, provider); const axios = require('axios').default; -(async() => { - let voucherKernelContract_Buyer = new ethers.Contract(contracts.VoucherKernelContractAddress, VoucherKernel.abi, seller) - const tokenIdVoucher = VOUCHER_ID - - let txOrder = await voucherKernelContract_Buyer.triggerFinalizeVoucher( - tokenIdVoucher, {gasLimit: '4000000'}); - - const receipt = await txOrder.wait() - let parsedEvent = await findEventByName(receipt, 'LogFinalizeVoucher', '_tokenIdVoucher', '_triggeredBy') - - - if(parsedEvent) { - parsedEvent[0]._tokenIdVoucher = DB_VOUCHER_TO_MODIFY - const payload = [{ - ...parsedEvent[0], - status: "FINALIZED" - }] - console.log('Payload!'); - console.log(payload); - - if(!SEND_TO_DB) return - - try { - await axios.patch(`http://localhost:3000/user-vouchers/finalize`, payload) - } catch (error) { - console.log(error); - } +(async () => { + let voucherKernelContract_Buyer = new ethers.Contract( + contracts.VoucherKernelContractAddress, + VoucherKernel.abi, + seller + ); + const tokenIdVoucher = VOUCHER_ID; + + let txOrder = await voucherKernelContract_Buyer.triggerFinalizeVoucher( + tokenIdVoucher, + {gasLimit: '4000000'} + ); + + const receipt = await txOrder.wait(); + let parsedEvent = await findEventByName( + receipt, + 'LogFinalizeVoucher', + '_tokenIdVoucher', + '_triggeredBy' + ); + + if (parsedEvent) { + parsedEvent[0]._tokenIdVoucher = DB_VOUCHER_TO_MODIFY; + const payload = [ + { + ...parsedEvent[0], + status: 'FINALIZED', + }, + ]; + console.log('Payload!'); + console.log(payload); + + if (!SEND_TO_DB) return; + + try { + await axios.patch( + `http://localhost:3000/user-vouchers/finalize`, + payload + ); + } catch (error) { + console.log(error); } - + } })(); async function findEventByName(txReceipt, eventName, ...eventFields) { - let eventsArr = []; + let eventsArr = []; - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; - const resultObj = { - txHash: txReceipt.transactionHash - } + const resultObj = { + txHash: txReceipt.transactionHash, + }; - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - eventsArr.push(resultObj) - } + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + eventsArr.push(resultObj); } + } - return eventsArr + return eventsArr; } /** @@ -69,11 +90,11 @@ async function findEventByName(txReceipt, eventName, ...eventFields) { _triggeredBy: '0x5aF2b312eC207D78C4de4E078270F0d8700C01e2' } */ - //should be like this - /** +//should be like this +/** { "txHash":"0xa96d9f92e73f1aa2a489a492c0cecb6d799b3cac807a93a298a84662c078b574", "_tokenIdVoucher":"57896044618658097711785492504343953926975274699741220483192166611388333031426", "_triggeredBy": "0x5aF2b312eC207D78C4de4E078270F0d8700C01e2", "status": "FINALIZED" } - */ \ No newline at end of file + */ diff --git a/testUserInteractions/fundWallets.js b/testUserInteractions/fundWallets.js index 4f070e89..b2eb9d72 100644 --- a/testUserInteractions/fundWallets.js +++ b/testUserInteractions/fundWallets.js @@ -1,32 +1,34 @@ const ethers = require('ethers'); -const provider = new ethers.providers.JsonRpcProvider() -const {DEPLOYER_PUBLIC, BUYER_PUBLIC, SELLER_PUBLIC} = require('./config') -let wallet = new ethers.Wallet('0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8', provider); // account 0 from local etherlime ganache +const provider = new ethers.providers.JsonRpcProvider(); +const {DEPLOYER_PUBLIC, BUYER_PUBLIC, SELLER_PUBLIC} = require('./config'); +let wallet = new ethers.Wallet( + '0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8', + provider +); // account 0 from local etherlime ganache (async () => { - await fundWallets(); -})() + await fundWallets(); +})(); async function fundWallets() { + const fundAmount = ethers.utils.parseEther('5'); - const fundAmount = ethers.utils.parseEther('5'); + let transactionSeller = { + to: SELLER_PUBLIC, + value: fundAmount, + }; - let transactionSeller = { - to: SELLER_PUBLIC, - value: fundAmount, - }; + let transactionBuyer = { + to: BUYER_PUBLIC, + value: fundAmount, + }; - let transactionBuyer = { - to: BUYER_PUBLIC, - value: fundAmount, - }; + let transactionDeployer = { + to: DEPLOYER_PUBLIC, + value: fundAmount, + }; - let transactionDeployer = { - to: DEPLOYER_PUBLIC, - value: fundAmount, - }; - - await wallet.sendTransaction(transactionSeller); - await wallet.sendTransaction(transactionBuyer); - await wallet.sendTransaction(transactionDeployer); -} \ No newline at end of file + await wallet.sendTransaction(transactionSeller); + await wallet.sendTransaction(transactionBuyer); + await wallet.sendTransaction(transactionDeployer); +} diff --git a/testUserInteractions/seller_cancelOrFault.js b/testUserInteractions/seller_cancelOrFault.js index 542ca44c..fecd4193 100644 --- a/testUserInteractions/seller_cancelOrFault.js +++ b/testUserInteractions/seller_cancelOrFault.js @@ -1,41 +1,48 @@ - -const VoucherKernel = require("../build/VoucherKernel.json"); +const VoucherKernel = require('../build/VoucherKernel.json'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { SELLER_SECRET, VOUCHER_ID, contracts } = require('./config'); +const {SELLER_SECRET, VOUCHER_ID, contracts} = require('./config'); const seller = new ethers.Wallet(SELLER_SECRET, provider); -(async() => { - let voucherKernelContract_Seller = new ethers.Contract(contracts.VoucherKernelContractAddress, VoucherKernel.abi, seller) - - let txOrder = await voucherKernelContract_Seller.cancelOrFault(VOUCHER_ID) - - const receipt = await txOrder.wait() - - let parsedEvent = await findEventByName(receipt, 'LogVoucherFaultCancel', '_tokenIdVoucher') - console.log('parsedEvent'); - console.log(parsedEvent); - +(async () => { + let voucherKernelContract_Seller = new ethers.Contract( + contracts.VoucherKernelContractAddress, + VoucherKernel.abi, + seller + ); + + let txOrder = await voucherKernelContract_Seller.cancelOrFault(VOUCHER_ID); + + const receipt = await txOrder.wait(); + + let parsedEvent = await findEventByName( + receipt, + 'LogVoucherFaultCancel', + '_tokenIdVoucher' + ); + console.log('parsedEvent'); + console.log(parsedEvent); })(); async function findEventByName(txReceipt, eventName, ...eventFields) { - - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] - - const resultObj = { - txHash: txReceipt.transactionHash - } - - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - return resultObj - } + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; + + const resultObj = { + txHash: txReceipt.transactionHash, + }; + + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + return resultObj; } + } } //EXAMPLE @@ -48,4 +55,4 @@ async function findEventByName(txReceipt, eventName, ...eventFields) { qty: '10', txHash: '0x8cfa03728d03dfb868e01caf3081f29f5f30d0173fbc191166ac9289275ff804' } - */ \ No newline at end of file + */ diff --git a/testUserInteractions/seller_requestCreateOrder.js b/testUserInteractions/seller_requestCreateOrder.js index 7d906dc2..3a3b5a86 100644 --- a/testUserInteractions/seller_requestCreateOrder.js +++ b/testUserInteractions/seller_requestCreateOrder.js @@ -1,53 +1,64 @@ - -const Cashier = require("../build/Cashier.json"); -const helpers = require('../testHelpers/constants') +const Cashier = require('../build/Cashier.json'); +const helpers = require('../testHelpers/constants'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { SELLER_SECRET, contracts } = require('./config'); - -const seller = new ethers.Wallet(SELLER_SECRET, provider); - -(async() => { - let cashierContractSeller = new ethers.Contract(contracts.CashierContractAddress, Cashier.abi, seller) - const sellerDepoist = helpers.seller_deposit; - const qty = 50 - const txValue = ethers.BigNumber.from(sellerDepoist.toString()).mul(qty) - - let txOrder = await cashierContractSeller.requestCreateOrder( - helpers.ASSET_TITLE, - helpers.PROMISE_VALID_FROM, - helpers.PROMISE_VALID_TO, - helpers.product_price, - sellerDepoist, - helpers.buyer_deposit, - qty, - { value: txValue.toString(), gasLimit: 4600000 }); - - const receipt = await txOrder.wait() - - let parsedEvent = await findEventByName(receipt, 'LogOrderCreated', '_tokenIdSupply', '_seller', '_promiseId', '_quantity') - console.log('parsedEvent'); - console.log(parsedEvent); -})(); +const {SELLER_SECRET, contracts} = require('./config'); + +const seller = new ethers.Wallet(SELLER_SECRET, provider); + +(async () => { + let cashierContractSeller = new ethers.Contract( + contracts.CashierContractAddress, + Cashier.abi, + seller + ); + const sellerDepoist = helpers.seller_deposit; + const qty = 50; + const txValue = ethers.BigNumber.from(sellerDepoist.toString()).mul(qty); + let txOrder = await cashierContractSeller.requestCreateOrder( + helpers.ASSET_TITLE, + helpers.PROMISE_VALID_FROM, + helpers.PROMISE_VALID_TO, + helpers.product_price, + sellerDepoist, + helpers.buyer_deposit, + qty, + {value: txValue.toString(), gasLimit: 4600000} + ); + + const receipt = await txOrder.wait(); + + let parsedEvent = await findEventByName( + receipt, + 'LogOrderCreated', + '_tokenIdSupply', + '_seller', + '_promiseId', + '_quantity' + ); + console.log('parsedEvent'); + console.log(parsedEvent); +})(); async function findEventByName(txReceipt, eventName, ...eventFields) { + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; + + const resultObj = { + txHash: txReceipt.transactionHash, + }; - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] - - const resultObj = { - txHash: txReceipt.transactionHash - } - - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - return resultObj - } + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + return resultObj; } + } } //EXAMPLE @@ -60,4 +71,4 @@ async function findEventByName(txReceipt, eventName, ...eventFields) { qty: '10', txHash: '0x8cfa03728d03dfb868e01caf3081f29f5f30d0173fbc191166ac9289275ff804' } - */ \ No newline at end of file + */ diff --git a/testUserInteractions/withdraw.js b/testUserInteractions/withdraw.js index 112ee13e..2f6736d7 100644 --- a/testUserInteractions/withdraw.js +++ b/testUserInteractions/withdraw.js @@ -1,70 +1,89 @@ const axios = require('axios').default; const process = { - env: { - API_URL: 'http://localhost:3000' - } + env: { + API_URL: 'http://localhost:3000', + }, }; const endpoints = { - finalize: '/user-vouchers/finalize', - createPayment: '/payments/create-payment' + finalize: '/user-vouchers/finalize', + createPayment: '/payments/create-payment', }; -const Cashier = require("../build/Cashier.json"); +const Cashier = require('../build/Cashier.json'); const ethers = require('ethers'); const provider = new ethers.providers.JsonRpcProvider(); -const { DEPLOYER_SECRET, contracts, VOUCHER_ID, DB_VOUCHER_TO_MODIFY, SEND_TO_DB} = require('./config'); -const deployer = new ethers.Wallet(DEPLOYER_SECRET, provider); - +const { + DEPLOYER_SECRET, + contracts, + VOUCHER_ID, + DB_VOUCHER_TO_MODIFY, + SEND_TO_DB, +} = require('./config'); +const deployer = new ethers.Wallet(DEPLOYER_SECRET, provider); (async () => { - let cashierContractDeployer = new ethers.Contract(contracts.CashierContractAddress, Cashier.abi, deployer) - - const txOrder = await cashierContractDeployer.withdraw([VOUCHER_ID]); - const receipt = await txOrder.wait() - - let events = await findEventByName(receipt, 'LogWithdrawal', '_caller', '_payee', '_payment') - - for (const key in events) { - events[key]._tokenIdVoucher = DB_VOUCHER_TO_MODIFY; - } - console.log('events'); - console.log(events); - - if (!SEND_TO_DB) return - await sendPayments(events) - -})() + let cashierContractDeployer = new ethers.Contract( + contracts.CashierContractAddress, + Cashier.abi, + deployer + ); + + const txOrder = await cashierContractDeployer.withdraw([VOUCHER_ID]); + const receipt = await txOrder.wait(); + + let events = await findEventByName( + receipt, + 'LogWithdrawal', + '_caller', + '_payee', + '_payment' + ); + + for (const key in events) { + events[key]._tokenIdVoucher = DB_VOUCHER_TO_MODIFY; + } + console.log('events'); + console.log(events); + + if (!SEND_TO_DB) return; + await sendPayments(events); +})(); async function findEventByName(txReceipt, eventName, ...eventFields) { - let eventsArr = []; - - for (const key in txReceipt.events) { - if (txReceipt.events[key].event == eventName) { - const event = txReceipt.events[key] - - const resultObj = { - txHash: txReceipt.transactionHash - } - - for (let index = 0; index < eventFields.length; index++) { - resultObj[eventFields[index]] = event.args[eventFields[index]].toString(); - } - eventsArr.push(resultObj) - } + let eventsArr = []; + + for (const key in txReceipt.events) { + if (txReceipt.events[key].event == eventName) { + const event = txReceipt.events[key]; + + const resultObj = { + txHash: txReceipt.transactionHash, + }; + + for (let index = 0; index < eventFields.length; index++) { + resultObj[eventFields[index]] = event.args[ + eventFields[index] + ].toString(); + } + eventsArr.push(resultObj); } + } - return eventsArr + return eventsArr; } async function sendPayments(events) { - try { - await axios.post(`${process.env.API_URL}${endpoints.createPayment}`, events) - } catch (error) { - console.log(error.response.data); - } + try { + await axios.post( + `${process.env.API_URL}${endpoints.createPayment}`, + events + ); + } catch (error) { + console.log(error.response.data); + } } /** Example events arr @@ -83,4 +102,3 @@ async function sendPayments(events) { _payment: '11000000000000000' }] */ - From 62e5b100fe4354b6eae9c768f446afe95b0af851 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 21 Jan 2021 00:39:46 +0000 Subject: [PATCH 14/22] Add eslint for tests. Fix linting issues in all test files. --- .eslintrc.json | 19 + Rakefile | 11 + package-lock.json | 770 ++++++++++++++++++++-------- package.json | 5 + test/1_test_fullpath.js | 67 +-- test/2_test_fullpath_with_permit.js | 55 +- test/3_withdrawals.js | 82 ++- test/5_pausing_contracts.js | 16 +- test/6_fundLimits.js | 2 - 9 files changed, 693 insertions(+), 334 deletions(-) create mode 100644 .eslintrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 00000000..cd5f4a0e --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,19 @@ +{ + "extends": [ + "eslint:recommended", + "prettier" + ], + "env": { + "node": true, + "es6": true, + "commonjs": true, + "mocha": true, + "truffle/globals": true + }, + "parserOptions": { + "ecmaVersion": 2018 + }, + "plugins": [ + "truffle" + ] +} \ No newline at end of file diff --git a/Rakefile b/Rakefile index a23fe334..a42c06a9 100644 --- a/Rakefile +++ b/Rakefile @@ -4,6 +4,7 @@ task :default => [ :"contracts:compile", :"contracts:lint_fix", :"contracts:format_fix", + :"tests:lint_fix", :"tests:format_fix", :"tests:integration" ] @@ -65,6 +66,16 @@ namespace :contracts do end namespace :tests do + desc "Lint all tests" + task :lint do + sh('npm', 'run', 'tests:lint') + end + + desc "Lint & fix all tests" + task :lint_fix do + sh('npm', 'run', 'tests:lint-fix') + end + desc "Format all test files" task :format do sh('npm', 'run', 'tests:format') diff --git a/package-lock.json b/package-lock.json index ee08afd5..343d8fe3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -126,6 +126,57 @@ "to-fast-properties": "^2.0.0" } }, + "@eslint/eslintrc": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.3.0.tgz", + "integrity": "sha512-1JTKgrOKAHVivSvOYw+sJOunkBjUOvjqWk1DPja7ZFhIS2mX/4EgTT8M7eTK9jrKhL/FvXXEbQwIs3pg1xp3dg==", + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "lodash": "^4.17.20", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + } + } + }, "@ethersproject/abi": { "version": "5.0.9", "resolved": "https://registry.npmjs.org/@ethersproject/abi/-/abi-5.0.9.tgz", @@ -1745,9 +1796,9 @@ } }, "acorn": { - "version": "6.4.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", - "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==" }, "acorn-jsx": { "version": "5.3.1", @@ -1881,9 +1932,9 @@ "integrity": "sha1-UI/Q8F0MSHddnszaLhdEIyYejdM=" }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==" }, "async": { "version": "2.6.3", @@ -2623,30 +2674,13 @@ } }, "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "requires": { - "isexe": "^2.0.0" - } - } + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "crypto-browserify": { @@ -2975,6 +3009,14 @@ "once": "^1.4.0" } }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "requires": { + "ansi-colors": "^4.1.1" + } + }, "errno": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", @@ -3059,78 +3101,53 @@ } }, "eslint": { - "version": "5.16.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", - "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.18.0.tgz", + "integrity": "sha512-fbgTiE8BfUJZuBeq2Yi7J3RB3WGUQ9PNuNbmgi6jt9Iv8qrkxfy19Ds3OpL1Pm7zg3BtTVhvcUZbIRQ0wmSjAQ==", "requires": { "@babel/code-frame": "^7.0.0", - "ajv": "^6.9.1", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "@eslint/eslintrc": "^0.3.0", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^4.0.3", - "eslint-utils": "^1.3.1", - "eslint-visitor-keys": "^1.0.0", - "espree": "^5.0.1", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.2.0", "esutils": "^2.0.2", - "file-entry-cache": "^5.0.1", + "file-entry-cache": "^6.0.0", "functional-red-black-tree": "^1.0.1", - "glob": "^7.1.2", - "globals": "^11.7.0", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^6.2.2", - "js-yaml": "^3.13.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", - "lodash": "^4.17.11", + "levn": "^0.4.1", + "lodash": "^4.17.20", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.2", - "path-is-inside": "^1.0.2", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^5.5.1", - "strip-ansi": "^4.0.0", - "strip-json-comments": "^2.0.1", - "table": "^5.2.3", - "text-table": "^0.2.0" + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "debug": { "version": "4.3.1", @@ -3140,16 +3157,6 @@ "ms": "2.1.2" } }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" - }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", @@ -3164,12 +3171,13 @@ "resolve-from": "^4.0.0" } }, - "mkdirp": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", - "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", "requires": { - "minimist": "^1.2.5" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" } }, "ms": { @@ -3177,37 +3185,71 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "requires": { + "lru-cache": "^6.0.0" + } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "requires": { + "ansi-regex": "^5.0.0" + } }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", "requires": { - "has-flag": "^3.0.0" + "prelude-ls": "^1.2.1" } } } }, + "eslint-config-prettier": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-7.2.0.tgz", + "integrity": "sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==" + }, + "eslint-plugin-truffle": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-truffle/-/eslint-plugin-truffle-0.3.1.tgz", + "integrity": "sha512-mjDM1gD96UknBUSEufgdx5m1x3jkWL3Xn/npSZhOVoTbKk/nkBL7dCcH7xsO6GyAjmjvzdev5o5IA4lKWf9b4g==" + }, "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", "requires": { - "esrecurse": "^4.1.0", + "esrecurse": "^4.3.0", "estraverse": "^4.1.1" }, "dependencies": { @@ -3219,26 +3261,40 @@ } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "requires": { "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } } }, "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz", + "integrity": "sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ==" }, "espree": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", - "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", "requires": { - "acorn": "^6.0.7", - "acorn-jsx": "^5.0.0", - "eslint-visitor-keys": "^1.0.0" + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + } } }, "esprima": { @@ -3917,11 +3973,11 @@ } }, "file-entry-cache": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", - "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz", + "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==", "requires": { - "flat-cache": "^2.0.1" + "flat-cache": "^3.0.4" } }, "file-type": { @@ -3971,19 +4027,18 @@ "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==" }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" + "flatted": "^3.1.0", + "rimraf": "^3.0.2" } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==" }, "follow-redirects": { "version": "1.13.1", @@ -4873,9 +4928,12 @@ } }, "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "requires": { + "type-fest": "^0.8.1" + } }, "globby": { "version": "10.0.2", @@ -6217,9 +6275,9 @@ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=" }, "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" }, "path-to-regexp": { "version": "0.1.7", @@ -6550,9 +6608,9 @@ "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" }, "request": { "version": "2.88.2", @@ -6593,6 +6651,11 @@ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -6631,9 +6694,9 @@ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } @@ -6896,17 +6959,17 @@ } }, "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "requires": { - "shebang-regex": "^1.0.0" + "shebang-regex": "^3.0.0" } }, "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "shelljs": { "version": "0.8.4", @@ -6944,35 +7007,19 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" }, "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "requires": { - "color-convert": "^1.9.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" } } }, @@ -6998,6 +7045,16 @@ "semver": "^6.3.0" }, "dependencies": { + "acorn": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", + "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" + }, + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", @@ -7006,6 +7063,11 @@ "color-convert": "^1.9.0" } }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" + }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -7034,11 +7096,153 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.18.0.tgz", "integrity": "sha512-6CYPa+JP2ftfRU2qkDK+UTVeQYosOg/2GbcjIcKPHfinyOLPVGXu/ovN86RP49Re5ndJK1N0kuiidFFuepc4ZQ==" }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" + } + } + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "requires": { + "flat-cache": "^2.0.1" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", @@ -7049,17 +7253,110 @@ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" + }, "prettier": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", "optional": true }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==" + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "^7.1.3" + } + }, "semver": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -7067,6 +7364,25 @@ "requires": { "has-flag": "^3.0.0" } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "requires": { + "isexe": "^2.0.0" + } } } }, @@ -7372,37 +7688,63 @@ } }, "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/table/-/table-6.0.7.tgz", + "integrity": "sha512-rxZevLGTUzWna/qBLObOe16kB2RTnnbhciwgPbMMlazz1yZGVEgnZK762xyVdVznhqxrfCeBMmMkgOOaPwjH7g==", + "requires": { + "ajv": "^7.0.2", + "lodash": "^4.17.20", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0" }, "dependencies": { + "ajv": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-7.0.3.tgz", + "integrity": "sha512-R50QRlXSxqXcQP5SvKUrw8VZeypvo12i2IX0EeR5PiZ7bEKeHWgzgo264LDadUsCU42lTJVhFikTqJwNeH34gQ==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" } }, "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } } } @@ -7684,6 +8026,11 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -7790,6 +8137,11 @@ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==" }, + "v8-compile-cache": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz", + "integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==" + }, "varint": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz", diff --git a/package.json b/package.json index 67fb41ef..1dbcd19b 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,8 @@ "contracts:format-fix": "prettier --write contracts/**/*.sol", "migrate-dev": "truffle migrate --network=rinkeby", "verify-dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby", + "tests:lint": "eslint test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", + "tests:lint-fix": "eslint --fix test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", "tests:format": "prettier --list-different test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", "tests:format-fix": "prettier --write test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", "tests:integration": "truffle test --network test", @@ -35,6 +37,9 @@ "axios": "^0.20.0", "chai": "^4.2.0", "dotenv": "^8.2.0", + "eslint": "^7.18.0", + "eslint-plugin-truffle": "^0.3.1", + "eslint-config-prettier": "^7.2.0", "ethereumjs-util": "^7.0.7", "ethers": "5.0.4", "mocha": "^8.2.1", diff --git a/test/1_test_fullpath.js b/test/1_test_fullpath.js index a3330de3..08a1d0a9 100644 --- a/test/1_test_fullpath.js +++ b/test/1_test_fullpath.js @@ -496,7 +496,7 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { describe('Refunds ...', function () { it('refunding one voucher', async () => { - const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + await contractVoucherKernel.refund(tokenVoucherKey1, { from: users.buyer.address, }); @@ -513,15 +513,12 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { }); it('refunding one voucher, then complain', async () => { - const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + await contractVoucherKernel.refund(tokenVoucherKey1, { + from: users.buyer.address, + }); + await contractVoucherKernel.complain(tokenVoucherKey1, { from: users.buyer.address, }); - const txComplain = await contractVoucherKernel.complain( - tokenVoucherKey1, - { - from: users.buyer.address, - } - ); const statusAfter = await contractVoucherKernel.getVoucherStatus.call( tokenVoucherKey1 @@ -536,21 +533,15 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { }); it('refunding one voucher, then complain, then cancel/fault', async () => { - const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + await contractVoucherKernel.refund(tokenVoucherKey1, { from: users.buyer.address, }); - const txComplain = await contractVoucherKernel.complain( - tokenVoucherKey1, - { - from: users.buyer.address, - } - ); - const txCoF = await contractVoucherKernel.cancelOrFault( - tokenVoucherKey1, - { - from: users.seller.address, - } - ); + await contractVoucherKernel.complain(tokenVoucherKey1, { + from: users.buyer.address, + }); + await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, { + from: users.seller.address, + }); const statusAfter = await contractVoucherKernel.getVoucherStatus.call( tokenVoucherKey1 @@ -566,7 +557,7 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { }); it('must fail: refund then try to redeem', async () => { - const txRefund = await contractVoucherKernel.refund(tokenVoucherKey1, { + await contractVoucherKernel.refund(tokenVoucherKey1, { from: users.buyer.address, }); @@ -581,12 +572,9 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { describe('Cancel/Fault by the seller ...', () => { it('canceling one voucher', async () => { - const txCoF = await contractVoucherKernel.cancelOrFault( - tokenVoucherKey1, - { - from: users.seller.address, - } - ); + await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, { + from: users.seller.address, + }); const statusAfter = await contractVoucherKernel.getVoucherStatus.call( tokenVoucherKey1 @@ -601,12 +589,9 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { }); it('must fail: cancel/fault then try to redeem', async () => { - const txCoF = await contractVoucherKernel.cancelOrFault( - tokenVoucherKey1, - { - from: users.seller.address, - } - ); + await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, { + from: users.seller.address, + }); await truffleAssert.reverts( contractVoucherKernel.redeem(tokenVoucherKey1, { @@ -636,10 +621,9 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { 'end voucher status not as expected (EXPIRED)' ); - const txComplain = await contractVoucherKernel.complain( - tokenVoucherKey1, - {from: users.buyer.address} - ); + await contractVoucherKernel.complain(tokenVoucherKey1, { + from: users.buyer.address, + }); statusAfter = await contractVoucherKernel.getVoucherStatus.call( tokenVoucherKey1 @@ -653,10 +637,9 @@ contract('Voucher tests - UNHAPPY PATH', async (addresses) => { ); // in the same test, because the EVM time machine is funky ... - const txCoF = await contractVoucherKernel.cancelOrFault( - tokenVoucherKey1, - {from: users.seller.address} - ); + await contractVoucherKernel.cancelOrFault(tokenVoucherKey1, { + from: users.seller.address, + }); statusAfter = await contractVoucherKernel.getVoucherStatus.call( tokenVoucherKey1 diff --git a/test/2_test_fullpath_with_permit.js b/test/2_test_fullpath_with_permit.js index 1d62b860..26e0f654 100644 --- a/test/2_test_fullpath_with_permit.js +++ b/test/2_test_fullpath_with_permit.js @@ -1841,6 +1841,8 @@ contract('Cashier && VK', async (addresses) => { new BN(ORDER_QTY) ); + let tokenVoucherKey1; + before(async () => { utils = UtilsBuilder.create() .ERC20withPermit() @@ -1924,6 +1926,8 @@ contract('Cashier && VK', async (addresses) => { }, 'order1 not created successfully' ); + + assert.isDefined(tokenVoucherKey1); }); it('[NEGATIVE] Should not create order with incorrect price', async () => { @@ -2162,6 +2166,8 @@ contract('Cashier && VK', async (addresses) => { }, 'order1 not created successfully' ); + + assert.isDefined(tokenVoucherKey); }); it('[NEGATIVE] Should not create order with incorrect deposit', async () => { @@ -2709,7 +2715,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2874,7 +2880,7 @@ contract('Cashier && VK', async (addresses) => { } ); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.buyer, users.other2, tokenSupplyKey @@ -2933,7 +2939,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3186,7 +3192,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3278,7 +3284,7 @@ contract('Cashier && VK', async (addresses) => { }); it('Should transfer a voucher', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3329,7 +3335,7 @@ contract('Cashier && VK', async (addresses) => { expectedBalanceInEscrow = new BN(constants.product_price).add( new BN(constants.buyer_deposit) ); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3391,7 +3397,7 @@ contract('Cashier && VK', async (addresses) => { new BN(4) ); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3447,7 +3453,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3474,7 +3480,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3566,13 +3572,8 @@ contract('Cashier && VK', async (addresses) => { escrowAmount: new BN(0), }; - balanceBuyerFromPayment = new BN(0); balanceBuyerFromDeposits = new BN(0); - - balanceSellerFromPayment = new BN(0); balanceSellerFromDeposits = new BN(0); - - escrowBalanceFromPayment = new BN(0); escrowBalanceFromDeposits = new BN(0); cashierPaymentLeft = new BN(0); @@ -3586,7 +3587,7 @@ contract('Cashier && VK', async (addresses) => { it('Should update escrow amounts after transfer', async () => { expectedBalanceInEscrow = new BN(constants.product_price); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3650,7 +3651,7 @@ contract('Cashier && VK', async (addresses) => { constants.seller_deposit ).div(new BN(4)); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3733,7 +3734,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3760,7 +3761,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3887,7 +3888,7 @@ contract('Cashier && VK', async (addresses) => { ).div(new BN(4)); const expectedEscrowAmountPrice = new BN(0); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3955,7 +3956,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3963,7 +3964,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -3990,7 +3991,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -4066,7 +4067,7 @@ contract('Cashier && VK', async (addresses) => { it('Should update escrow amounts after transfer', async () => { expectedBalanceInEscrow = new BN(constants.buyer_deposit); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -4132,7 +4133,7 @@ contract('Cashier && VK', async (addresses) => { constants.seller_deposit ).div(new BN(4)); - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -4217,7 +4218,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -4225,7 +4226,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Old owner should not be able to interact with the voucher', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey @@ -4252,7 +4253,7 @@ contract('Cashier && VK', async (addresses) => { }); it('[NEGATIVE] Transfer should revert if Attacker tries to execute voucher transfer', async () => { - voucherID = await utils.commitToBuy( + const voucherID = await utils.commitToBuy( users.other1, users.seller, tokenSupplyKey diff --git a/test/3_withdrawals.js b/test/3_withdrawals.js index d6eb93da..925e79f5 100644 --- a/test/3_withdrawals.js +++ b/test/3_withdrawals.js @@ -848,7 +848,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -924,7 +924,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1004,7 +1004,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1077,7 +1077,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1155,7 +1155,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1228,7 +1228,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1305,7 +1305,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1387,7 +1387,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1466,7 +1466,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1645,7 +1645,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1704,7 +1704,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1767,7 +1767,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1823,7 +1823,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1884,7 +1884,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1939,7 +1939,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -1999,7 +1999,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2064,7 +2064,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2126,7 +2126,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2139,13 +2139,8 @@ contract('Cashier withdrawals ', async (addresses) => { 'ETH - TKN [WITH PERMIT]' + `${i === PAUSED_WITH_PERMIT ? PAUSED_LABEL : ''}`, async () => { - let balanceBuyerFromPayment = new BN(0); let balanceBuyerFromDeposits = new BN(0); - - let balanceSellerFromPayment = new BN(0); let balanceSellerFromDeposits = new BN(0); - - let escrowBalanceFromPayment = new BN(0); let escrowBalanceFromDeposits = new BN(0); let cashierPaymentLeft = new BN(0); @@ -2212,13 +2207,8 @@ contract('Cashier withdrawals ', async (addresses) => { escrowAmount: new BN(0), }; - balanceBuyerFromPayment = new BN(0); balanceBuyerFromDeposits = new BN(0); - - balanceSellerFromPayment = new BN(0); balanceSellerFromDeposits = new BN(0); - - escrowBalanceFromPayment = new BN(0); escrowBalanceFromDeposits = new BN(0); cashierPaymentLeft = new BN(0); @@ -2305,7 +2295,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2378,7 +2368,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2457,7 +2447,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2527,7 +2517,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2602,7 +2592,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2676,7 +2666,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2754,7 +2744,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2837,7 +2827,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -2917,7 +2907,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3072,7 +3062,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3165,7 +3155,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3262,7 +3252,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3352,7 +3342,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3447,7 +3437,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3537,7 +3527,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3631,7 +3621,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3730,7 +3720,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' @@ -3825,7 +3815,7 @@ contract('Cashier withdrawals ', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Event LogAmountDistribution was not emitted' diff --git a/test/5_pausing_contracts.js b/test/5_pausing_contracts.js index 418f380b..514660d5 100644 --- a/test/5_pausing_contracts.js +++ b/test/5_pausing_contracts.js @@ -253,7 +253,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' @@ -321,7 +321,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' @@ -571,7 +571,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' @@ -639,7 +639,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' @@ -882,7 +882,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' @@ -950,7 +950,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' @@ -1192,7 +1192,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' @@ -1260,7 +1260,7 @@ contract('Cashier && VK', async (addresses) => { truffleAssert.eventEmitted( withdrawTx, 'LogAmountDistribution', - (ev) => { + () => { return true; }, 'Amounts not distributed successfully' diff --git a/test/6_fundLimits.js b/test/6_fundLimits.js index ceda586a..6d568b5f 100644 --- a/test/6_fundLimits.js +++ b/test/6_fundLimits.js @@ -18,7 +18,6 @@ contract('FundLimitsOracle', async (addresses) => { contractVoucherKernel, contractCashier, contractBSNTokenPrice, - contractBSNTokenDeposit, contractFundLimitsOracle; let expectedLimit; @@ -44,7 +43,6 @@ contract('FundLimitsOracle', async (addresses) => { ); contractBSNTokenPrice = await BosonToken.new('BosonTokenPrice', 'BPRC'); - contractBSNTokenDeposit = await BosonToken.new('BosonTokenDeposit', 'BDEP'); await contractERC1155ERC721.setApprovalForAll( contractVoucherKernel.address, From b62c7aa0aa0c0df2d0ea4b6935d69525ca17067e Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 21 Jan 2021 00:40:36 +0000 Subject: [PATCH 15/22] Rename migrate and verify scripts. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 1dbcd19b..89c6733c 100644 --- a/package.json +++ b/package.json @@ -12,8 +12,8 @@ "contracts:lint-fix": "solhint contracts/**/*.sol -w 27 --fix", "contracts:format": "prettier --list-different contracts/**/*.sol", "contracts:format-fix": "prettier --write contracts/**/*.sol", - "migrate-dev": "truffle migrate --network=rinkeby", - "verify-dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby", + "contracts:migrate:dev": "truffle migrate --network=rinkeby", + "contracts:verify:dev": "truffle run verify ERC1155ERC721 VoucherKernel Cashier BosonTokenPrice BosonTokenDeposit --network rinkeby", "tests:lint": "eslint test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", "tests:lint-fix": "eslint --fix test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", "tests:format": "prettier --list-different test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", From 542957ca988a127eae46ece237ef8f4b0c5b7332 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 21 Jan 2021 15:15:38 +0000 Subject: [PATCH 16/22] Update README. Add guides for setting up development machine. --- .solcover.js | 46 ++--- README.md | 178 +++++++++++++----- Rakefile | 68 ++++--- config/accounts.json | 14 ++ docs/assets/banner.png | Bin 0 -> 379084 bytes docs/assets/banner.psd | Bin 0 -> 2906025 bytes .../assets/exchange-diagram-simplified.png | Bin docs/contracts/deployment.md | 26 +++ .../contracts/overview.md | 4 +- docs/setup/linux.md | 83 ++++++++ docs/setup/osx.md | 79 ++++++++ package.json | 2 +- testHelpers/users.js | 51 ++--- 13 files changed, 403 insertions(+), 148 deletions(-) create mode 100644 config/accounts.json create mode 100644 docs/assets/banner.png create mode 100644 docs/assets/banner.psd rename assets/boson_exchange_diagram_simplified.png => docs/assets/exchange-diagram-simplified.png (100%) create mode 100644 docs/contracts/deployment.md rename doc_contracts.md => docs/contracts/overview.md (95%) create mode 100644 docs/setup/linux.md create mode 100644 docs/setup/osx.md diff --git a/.solcover.js b/.solcover.js index 1d1afa35..2d6d03b3 100644 --- a/.solcover.js +++ b/.solcover.js @@ -1,40 +1,16 @@ +const fs = require('fs'); + +const privateKeys = + JSON.parse(fs.readFileSync('config/accounts.json'))["private_keys"] +const accounts = Object.entries(privateKeys) + .map(entry => ({ + secretKey: `0x${entry[1]}`, + balance: '0x8ac7230489e80000' + })) + module.exports = { port: 8555, testCommand: 'mocha --timeout 5000', measureStatementCoverage: false, - providerOptions: { - // Default Accounts with preminted 10ETH - accounts: [ - { secretKey: '0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0x823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0xd6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0xf41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543', - balance: "0x8ac7230489e80000" - }, - { secretKey: '0xfac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186', - balance: "0x8ac7230489e80000" - }, - ] - } + providerOptions: { accounts } }; \ No newline at end of file diff --git a/README.md b/README.md index c4a89835..ae38cb27 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,162 @@ -# Core prototype +[![banner](docs/assets/banner.png)](https://bosonprotocol.io) -Code repository for Boson Protocol smart contracts. The description of the -contracts and process can be found in [doc_contracts.md](doc_contracts.md). +

Boson Protocol Contracts

-## Getting started +Smart contracts for Boson Protocol. -Note: all commands below are run from the project root. +**Table of Contents** -To install dependencies: +- [Local Development](#local-development) +- [Testing](#testing) +- [Code Linting](#code-linting) +- [Documentation](#documentation) +- [Contributing](#contributing) +- [License](#license) + +## Local Development + +### Prerequisites + +For local development of the contracts, your development machine will need a few +tools installed. + +At a minimum, you'll need: +* Node (10.23.0) +* NPM (> 6) +* Ruby (2.7.2) +* Bundler (> 2) + +For instructions on how to get set up with these specific versions: +* See the [OS X guide](docs/setup/osx.md) if you are on a Mac. +* See the [Linux guide](docs/setup/linux.md) if you use a Linux distribution. + +### Running the build + +We have a fully automated local build process to check that your changes are +good to be merged. To run the build: ```shell script -npm install +./go ```` -To compile all contracts: +By default, the build process fetches all dependencies, compiles, lints, +formats and tests the codebase. There are also tasks for each step. This and +subsequent sections provide more details of each of the tasks. + +To fetch dependencies: + +```shell script +./go dependencies:install +``` + +To compile the contracts: ```shell script -npm run compile +./go contracts:compile ``` +## Testing + +### Unit Tests + +All contracts are thoroughly unit tested using +[Truffle's JavaScript testing](https://www.trufflesuite.com/docs/truffle/testing/writing-tests-in-javascript) +support. + To run the unit tests: -1. Ensure Ethereum is running locally on port 8545. This can be achieved using - Ganache, `ganache-cli` or `etherlime ganache`. -1. Copy your 12 word mnemonic to `.secret`. Create the file if it doesn't - already exist. -1. Execute the unit tests: +```shell script +./go tests:unit +``` + +By default, the build system automates starting and stopping +[Ganache](https://www.trufflesuite.com/docs/ganache/overview) on a free port in +the background ready for each test run. + +If instead, you want to run the tests against an existing node, Ganache or +otherwise, create a JSON file creating accounts in the same format as +`config/accounts.json` and execute: ```shell script -npm run test:unit -``` +./go "tests:unit[,]" +``` + +### Coverage + +We use [solidity-coverage](https://github.com/sc-forks/solidity-coverage) to +provide test coverage reports. -Note: currently, the unit test suite will fail the second time it is run against -the same Ethereum instance. As a reuls, you'll need to reset between test runs. +To check the test coverage: -To run the integration tests, follow the instructions in -[`testUserInteractions/README.md](testUserInteractions/README.md). +```shell script +./go tests:coverage +``` + +`solidity-coverage` runs its own instance of Ganache internally, as well as +instrumenting contracts before running. + +### Interaction Tests -## Contracts initialization - -[Migrations script](./migrations/2_deploy_contracts.js) for Truffle also does -this initialization: +To run the interaction tests, follow the instructions in the +[interaction tests README.md](testUserInteractions/README.md). -- ERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true') -- ERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address) -- VoucherKernel.setCashierAddress(contractCashier.address) +## Code Linting -## Deployed contracts +Both the contracts themselves and the tests are linted and formatted as part of +the build process. -Contracts are deployed on Kovan testnet at addresses: - -ERC1155ERC721: 0xF3aA8eB3812303F6c86c136557bC23E48d634B58 -VoucherKernel: 0x1806312211bd1521430C953683038d6263580feE -Cashier: 0xaaf749c8e6e37b51410F1810ADcAEED18d0C166F +For the contracts, we use: +* [solhint](https://protofire.github.io/solhint/) for linting +* [prettier-solidity](https://github.com/prettier-solidity/prettier-plugin-solidity) + for formatting -The frontend is currently pointing to Kovan deployment. +For the tests, we use: +* [eslint](https://eslint.org/) for linting +* [prettier](https://prettier.io/) for formatting + +To lint the contracts: + +```shell script +./go contracts:lint +``` + +This will check if the linter is satisfied. If instead you want to attempt to +automatically fix any linting issues: + +```shell script +./go contracts:lint_fix +``` -Contract are also deployed on Ropsten testnet at addresses: - -ERC1155ERC721: 0xe7028d66222aD1AfEB0098956347A6284443bd16 -VoucherKernel: 0xa93f95bf0039CE30957b77A6638e2e273598D576 -Cashier: 0x014b8baF57bA77FaE23075aa93c2B768eeb440bD +To check the formatting of the contracts: -## Progress +```shell script +./go contracts:format +``` -See the -[project board](https://github.com/bosonprotocol/bsn-core-prototype/projects/2). +To automatically fix formatting issues: -## Coverage +```shell script +./go contracts:format_fix +``` -Test coverage is executed by running the following command: +Similarly, for the tests, to perform the same tasks: -``` -npm run coverage +```shell script +./go tests:lint +./go tests:lint_fix +./go tests:format +./go tests:format_fix ``` + +## Documentation + +For an overview of the contracts and their responsibilities, see +[Overview](docs/contracts/overview.md). + +## Contributing + +TODO: Add contribution notes. + +## License + +Licensed under [LGPL v3](LICENSE). diff --git a/Rakefile b/Rakefile index a42c06a9..4ce82a1f 100644 --- a/Rakefile +++ b/Rakefile @@ -6,12 +6,12 @@ task :default => [ :"contracts:format_fix", :"tests:lint_fix", :"tests:format_fix", - :"tests:integration" + :"tests:unit" ] namespace :ganache do desc "Start ganache on provided port, default 8545" - task :start, [:port] do |_, args| + task :start, [:port] => [:'dependencies:install'] do |_, args| args.with_defaults(port: 8545) puts "Starting ganache on port #{args.port}..." @@ -26,7 +26,7 @@ namespace :ganache do end desc "Stop ganache on provided port, default 8545" - task :stop, [:port] do |_, args| + task :stop, [:port] => [:'dependencies:install'] do |_, args| args.with_defaults(port: 8545) puts "Stopping ganache on port #{args.port}..." @@ -38,72 +38,90 @@ namespace :ganache do end end +namespace :dependencies do + desc "Install all dependencies" + task :install do + sh('npm', 'install') + end +end + namespace :contracts do desc "Compile all contracts" - task :compile do + task :compile => [:'dependencies:install'] do sh('npm', 'run', 'contracts:compile') end desc "Lint all contracts" - task :lint do + task :lint => [:'dependencies:install'] do sh('npm', 'run', 'contracts:lint') end desc "Lint & fix all contracts" - task :lint_fix do + task :lint_fix => [:'dependencies:install'] do sh('npm', 'run', 'contracts:lint-fix') end desc "Format all contracts" - task :format do + task :format => [:'dependencies:install'] do sh('npm', 'run', 'contracts:format') end desc "Format & fix all contracts" - task :format_fix do + task :format_fix => [:'dependencies:install'] do sh('npm', 'run', 'contracts:format-fix') end end namespace :tests do desc "Lint all tests" - task :lint do + task :lint => [:'dependencies:install'] do sh('npm', 'run', 'tests:lint') end desc "Lint & fix all tests" - task :lint_fix do + task :lint_fix => [:'dependencies:install'] do sh('npm', 'run', 'tests:lint-fix') end desc "Format all test files" - task :format do + task :format => [:'dependencies:install'] do sh('npm', 'run', 'tests:format') end desc "Format & fix all test files" - task :format_fix do + task :format_fix => [:'dependencies:install'] do sh('npm', 'run', 'tests:format-fix') end - desc "Run all contract integration tests" - task :integration do - Ganache.on_available_port( - allow_unlimited_contract_size: true) do |ganache| - puts "Running integration tests against ganache node listening on " + - "#{ganache.port}..." - + desc "Run all contract unit tests" + task :unit, [:port, :account_keys_file] => + [:'dependencies:install'] do |_, args| + run_unit_tests = lambda do |port, account_keys_file| sh({ "HOST" => "127.0.0.1", - "PORT" => "#{ganache.port}", - "ACCOUNT_KEYS_FILE" => "#{ganache.account_keys_file}" - }, 'npm', 'run', 'tests:integration') + "PORT" => "#{port}", + "ACCOUNT_KEYS_FILE" => "#{account_keys_file}" + }, 'npm', 'run', 'tests:unit') + end + + if args.port + puts "Running unit tests against node listening on #{args.port}..." + run_unit_tests.call( + args.port, + args.account_keys_file || 'config/accounts.json') + else + puts "Running unit tests against node listening on random available " + + "port..." + Ganache.on_available_port( + allow_unlimited_contract_size: true) do |ganache| + run_unit_tests.call(ganache.port, ganache.account_keys_file) + end end end - desc "Run test coverage for contract integration tests" - task :coverage do - puts "Running test coverage for contract integration tests..." + desc "Run test coverage for contract unit tests" + task :coverage => [:'dependencies:install'] do + puts "Running test coverage for contract unit tests..." sh(['npm', 'run', 'tests:coverage']) end end diff --git a/config/accounts.json b/config/accounts.json new file mode 100644 index 00000000..5171c28c --- /dev/null +++ b/config/accounts.json @@ -0,0 +1,14 @@ +{ + "private_keys": { + "0xd9995bae12fee327256ffec1e3184d492bd94c31": "0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8", + "0xd4fa489eacc52ba59438993f37be9fcc20090e39": "0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f", + "0x760bf27cd45036a6c486802d30b5d90cffbe31fe": "0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2", + "0x56a32fff5e5a8b40d6a21538579fb8922df5258c": "0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a", + "0xfec44e15328b7d1d8885a8226b0858964358f1d6": "0x823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2", + "0xda8a06f1c910cab18ad187be1faa2b8606c2ec86": "0xd6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3", + "0x8199de05654e9afa5c081bce38f140082c9a7733": "0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a", + "0x28bf45680ca598708e5cdacc1414fcac04a3f1ed": "0xf41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25", + "0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a": "0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543", + "0x87e0ED760fb316eeb94Bd9cF23D1d2BE87aCe3d8": "0xfac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186" + } +} diff --git a/docs/assets/banner.png b/docs/assets/banner.png new file mode 100644 index 0000000000000000000000000000000000000000..2a3ef41e6d4094bf05a40c720fcc9d3fb0c8d78c GIT binary patch literal 379084 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

}|uA|NRAXWlOrhn5-?R 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 z zm-X1qZn3gz2gQ+6S0AY2!4MC$gy|L+iDC#kg#aQ%cCx9B_Fh*gidjacR7oT$x#tVp zP*?kK=-lWCNxI~&b=;uj=zMRFug@7420VF48q_Y_l)oy`ou#c0B2S}6kCtPhPhL?5 zM6MH2h1yAv&zYx?sHO@lAuXLfjcl?|6l z#k;=wQn9RR)bW-~RqVa{HsriN*2}4bhLkK`<^14__IXeDQ2b&=QyqLUF{v-Ypi

wq7t3rUfP$0@OrU#^T$F-W0ozEng+nPZ$GE@_onr)pvQf_JSK z=3~moIij5de}vtNnuGb9haik%Ag7aQKVaYA|62%j%DBLd<-XNVQ+Wu$k!Sp(RanUx z+0U>(NMRm)nVHF)+7dPNN$-2OcULdV)=v|{YU$y-MefXG%l#HrSG=O{E%6mLn=QZ)k6Vlo@g{~yP^-y?n@?pGVfVtZfz=*Y z?zU^;1F+&*7-~$Bieb6`s4vzTHC=mS*|)lV`I)iLvU#l7pVdwfXn)K+P?MeHDT+#( ze8+?z8n$)Y!AFKg4t6H8u3@yf{CZ)w0(3}X7B7z;PNiyj9XH~=aT5`>wi0O(bYzkG z*ys@t-?#KtX_`^3TY9C)a$W`w^Q#ALKKr;I&dr`{9sB*k8)C8frOaa=wRqRNlr=1?0BKLkb zL@vY$^HOQo@8MK&PD;JGWgw&P3-NdTT;c1+3;oTzFZTQ15XRHag0Q`j-Tz#$rMM!a z&f%HE@>Awl0*AMVSxeM4%SSExg(hU)qe}D9S{&pBn#XJ3_j&SA-6)=Cg|XulL`4J! zL|YPx(DYCIC?YQl1-6XGhJA0ChtCwky|-+W^+=_kW~mHw`G=3?clx0M;agdWxXb`_ z3C}6+(!(}eH2#uEnng5)7q z<2IM&lC@1>OC{;GC}EhAWTuv~#!r8hc>{etQygYkvk{+agwwD7ZRw$GxrSWTI5z!n zO2V;64G|ehM)=;Bkioc(8a;Zr{##@r#{Yx?UdxNQ@u^n2nIReUtj2eO zq(XOWPfeIICXn^JqEET$uE&Z z@zn7|Q}|%Hfj3b>sF+Q$CGfCy&MycrF6Paw$)1}~L4XjcQXc3`28j=l-$J87Kk6SC zs~z}fgodOx`4cO^2II-~T57@Q?cLOf80oqvwL-BVAlpI-LmC0HF`c_I6XylaN6*>Z z8)uyf|H5;J%HGv3c(sD^EY^k)67izczXi2q@8|O&-nt;eUY`nPMI}M8>nltgE^&(n zPFNmbB#T10)^9#Xjsnd!WQ){coD+jTs*21ujh!eo!WZ)@IcuWhv`Q>Qrg`ZW!y&91 zmUO#UEER^*9(<8(DaXE`i8($#(>&!>;t2yGU2r}Wd74JbgUTGaejzuIih`Ii@sR|8 z8uB7PZQXJB{N&Iqw;cC^$^xx4b!M#gTYMW#$`w7d@Dxq8=N66(Vi^K^sTyE6+4wIV zXE!ytx{G7sbxz3YcHt}6bPFVN{mzRQ%a?7{(7|3?Dz~+XFuHTWW@Qy*l?=S^r;LkF z5pg#Xc~LAqs5V2~p$VA8xnpBQ?IE)SMf>{|x}j!x4PUhHLc;l4(3fA5+fg!(c=PYQ z{5FA-|4#nGYaXZ5%z`oG%ouMM;>1*eop(Fx4zGKyU|f0SAjqpJ%j)pr!qTf$qeAD` zs$VpTrM5!5_xA}*>aiAAel8y)dNL$kEvbP`ITrsNp68a|KVC6sQx|Q1CR`svMGlpU zV0-lv=mxvkLSEO@C}{TFZjvR#!*Bhl?fa@9(3lL{o=Fzt+WxVkA7#7C$p6vFDm{p%JjH5a7@BqzWxTGyz>~abO z2`p7t=I2+rV!tD!h9vwvZ3iSMF4`E-jqzdY^H1{ZHk7dAqn)2h-6B6YJv(j@+V$%F zpuD^Z`}#e#=S>28BO~|+2=@GbHqGeE;t$cYA9>yevD)W|6_`5B9FoE3>w{!-IulnK zdm0$~uLR>!$OUI21i?Veky8eblJmm=?kOZE`j}h&_w<0G+4bP5d0VoSAikDxWkEEP zAyBe576J)@n4uMV<&R=#wEQ24FTyX_dT&a8vE@B4U$)(Bf__9QT1N3OrI(gK%B7Zi zee7|{(GxSm?;+txl)q+HB|r)(@AqB^AsVa%~hVQjJ+_Gu9oZNYKAp;>wE(&Qk+MY2dtX3=U!8HdK$!-W^CSIA*t_a+9f+?Zz^(z5;4l zWA%Ucy}C4T#r?aT$a~Ikv)R(!(Yxj#lx~4iv|METmOAi2Horb72JmExUIid&vF>{Q zgbRieOfgImtgP%py%nEhI5zqae(->qdG%V^4Vp?VVPma^PS7}*(`uMsJ?QizHQ5eF**)sZSzXp-2wfHo~ zDSY_4*S-{9lKMq1lKNfI#GUHSi*ghN>`xF6Fqf@f_+e^{ih14K`#(;!n{G^RjJRJc zWd8ij$!v9@)nU0vw&FhS*0%wzAud?kkuZ%J>JLoNDYo4C^ejhT&!5E@HFh6(8ZC~$ z1qf`uUXuRgjtS8EfM%eGJ2M2QKmC(UXVe`2m-h=1M3r7HIIaJNXei=`&L}%}@q^;_ zkz`k&Fo>-ifgZPtME~~dnqi3g1u#g|YvK-{U+z!Gv zdF1#=xInKL|M<}BN2t*unqML5LYNlOyDCQz`9a!wC@y^}{?jXkbS|j9C4@G*Va(;9 z@H}z;&_hFr=+h(Biy<6(T)qLC;oT zfn{9mNJe~Z9`$CLqV$6Ct=hgp5<5<3m)pL9B+urXnS8te7DC*u1i^7|GEagCJ8E-Y zq0b6NGQ4YH8N=cEspLZod6vf!>Td}#-s&%Td`L`1@!4A6>3@b5@Ue1ej(@C^iiJfi zQoiIVS9)^(UT<8LLWAF5vPdsyI!%mipfb8Tl;uQ!Fyc=$1?D$6A)mI!_EFtH0{5Lg zmus$zJwP5R^3_u1w_-T+T9A&~P@~{hWm;8%`)mHHG5M-Rlb^7G(O>fMn;j+fc;ICc zp4|#hP&CQ0oyn4WVOSDiJGc}$sKnBRC?9ocr+J&x&G_P zu&qNDTdXOJNnop8Xkm=MCJV z`^s_Dy2N^2P?vHhR=)7xuQLLH~-#kR3xP6DZr1+Kb!6S*t-pn0P6jqm} ze|7+Y-*@sHuJ6m6ror2+)dJKzX(5y=INj_p>Jc zv-J%ClT4hvQ$irIhDp;&di)3`1(B(Yyp!pSBX+6fPqO@q8kdTr+c}5%a)WFJ-m1=0 zsERI!r`|#}T^J#-J>A;+9cr`C-mg}j5AIpFr7=P}iKDI@8)&bpZyYex7yp*;{W=;Z zi57U&^Z7;&9@`UTYYjFo-WleZ2(8Mox0g_^3-O-#M>ZQxyAtC+=0%jtJ`}fYf9}9p z%ANo!XN1X8D70fg>tdrVP z+6kcuD0I*4zbOvHem8)Zh;PbEr?h?x&zZQh2v3Hq z1qC?tk%6LQ{@QIhRw)l5X@jEr*N2l6bOaKt8aCy>*7QAv(q(Bn7^t)2lc33+^6Xmudgq-gd9F8~Qjy@^)ynaZf#o zEg;XV3Qkgf+-(VEliE%6YL1H^M{m6LaUm^zTq7SoN^gAMJe_9FjsECZQHhO+tbv9$@XM7*}a|ff6wRV`~6(kx_)b|BV2S_8TB<2PfsRg3s{%} zH>wO;JlgWYGS>?IwNL{ohL%NFi+uiwoj~vv+;jsyO;KL_@Occ=SMZZq_=@}safc4l zQ%_Hk#$)w!`jE;}T3fP+xZR|2kWbl8i!*(C>phbe5GQ95)DAs&{N=6fi@H^H( z?H3u_v#$mwa1WuTyMn+tXnv82gB$NxA=xADL9Yq32Jso`MR~`sF(9P@eG(i}Fw0y8 z!8)$Kd0F+NQz;HRGHxCGYET_i3w3~I)5_J@3zeZYVhumS)9UDqC|JoLG*V_KN{>ig zLiJk^RaH z)Z`zU3Tym|{c5dS@1tK2m9%lC;oM?b0{krXgD`M*nYB!;M#_1LR@kVs;yw3BunxW1 zMZRVu6f@pkow2%knUWrc@NK5R@^`n|y{2!Sn&vu6p1Lc<4s@+c2uY94+fIYND+OKK zJQqFBqGkGd!?FK{fKlwqEfqD^Z)tP@X|@=IMt&Imcz=Gvg^H` zw$C_U`HiI?DRUD;J)Vb149wnm7A#dn>y9`;uX*`Ds#T&;tyi`^bsuqhX9IoG5tXHa z>Ns#ajQl%T*9&i1u|nFizESz0Cj15x=ZiiT_D1jx+|ABMBoSoSfFU6!9zrdoLG7of zKW#%^J~Mb8rCZZY#$h_Fu!rKuGBLx{1U^)s3PpoS4(y`#Vh6bI?Or5IL1=Dy@!X#9 zoieLudy2PZ%7zKlp2p9v>*jt=&?Y>+>9+SO``ka~_x^32%0v9b+xjw;fBc@9@jII5 z@%<5t(R#O-FaDa|AG`BAREMAPYXa(=1Kdb`Q3Q6 z=E{9#-+0cyw+r)O)GWrZ_<6gG>f|Tqo%5}dQQ_JSo!YusCw5CY z^l6@6ie5jMxA2r+d8*rwAenu8{+Y0uULC{9T1Q!t+VIrs;oPy$9jN`Jz%lbnqY7Es z{DC?$nzXMB?<#ak zUMBGJh9X!fGq@I*;Pyy9vluk+9US}y>%u0iG;vuEB{p>ty+H>L)c$R>DqquIsn9$X0`GNp-9X$*ChQZ}`cy0sx08zQK1qh_Y~aKf8H zI$0ATly11UHcT_AFB#Mxt&#-zN{jOVUJRv+qAzckpi)ebR5TdSP#Z4-nv=ph8&Isx zpwD`JkI%0pJIaXzAJjAEZ-Muw%UiHb_0(cwL1k>{5hHY$hR7IVBwh(J@T)nOC@@%e z_y{jexazy1(yOZw)t>l7mJ|p6#ZEq``E}m8*J>^#*Z0q}P2X&6WMi^-{+v^Y>eWGM zfJz|*h*)yqn0F{lY2UvG{s;pPP3b$|10WvD%Kkw8-Z`lAmJoJGr;jG9A@?L8d%rFJ zX1j(>DvcVp20EyGMN=pXhjvj&_X*GfBDYlcXg<%v{=5F@G4gz?Qkvthi+bpiteTU6 z__HOH@K>3aleT;s;_SrzLibD~V+h2ocNQg22BIKUR5|%&oS?1_e&e;c;NEVx1{(!g zUjBtY2#6vms0^l!JE*JwY^wA8u>>99S)c7%>|Xa&_;T~Dzy3G_4#rdDc;xS^5jC~| z7{pSP^rJZ zSxB=G*GPHfHXRv26r6uNr|_5$;qZQ+?jt}L_|JuAXpT)nig%AxYp@^-}krK zYbWyW_I@zaV6RQ}nDwvU)TQ20TQ}FG>j^OU=C9PS4fLve_49DQf>+j^y?vVLHdhvh z#6|iD_g8LPa=*S^$H}R<&G2&1BLwt4+8?@qU$tc@@mxu{4JN|`|9J@2BIQ1iLR8Y{ zj-*aMZMzLfuX~H3EHJkC1Z${9JULPv(*A=GuL6Nv5he@m_9!OI8ZepYc#MmKzmr6; zbSh7FJDKg^f;gKm6mp(v8G^x9u?dei!ah!0X865U6rl=&Dg)=dDR5>BocEn+Mkc>G z>Dx)JjAkZAaO=$+eNa`<()4C@Pb&DYL*=3p|52bp2ja*r2P-o(IM%}c%9x2W9JE@^ z{;d*xU82$ayO6e~R`A+-)E6w6(V`2rYlB((g%BReeu*+c$uZ=Qe|RTJn{>tR*xsBZp%Vhy>&IR7Ik?od%iI zs__OhoK9Wc6MLzh#Lb4ZxuQ@%x6Hu;zFws09x3>US?+|S`X6EZ8_1otkpfdw(euZf z?TDzKd}Rt_gcY7ivoKR?0DzR(AZLiP zVqC3U=>T9W5!TYOmLYxju1cx{MSW{@eQa9HKjqUivdP|HfK8~|MJFz=3M6R!%+n_u5}2#)@#*08&> zx_T6#AucB-c1V(uuEfeI zrFK-%-FvUeqHZ8S83JJKRM@fN=kh=mPqD|07;ScTiFqn5GV~|86~n>|V6*DPe&Y+d zs)_;;;#z-r4M?<9si{?l_v2vW8}0 z)}GAbhw3LgUB}SBBtDxaS&oN)xizO$rxFc~PY;r_Niuqw(8O!L!wFX;qBR*Kr}}*; zd&gJ{bx=XWn}A+E6l=#^?9%gPP4>`mTH2&;SqUwuf&qHU4tK;LSQv8Ux%Ul%m`u>| zo->m6aQNduj$+|;@m|m6P9Av0ri>o;@F!pfPc z{uy z`FTN{D&e-2Uk3R(LClS4p$ogTiZ8gOmT-n=L41)?r)|R0^5|iiSOKOnv4a#NfaiUT z$K>lM5@M?QG}?did`JV45iB2szSggmT*kc`W$@>GVudh ztNPOFSz4+^mEvlJ+WKX^XB$W~6w&(!s$5ucNky?gZFl$~pqgwIV-Vyan z!_9CwMwx1;!#V)2g~Se-G<}OjAwygzMH8s%1@>)FLmLc$W00A4jdPz;^x<}~h8SH9 z)&jkgx~cYbrW;@P;I(;GhdRlX9k=d6fYJKd-Y%xCXP8>PZy)cEx;GH3*9>1aJB$L+ z*`fgQwTBC+Q;m)usGN8B>&SbHh_ra}BZ>ROkj?JUoq)d{1K!}#ZWd;HlbVqpU~=jO zmb17{aBdK=xO1m8N(IeO`N%bLi|By)ynXPn_*Tn&Uj5N~cO6)Vo924o$tr)D)?f-h zCC?T^EClUI9jfSe(%cY5{dTe37i-WrR_LYqBdp0f!qq({HV15|rc|5r>_*lhII;dGHx)!F|8h1O~)3dCza!$Pm$Q(m^=_wJAoXlVii zAY?W(24-IIt4K%!moh~!JLhwvrqPy=6&jsQ)$4xctxSNiJ_heKG*j!D?eFF)B`KTa zd1kM_7Aszb3-hD$;Ro`s{K<1Vpu|LCOU<}GF<}T?!W()-8gxqyRi_W1Yn1z2mY7^Z zERnZ1J-%!pA^u>mNcQ+{93kR|=ENB=gjkMGraF-9EHAOvr;+8ReeMG8tqwDh^Z%kpTwEYPuN4W4*WbLd!yBip;=USM+RaPO>2F!UWum+$6EzetGqoBSJ zBfeEA6Q>56qurXCXj3%Cvgg9RhyXyKSx`MzN+|+#GhAVl1ciH{=D%DjfIL~qVmVRA zzL3^eCDj-_1GejqYhb}X4DxIjoE~OD(ZL+Au$7y#ODy2bK_TzZfqeg_=Gd>D8|=y( z=}KctX0LS5#Y&sVxWzv^d-ddMlo(So&xFzpkx}bN_H=uYynCf3oj0~OJPTrO{*>-*1c7;nXxH{otMZAin`@O+B z>D%K>S8{vJ=94yvL|@{RMgLQJ(qosWKX_&Pwc2~|#6(i30Dk9#f}ud}VsW7f?|+mZY-5F6Ne^cEU}_hF6b6(<*hYm*Dc*IB z?x~(D!yX=nwSSA+MY2;dlIEL%n966Z5sLErQ4DZQ*c!BQ8WTIhycN8^?NWqo_u$6k^;g77> zjko+Yshq+3d_+6@R+$jRoXDlcxCSRMuzs^Mv5tu=(>SL4OxpC#y#aHxlMab?71TWE zV?U$^%aj;op4?#8lBC0i$1Lb;JitagpnAK**%N!{y#WvsGd z*i{sibBi#gz0gZH1ZXIZ?A#1|@HJ~N=b>2QP%K{&x)M|oo&N@-PlZB)tHJ@qxHW?E za0x8G`@k4*+q#Wg(^Zh@7GED!RZw-rS5_$)OirHumEX!GHo#R=q@H>$fo|28b>TN} z#v$37oSXyl+iip2ksNaFInQUKf#BW(fq!#VT3CLoN6kMS#9}9Gu{lX1w!a=N@@Azs zeA;DfA`f14nR@-cvDw`H0dG~$6^HCp%w3y?IT6M<}`jtT~^Mp(7>hQBIix<5t$W=iKI8==9y2LJa$*(?qBb@K-T*MdWEix z1j?03X_YLwj4nLyDn?X&j?_$w#PysPy4$M6@eWx_9o1whmmLcaO`5W>$i!8l0!3{( zex$w^(wYNplfFOpnf@!?P`)Qr;7BFyt=RTFi$IgtiB`_<>fb`q))u3# zF<}kkr;4AJcoEVMd2Q%iuDAi4Q-XRj$><*|3M*%xDRD8*4(i937fL!tfMox(P(JBI zv>_&-}&?_5v@(@K(BCr$bE1Sp6n z(b0|he1P>DH^)C2$+zn)SNmS25}HU@THSq})C(&!C~L3;vR27J24pZ`IHl&sT?4pm z3O|bT>5l33_d^_HFVcg7GPJJkVo{PFf@B_Rb5M+RaIc6eg=Or2w^v3NZD&E;7JU7K zZI$+*@Bd=~-X4D}z-%lbJl6^30GaPyfJFtx9LBBi|E|ipgM$46VhN!mmaC9=iaz}} z0-R>N^UHMKeOCsIn-A}i(-=VFaa)@-y%U{}3!^2x58{SiwMo~0xz|;MwaAYrTo1dT z&#B5@$46*$P@6gBfUNKvtpeC=g%Xa=;r&s1y7{1<9A%R)gSLnpPtA9fKR95k8rld)XiJ$L`;pF>Wh4 z7Xo zEl}M>s8>e$GR|~U!j+|}9IRz&t7Zc~rYKsvQK$NEI3ep>KVM1Kayd_WHyz&BBTRqaZNW$6L zqjscOhEOkEM*ZV--WLPipvKY{9hHQ+nSWJ}DZOf=`#8`-c)u9NO&33HI9fnnD6J&} z54?sxyOWRjTmp~jz@omc(nkQ=xB?$8b%z~w@x&bwK02anrO-JzVBd| zQ0@$p&jW>9!L2t zgf{pF^<|+vHFeFgVAXuXVq^c{hP6wJLyy8p;KrIDX!S#ydtlCnu=bfY9S+kCbNj%& z4YgX1yU{>vaCch|Rf_ECp#%?`SVG?&bLbshesml`hk6D)Xn#%!Umx#8g%ffenH;!Y zt*Ocfq;Ie}z=(w2CIDALBUO<1Qv^|=-8U;_JnMVgeuMJ0JqC3ld=~o@E7GVxS4`o{ zs>CSzjl)d09(b3-f5%A=^at&Mc8a?dR0_OrDPJ$~|y$QKtweIai~ zjo?J(wlq3OP2kEYYo;Do_g~j?Vlma^wPRQ>bW;3ZFNpQVud3m!)Vaeqza61Y3}JP} zgUJ6C6vO-x08x7iwe%<6fO~G~Z+-d+fc4WhnGUL(P{FUj63>cYpJC%tBOvUI409V$bPFLJNKR?*b`aUpBnjVs=0RpdR$F>*)1vUdo zR4IyzgFh6Sd92P)x;t$9U92z;ZKCYQ#UJg$+iDSCMm+J%&3GI0hdLl$+sGU&@Z7or zhTONp=7_}a{y`FblN{GnNw3loz#p3>Qj$*ZO$lsG2~MpQcAyTx>aosX0$YIzBr7@? z$j}Pwq#z@Q<(nnK9zS=jLUC!(2S8h{rl&hLK4E^JVkS4mKh{>HWL-h5rG^h*+Yqui z2{T+}u+*&P8~d`MY&H{HQT!t5IQ%I%St*$(?y-{utWpZa^x5F$PWd{C#ZeJKh(XaZ zCEG%nG?7UE3Rz3}_1*H5;cV=EA29w%0_4P!;6x9{M~TMKhhQ85n)+861&k;t2I2EE$29=q@2 zv=d~5)-7MTI@DR~^|EK_O^49-_LtG3Ia$0TXM$tMY#3xEo2K;@bhiU|J_C^b zlU)FwNA(7%f_q@((9?3+lE%3HJWPVvaP*DPm8{*nU~u1kb6mey+-yTe$(`r?cGI1k z)#b*T+MY4q;fr8qzuj!58=NCe=IezNWms?#D4x;F8GiSZQSDSyQ}Zk6#-7R0Z;bXi z?Zn9FpSG!p*JxsQU-c?(0fCFuG7$q_i1-n<=YI%RpSL<-)ry)IwelMs*``pcifB$;~b`C1#?4RhiL;|D7l)zW_d6lAC;Exs~Vl%sd2m zRFxq5&ouU$6f1p$16dPLu){+cHEDfYk6UK)!6o+$k0)>S~g^PFJbqZ}S3`VSW zTW@RX7S}Lm9+0oyaP@e9_hmzIiF?0{I0ey<*T=G#z=^aVIw>7Io)|Y%Tzu4#^LYF; zG$@Myy|Rt=6eYGn%y2%xV_`N}kzpBPe1 zvnz7u^SR+r+%Zz5{nr19;r4Clcxx_vbyYIN*f7snJ>%EVjN6^~=IV4pT#v#%Wie}c zy5``-XyEx)k}87xD%Qy>k}ucTg-l`A6n2Oc4$81@mbgkUzX_jV22wiwPE!#(o@k{_ zK~EP=B6aIQa})Pi?GurTDSR{{M1P#|u%2e9;0ztsOd7Q7 zC(24XuI{2XnyfPsS%iE{P*5x!$r?5cS!wF_pQ>;= zsG#XM2uxK9tmuH4b%h`Bvx&Y5trTM|(AO!F0dXY=BMhav0*Mg;mOU&!R)S43*K3RL ze%gQi5h9K9bzc~V84Z1RJ@m?w&Wstl+u)O|b9bmay!|yo{-(ua@^pL$V&low-3P&{ zJp0_N;4%GzPWe0K`udYcU!(UqMXC7QbD4?{Qv)Y*o2hu&<1-l9s)m|ciwZWL99NV1V6)4*BeGlu|{N?0vBp9-+5k3!V_2dYQ65a<~3H5v6 z$v@g{s%4zkSF-qn1m9ob(m%Gh0-DMZ*HpWO)soSkZg_sGYUo!^=Y+Z1lTJ=wZtc&4 zA1;}d_&>t$e~yYre2h4T^n0VIJc}nit^S|b+9gCS*T6wN)<|X)e-V%aNBMaJxchAi zu7-WGrqpWDfWh{063nX6G}iA!;v`xz{ba_kDq*34`ZZrmo=h@+SvWNZWdfqW;7i|i zP6V5_1>$z3zdj-Z^R zV;k~-M0OMD%bGSf=6CN&MIwOI*^hXmi8ZT8EKyJl{bwH|s+`u4xrSo^3CZ;flM28t z+OL&G(9$+@mZDYY}>X zE5Gh*~Do1NU&1?c9l-TjtI9WI8`OQHqPC3&wGC}#_| z-b~jH{Ll`UZ{Wu;s37NXabe}=4$MSM*38ro>C6G%j-i$L-OyaIFyRMxmFA`oSIs|j z;WaY=rWl)e=-OYpgP7IN@NxRf?ph+$4OCjwTuCS^>pGzGhuSgN4EYkq2l8~ySSR5> zpvqUAL6{C5HU_>v7`o!`5pC@hYe^w|-Eg)#0{aa}p$lE!$l?4G>0)ql-jh+1jp4Tl_FmH%yQFPVH-86XgGqp5g>VC?p-El=bm8okT{KW&N{y-X z;$1lBD#`*LEtdcw7QqAa>e|?;sy??yT~gnveQn-TQ>#oBVd};S>0aOQ$Q#EVsdlgH z5*ZF_>}Jvh=An}`$h`Iz_wtA7g@8GU+otRSwf0dnJNB-qH4xqHUhs+xc> zQDHY>`L~|6L!XTVxxuaZ@4W2&H((UgIg(GSY!=0_drkjeR?cm*(adBITJJ{lbrA3#G4J#J4w&M7ep}P; zl=iKV2toqIPE?Qe^TT8UtJHRbWkeaAu2_S*yOf_!JdZi7i(>QDWWcc-%TWh@{2_b% z3P`y;m3-PFKTc1>OQC0S#N((2^mr<794FRWw1tcnl3PI50(#iub}scay)tcKd6lFg zhQh-Vp5}s)el%};A$A@qh*`!`J}iKzY<2#8fG9~Y*=g;9;Y$qz1_~u1W!up^Q&-5N zOOSk>9|M_?ToLVc15(F}TJprMBfV$mY8|>Ao>OlV%vD&`RcoZ91v`S@mFN=teGK&m z_B`+kA$3;Us_tF@42r?-s2sdz8JY`*F)Uz-WDu_~26KXb@1`)}gTdlTS(HHJZ^BiT zjFXL8g=4PR4*S&fSHvL%h)rt?GDn8BW(Eq3QQ2lzwWwC-wpA@$V(Ux8N|^y=Y`uWA z!Z8YIgrav%cx%8Uli~A<<;MHnu%?hV_=)=;GX5syzy~Ve7jY+Bd-n_>E5$sJqa(@5 zEU1caHYYDACbu@7gw)y|D+Kneq(X&K$F2|)jq~=$%rV0fA&1C7F9(|pnYl#82mXVZ zF~tU2TWj=X)iH&{A8xlGC~er?xJ^wIKoVM`Y~_KnwBG|(ah(z=ydx>wyTn^^@$L|1 z%A1Z01>4CBX>AuNURhH zNP^UIBWKWZAFE>c*(_1b?n$Xr)S9vOPApYF8A}P$x$j(=R`bwu8pz#Wqtmq8(HPOW zd5>1H(nUBu3L`A!YZ*xW#+hs^;moSgpizIOUv~ zhpefGZ00cfBZsq2e*FPR_bpJYqODr|*LxLE)@7P3yU;>5@8ry`AxhMM3-^B97LDlgA%5uh+;-QT70(PQaRIK$p#!r z*`@Q?wQ*2M>A6vp)L_|sjU7pyGy@A7fY&t`8y7|cmGll{MdFAQeP5B`tCA`F0*z(R z|B`XHC4M;+*bt))>UN0Wvpj_nx0WSG`e>`7duLUo+jj#aO7|(4b@z4D2Z??WzURHuh^ScomkY zSE-Jon;jq4o1ZbR(wl$V{pFpK>3Mb|7WlIkNr|h~1ghDRQ8r>RfP_ytCT>rs+xFc4 zoZRS4FJPQVl3u;dgTyesob>_fYg`?&|E%zUCYg;0-M9<4wYnr}`xMTd@?5$Cn67)>5 z2Ls(u_Bt|A@Z2{7op#TrDHN|=bzy_DyA!<|Ne>X`A@C;t(xe4QaVLj1*}#Y6&i;gY zO(Speg&y8raM%0GraV!S6(g#<88whbQqtFh+Nm)uDszAyCn+KD`N9nItrPdf@O!Dp z=OT41+#T~S;SXOIoIub;kH~)SI7GQm;yYhz9gaG%?Bhc6n36*f=0?TzNtCD0GG9V%d(&5n*=83yQlQ>PAvH?9eA`bcE;MLS4PbP_T`^9!d!Uf+W)r zIh4+svUFG?3pN^Zg>=pN&{OgBAQ7HnDK5`4|5oyyCjc%JtG;B+RvJPq))2Qg8?469 zX-2)lOcJqkz3UT)Hh@Jv?q=?ej4FsIi(;YJNm53tAc7QQW&;3Jwo2lmuJp$*!UH;* z$@p9}Xs53C%YzHbpi3X&`Px-`$S`Rfbe~kfuZ9gd_?qJ*JE(p zBJ2XGLfs-+{f-~4_F<&%RHygK>^f&x5a~Mj7mW>W-N8!rhgijDj>|M_Xg>J@*G0#% zE8?^4ad6mZ@OznSWPi2k5~Dkxz9Pz!if;bAB<7>Fo;mu?{sH8op?2#>dvtB_IM0Ie zYLxo3fi@krs-e?3^G@7D_% zmDeTZt&P6D5cxChK-x|Ryp~P7@w#)|&G7KE=O?M(Vu~Tfqugi6wT3W^=X;X-{yD2! z@6~m@u7WH!+RM-Ogzis`tu)8?63|8)R_Fy#sOAgszD`AlLX86outB>r`hwzCS^D2@ zChFV!;O5XbkZSFuOuTtug-S_;p(u3?lwORZFBP4sEo@yQezaqRexUC^qDHB^O4rbX zlF)zJ>7sHZOTC1{dS;t&iPozo8UD1}98iZ`rH!X-DMcLIa#Jt2vXucKE34NY>Iq%Z z3}B)~^?DP>bNO4KC7vyd%Hk@oFbr5*m=ab?2J3VglsHTKKbr18_a4YezsgeNzmXFpvof{;LmCPu41+gXsW>R$e6hB`dvO>VE8n~e#u0m}Tu*TfUYWWA9DZw94eH>;Q< z!dl=TeR~$%zo=@%4k*VfTf5eLybN#JbP z)6~7!HeV<4IEIig*Q!43N!bAJcDD39M>DBJpdhS5Najb+!Fs6zEsEM4-D*2{z#F7k zg{cMhUOpSB3$v_WJR=19s2P;ccPU=io#J^cn@^V?1g&T7PzU*&jZ7~p2QM*K>)-&F z^@AOBi5lBzz7w5}o8Tq@zd_Ud@lEqkfi?wC3etIhBzb z1I@o?4sy;SVO|FEUKtR{I+Pm=*S197RfW838atDPDX4N*HC(aC<^Jgx^SKybS4OT2 zlI%0-jQ1xl?C-=qm1o#iHrDXJf=wXxwk@q{-w(tO5qT%x?{~UdXY1klQR>R{miV&B z)PrDafO9&4pUAdGs6h4fY*x|JNn zsxKrUhd7*QPE)?if{$#@E}ZJ1@;~J9CAM_055dSDC36CGg>2-0E$B6 zh3M{>CT9rQFO6 zv7?K7R-SrMx(e27rgI@^<2)aHCW$(o;IXMQWgk~C4wfsiX_kIcS$1#`H+rw1Q2UK} zzQ~`M47(RglHqRe!aA#PVODTsr@UJ5lqG&B9!6LULqj1v{_Wr@Y#3lv`y~~hton!woKd>)B+yNvIrQ_|mZ0?VJ`x^K6EdSLw zV_7fU;fQ@F6tV&C#?1L`4J=e+q!{AYRJk(0mjc)hGs2t|4usrr5S!o#H&`7-YKj^s z$$V8ySa#8SzP^-jZCZ4CNRz8Y4tXFpJcmSvh&y}6 zn9$(@QH7&VpTfgHATR7y*{uRBLw&5L=yIFfJ$K`}7ho zUa1EeQg`5EEnz|NN;ahX+Q{S{0d!s0jRr6RWY`(Qx^Y_Byn&@TcU~(9N~5r#CY!|q zV6dC^lobn8qaI&M8#m% zTFQf5^lKOh^!($fEaBa2Nio-pbQ=|P{*&{ob>d9`y;`H0l%?A9K%KFhC$zMB^QECxo_WJlDWetRAQIL$l5eH-RB;PzuYr`CaK>ZhBWG*}$n z3U|HgMxOTjs81ll3&Me4Cz(p?CKT4ZpQvZh^!5L|Lcg#GDV2T;Z#5NhtbPWm-+wOt zxJ4!TdF<~!BT}j-g)RI_4CVJ~W|6<)x)={4$OwGVCkb+Kx}o)}ZMuR0=KF#@_j_*Z zu(!1rjSC?I?m5XcT;H`40F~_~qM2hxCsO^$kzmzd8^_msa&=ymUEb4CiTcPSW+4yD z091`9IqaW?Q_yaW97N-py=zEG3G|u&-e+C%aAGUvp@FKxlKX9U9}de)i0)GsW++<# zeXRkh6IZcVdSD6V$KShG>idYTmNdxn8*dvfOLI!^W*Gi#ye^!0-Teh$D`#3(T+OA3 z71!ReKA$v0{kLA7j$RS}eTXC-Z_P?=1t_vsnu6()M9*um>Ti3b9bxtv9EwEP#a2uVN zH>=Gv)AB=MF|MLKH#fIam5}U zaN6dWI@o~73dGu#&%5&si}$v5+f-9|xO>;8(=;3CaY~MvQ8T5yJn@!N^b7genwS0i z+7k#BPb`#N<3*-HMLLHQ+eYUN%H>+A{WxNq@B+8CB2Ko6yz-Y5Wx)q2eIOr}#270Z zk5G79E}`SU!BMmyYj9k%zfa~%wz!U(W{&0oIy6CF?NQXlIs5igraxbrJncr!xhjz< zd2{p0R5%%d9TenYgHXDY-xUCcznKlp#2Dq!=F}~d-09!-@rb^W=Zo{s1w1_ali$H*=ujN ztfySxZ?DX+HoPvJDg}PUxlihTSSrWmKD-#W-Fm6eGbW8v8&VPeOT*oN6HFf^f_2D) zMbpIDh_LkC>rFO&^q|<0&}@|18f4VH`}Li#@=1K;0^2=$s1le2blJ=2^i}KB=|=-N z6?XW9BMTbq{y%;mWHOh-l01W-N#WFa;eawN@a{OTWfULd?zjM3RrEG`R5m=M=x`!+ z#<+d??!*b)#C9xByC3oEB5tT8%-P4JxsolNdMn_J7Xe;VW+@7&L+6(;V}~IR;dOFH zM69`Oey}KnL`dcqVi_fIOzCJkZCJV18e(zZ@PLTjFft83GLyBa>hCva2A1XM|TxZq~ghD(j+YQ*s&gROnK#YQowLqUqgmtWFT&40-DVm$1_u9#{9ZApy6tR+PZ2IHWtsw{xKDurwts67WhWOnYk@ zL|Ax3q*dnSidyMjB40^?Dgsyd;5oV(d%Ff(ho=&DKpwy4!?F;8Z-Gjw%JzqGfx>LB zH{q%g7M`%2GgTGaJ(y?3#-82mjkwf{otwd8SG?RsW44+=Y5QgP&_ecOf$iT7-Ix*@ zRd%ok+-x>a1F+f02Ch@6+`trZrYj4*%NTLLj8_MoOar*PLx%ABXW;t*+FBcgm3MFT z4(CxbAU}I2UxtVm6ta;Mu+)teSSl~t7BbgJo&rNFx#k6k5cNic>H9~fAo5I969!mV zqQQE+bIumBP2PPtSU@ZZYMy`L8>qBt7`6RKO$Ou;h6@XYJLwSGy<8~%Jt;*0A-EOa zCtw%U<;t}W#6K8>*Tm!i?yju<(QE!G#ni-tmmQeO#I9tdB;^M7lXz^jnGx9A@<3x} zo<0nor_Z4i;OHo;iJ9>E75c*;Rweyp4$|lwJ5ycDB3q^%L&kbGLPw5@(d0#vR7oW5 z7$XZ0gb$o*=g-VfO>axLOo4Dns!2()!J`D)DM81aa}xiv$OfYe!@+xWgB@mm^x|aE%?j765jvz#0$si@hHYcD#npeJ(z6j`3*O+)Uj73 z74Fn#$DUhiSsLOM!&>PduU|+MCCDH`K=T>DL)u)MTYf1qQM%Aolb(t(P9!5km@2)m z^>ddV^ftvIh3HA<>A_CY1@jc2&c+K6m%b{fetfiv-V)7D+^bEmPf;33z@evF#&^HZVn&>$nT*fB8Q7GnA9BMRA^!5Y< zew~Sz^)&5O;HEdZ1IE(zLtHHG zk;aoyy6o5+;)(kD3&TOn(lqrb_p(URGy%uizCMtdUdIV__<3O8+o`oj8vU(Ij-*ZC zqH=HyuhfcJsPay4%_MJ7T0gPlkXfO~M=(}83HsP&n7@M6+e~v-zvkkJf->kxUN$eP z0@x9P(?@f0#V$wp)_>%_yLTw@2!_7XACV-7m!03}7d>u^pjsId{JY?%DUG5*m?W9m z2)N(p6QL!{@PVsGwvli-b1LfjK#QUd^L$fg3)o(jw|GF^hZ#nl$AnpQ5+!W9*Z|m^ z2e7mS%nR}l!Ye_vz*s zGhm)+jbVVGkP8-I3!Tj{1Rnl~C~BiiA)z)_;6M=G(UJV z#1jC1uwPN#4S-oj*@sXzf~a6%x5dIni3X4;jA-E?&)z_0V+U&^5MAdi?nHqmsuQce zLX^s3if+pxgD}kE(1J*VGPfaCx}mfBXx>4l)wc9MJ>!bh3Go-J?Bro6g~*NGqEyl_l7Pm%NKJ z7+IchI25$weBXwPZ{M|7=>8pvjjPd0bEvl1K$n>iyPq|8GGwQ@hdFapH3c_G?#M{1 zh0gnDOi)IRSxuHvsz#)%U@TkBaw7f-%+~Jff(1SG$fgOzFe#by19WVJTD{aUnqy9nySNAgUNtt2U#{j{2wB_a+hZfB< ze|qkL2d`enTOxJJg68CplMgYKd}}=T;KJT=;gQ4yusw{bVUlJI#N}+~nYG7h4kT%@ z$?x7ive^kV__s1sI;#mwO5e0OuHA!*2zn=sM-E9_*$TP^0t1Kjw^_D6eiKXB*}x+U zyz`0N3*=c=jVa7iql{uRv;K$!BLr>FDQnj15Z7&8G0g29d^fNp!3zY(ZSPVr`Ih&S z9J9Di{o(sdl-hr<_tL7!9)GmtujeemSV1|=F`AE;WST91oIV9z*pr%ObsL)7P12BV zcZgz%_@0w9U@lMehnF*csPJ!Y>+q z0U+6xKL+hIzJdIYwyVw^n$^nDin~nx`03;`|04R!QGqbfOKv1j=cqJ5wE7{6Ano)Z5c^@86jyCx0;Eh`GO{rB@~yPlk9VvYp{OWZ~cvYemzF; zu2r`7zd43}{FAA04n3BIvh4r(hHzvb4aGq*ky9#P|PWU6)tbBbl*2 zgeP#p)M>-8vd#wFdL2-R&bBLT^a=f#X@n}b7XaBIn6}q0&I(w7eNLIvHP>-ejk&&U zwyz08J8sHtvA61Z(33SUsLzz-#XeOC3_M{za*k%hjX|U#WdHQw4^FHQB{XewGyWnO!&GhKIfhRd zF%)j0Na!Sp>NFi8WeKzBpfngE5NSG8(dNlM!(bjLe=C|*gN`xmnQgenqI`ofl|!DH zB?+3+Kg{N8r>d)a&o8vNFFEisjdz&nMmI;uv>Y9rA#!;IA7t$z z{kpdqFWM71-AJmo@IegFfo9!Mu%-r&o^ETk>Qp>=rZ-U_O`Hsu+;N{4YsK6QOeRWg z#C{!U2~1Fw`cr$GUcJ(NC&(b9sEHZ*1Rv-t25MBeIQuaV(vWIb@&Wl;r|UJC8YRKR;$Cmc z(5?STZKVlo=$T?-hea~hbvLurwcT&zaqwrtQa9H374gmrDw5_JQ8QOg5=?laz7|AZ zTgj{7|D6ViOV`A{#LmbB*VNZ?baxXNG1Gzwca`2G8(m0a*}e%{TQFjG8t}8|rKJ3; z$j$!nS~MZE+D)_v2j3$6_Vp9qz61c3q_{8q%o%lMFL12f|QjT^v zai-o^s~#b44>0;-7G<-$pgfQPksxuHfCon5*Bf#g#7UByZ`#j8HGIthy<@;I?)^b6 z0p82a`5}AVX-=oRrz_FC($v(N{p1RT;=JZX(vBm9-K(v@zu`6DQ9P~H!}ePMUxDcN zPhq6NB;yB@&~ul1rAB2-^)J17f}f zhDOenL?0|D8mc?C9`_g&gJ6%kooKtIPzvCwJEF^L;t-PliQ6&@+oxe{@UvGE-mD=c zGgVK4i-Y$^tEtx>6A=2=mDvIPEp4!D`Z^>u~W7tsp)NcqKUAk6wV3PULZ!l|X9!BDP$JZr? zyxkRP2XxbtzQ;{AtbCNq_|ZZN6gY>mF~RkSMs9%)#=p$UD~hZYhc{v z$Ge6VoR#u4I&@(nyvA=zQz&uv8DzItEf3QD5K>%@=GQKJM*Os*eHhiD3NAANZYnsa z!mUm#dn!>;)q%XNXYqM)*ad@r!^ zQ2N)$8+Ds*PEfh>{q?UrMY%fEKxT+&3Y(0VGYKW4Y-4{_2(!OGyBU2%Q{E;*SLSI<#cfCU{z< z@{b-y#sJV_z8uIF`)#B~L%o#TYRQ2d-6@aQShBHs)5``uGhsr?&e<<*Za6iew))39 z5buJuI9=uKN4bY6>Dq5qwCX{&cm$C?AlN-gaBoD4bY#7WQ$J5$+G$%FSQ&VD($P^F z(U*1V9^_eS@nVb1z>d4qAo0Qq_N~4vMr;jrrB0w?5_SML*kmLBc#tfZj+#=*HJx;R zZMJ`?))wX;LygC$3IqD{TyExeVEOR_cBmTMh5L{>JfU62d}7#1#-3P8tQz_SH&ugb z{j5gJ&|(O8TfS1x!<=0zE%T^|D{d~b?J=lHa~PiQcw5RF4^N#4(qv|;t-O0b%0&N9A7E#Vo0I-Vv~w?6tnpv21R%tBy!7px+eGtx_b zw4_c4bfOV>`L_WZVNoo6Wv-BtfT;XJ>ii^Weti@y{3*{J4cB>(GTueVxUK4ddKbis zRO72v5w1Y{?qLu@@dBEZZr(AbzNR>p+PTgYHnery;r7Z|--Rg|DubKap=ZZH>7mJ> zm82OAXc0P;MU9u<9v}GjfKnIo48{gBOcl%Rb2er+*pmqi=G>lw4ywt06!L>p{~q+> zj@qn;!2j!92o?_JsXq6G0$a&D4RHr%?;AhfTM=kErOHp#kVgN3MM0v|ydM;boM6FU zKdt{(RaP&)Rs6jxx!xIPczDjKhryYV86@OQ7;Zq@Fhs~N&Ny8cuda_)-G}kLxP^lG z>!J$*2^};JIO00vhP1d1jHM@17N3UF!q7rV?6um9ob0kSC=l)$&?{G#5OMz#?<_*|gCTmLQSt%5-HbA2(Thc*1kTq6=^&5=|5@0h z+)gL%`Vdn{PvSEaodz)$k}`N9hhVXY4p5^9(cA@hu=8K;E?LJL3ggMh#l=xiDb0Gh ziyPFO{~K6}22^pMBQPEY*hKormU90UNBU@3$!8xEN9CI$Z)QFlb$-)4s}K2a2&+l+ zZy^>D{*3Nyg(k-&6VIDZn}OzW*~2U0Ien`N{unY#Pe#wZs1`DrINetNm@AEABe`)- z2qxMPL|K5@6*(a8dKqfwg??$+a~%{FL)SAzkQ>aMynD^0yeggFySr2iDTMG%ShHW} zOLHH4wk&#Zrp_2$JjV~0ieDq4m`+d}*tL3{-6`v71Bz`ipp9kFHejaV$95x(Up^28TJc9kQp1-F+)Z1WHIf8L8d&9e#SB@|?-HFgv9ok3N zXHhQDCoITEWu=Z3Zlji=7U(x0mpd70KsU@=59$EI0J5hvYT_I?VLBw+JdYie?Gs$@ zQk-_=^XUm4fNMtS1m-~5Nnz6Q?x?gpQGzqvVip@u*e<$7q@082>p_zRvMUIs+GM6~ zQ<`_5yK2Xk79*}QbS!K>^tsHwTm;ZSWI_Q659n*B11%UUE5m{=U(~*(F@fjmS%cYc zc^|+wP>3SJC{oN^&S)@|xg7e}bKF*3>B_fh?Sas&g5)@JX0$-P#r*W~R9nXWnZdl1 zak1}{%jRk~->(8!8zhtv!N+vH&0)8dJTM3R=3q_=*mJk2`2sqeCam-7_n^-x@6?bX z6*Z@vgxUs=go?bm4=FGa*Eoc7bivXX1I3W5kMZ`MOCAk-P3P+oO68ChpNQxkk$_WT za~}rKWro@iGj9x`vx!E{HkB@x0uXffsxWeu9jK?;k@a663>4lSsM?@M$PPPfb4{t9M8A07CDPa6;69bNUvl_31VKE>_V z3DsA~?f-K!XdyViaa&xtMqC^lM*I@wi0SWzszgaO(XcT??cvl)8!)Db$AjNB8`l^i zuWLfO(OxX{up(GdpT21aB)|ZhNySG$ONaBG6yWn!G=!KQgNlHkYa9;Gv+wRtEax)a z{;;C*51K$%#!*cT(HUL#1T;rO=$$S`fr3v#P_CXSLq^Rj@!Iq##Y&*usV4?US>os@7 zAM4=UkAkCC-#|PxfhUVPOr1?3o7tKMPRgR4~a;u#M&GDg`NG&FeYQ=KDb~G=DwH zi+X&9mM;#DIHV#GBA7!aN}MB1%Zt$5g_@|p3}&mzDveE*=)J==hE0{<%ueF72Lo<9 z&NFr-4odYwFgz*I*Y1j$`xy0C%$@AT%NDnD0e|{BNl#QTPs~4B3&#HEbY>SbsUR9R zn1>wOPqO@rUPQs1i&-)%tYVrU0?BQb9~xB8EBIk6K~#pJXKMDXfFXNIF0*lUi3#X( ziY6H$W)LH9^tlfGm!n#=p&EBIN8UssTOvSp0*ViCIEJQ;fkKl?z)nJo?+gu-?ZRm+Pf%{0a;G}*R{Zb)GZ?)B_5aQV> zqvx9(({YSQIHBXzghMFL^lj_==`@Hu3*)kHY)LBucN}7)=JO-_ZWa=ba9gubsF@Mm z2b1I6iGS{n#~zkn_ss+n1>SqUfIVO_>|ZUR9VMtH7*5@Fk@|2jn`wFgO6xBGCPW0( z@|phbP`b$3>zpH*^PrI$KtFotJbuP-x+><8UuT;81VfSX(q2a}Gg;y6h@^7;yU6=+ z_(w%=2k+Nq$kOcgswe7ocFNwrO}q2XBVCWn@vYvQD}fM7-%5?aNh=HV^s>blom(ht zP5It*-)=5pjmwukmd$Dc`Es;ls?i#{g_lm*9hEeSIBa3dTWh2;8it}7$F&FMSxtmA zSvI@1pfiD60fNtecU&HZ5R!jiwEhk39k13yqqm1T(QBSTktU`}ulUXE@)Pm>Y;@9* z{TFKp6MP=5lVPsXncKcdT*kxcQ+Eo&v%6~WKE@?j9wyV@N87ccF)BjEI^8$HG2f3M z72{&apQzn?kE`B11(W`VRrqx!7I;rKfXgtl&P%R05Cs+^f(R-nE(}o>`Dp#0gz75F zw!LJ1l*;O8d|iHs4NN&ApXYxR*AwAgkF218t)w64a2Vkwi59jYsx8`IqrX}4Op58i zD?-DO012Mc95^dv6E1m+%+uSrnM4&MQ#Cyx2Xmo`HqIs{#l`3+%^&z1o zzHq_3@u0NTAOlMx&f}5lGgH8R5zPMmr2j#-1{Ai8Ddb|N^0U)I;BPjS>pu)sZLfY{ zrU0)WK?@4Jyle*CyY~N*BmLOc!`X9I)ILS=UBVI&98qX?F#^2GO4D$#V}j^Wiw#>J zo`iyCSs-{CAYn{awm?qhCgskNNPx@Z(vEQGmS1;(GBSY_wgYNJ+EnWH1?I93{mz(63*ovsa) zC2fb_GCbXTXJ4J9+N~OROvk^Ww6>M5J0cS$%Z?T%FI1z0_I%aQf~;2;b(+eP_fI7C zc3Gr4yc7}VrB7^70qB(UlAT8t;o{RrN=Z_+JPjy{8q==1>3bmJEibX%;CI2yRRS&h z&acN{ci({Fwc7uULf#0COh@YH;U4K>I`PGj55RbfoE?uj4F{KxNN$ze42@HUw$tVq zY_S^J&0pN@v zXOS{oJJh^ulhJ)@A%caP7mf&>`(K>*hNyKv9Hq%T25ndCeA%nO67aSv)@@gaLyE?R zEb9}47b1|Mdax8v+b)drTKh!qeqSJ{=GSFfOoS)4`|%aCPP`ek3%mG&e(~S-$HCGW zz0@_ivL8$)8o*vRPSG2p_#gLoKEIR?1*ru%UX3GaI;j9Ea&-|GYfiE=-uml(r4+^~ zKn?~XiJviXt@jS>8#hH1KR>Bm5p7YF)&=^N-muiyetgAzxYAej5}D(XnO$kABYMJQ zrvuudPfn`Tj@m_poo3wq9f+df4*L7%b}eW38d>O5Xq`3&V6+$B-OTn0&f0Q@Svi7I zRm()z@Yp9I3nb|Y^P5ToV3;kW?Q@TG{RlYEQHju58uzPyQHNFJ6PUQTPPF!3iD$bz zCPjMKrSOAS8#Bw>tViDoMa_TZ^FnQ)BKMm{`t^;w=*l10$r*`EJ`9gVa;6&%I2S3H{Xs%i<*-s%YQ%|C4$<%-}o!JE9V?z=gJ zJT7|*Iws8-4N=#{9nrHnH@Hc8C$W9aREoQm&zhu&BFu6(bz zsAW*HaJ^=Ck}a)5wF-F-pJaLI0rL>BIJ0k&`v|>$G)kD?&8CqFiNiXQV#vB+6Dzb) zf%s|X8ond_TiR#>3;(g6Og)U+b5C6{JA(etg#VN;m!^eM5r2Y8ZRd|b{U5MbVgFDb z1Zt$KasjEWWksJTh ztZQ4n=jLAB2*;}L4fFcksTgf{X{N9oN*!NcYjx|p_5u^9^$rK-usvVlX177TogwH! zlyUTm+T%)IqyadQKw9O1!n+D4K)%5-?|!8y;8ibR;|iVM3+FD1Qq9*y8qG8TligyS z^)$)hC4Jmt&Zj7h=&^8u~V0uIfVE#TT|J z3?~W}mTOtsx>~|xNozzn^}{9_-B~0X8vIHlzr7Q&p(M}6Q5s4tvDQXWEMW*_lq{1Y z3s{=KKgb7D; z%tv#e5)EfY#9$vRO92a6j+uRw*1X5nHJ5iGxgDh{wxw@eOv&ap5Yon727>eL3d824 z0|wJsGJRy26$ju%*G<~VMspj$SoqmJ?y+8KJk(yG+w2PEj*8S4xhWZCZ!&yrF9S5E zrkjv1+gOw)k}VmD^h~2o#047Ef-7&+WYaV{UP;{+875QfLvp6p61`p=8&L}~;175` z!mY-N#TB-#w*a)YU!PiQzZ47dGQ+D=HN-OHd=}RIVA7gy?YJ~A$CotU|n2@?2UMCnAbdcH^9$NNlaKpc_A1Qp+^?Z{km+_!A(9~IvXI*+mru7#O;tDr05$nM$wjx^%NR4OzGeg)>ue1?f! zdgEpl8ciDx-pv>GK6)K__0_g^ZM5ZN_0lhyt9jgtpB9Yda)l-qenc!R2v3Q$Pe0{hYy~nTQ8F^uZfFYZa!&VEH^neGJ(An)UmO z8QS&xrHSc`rlj$By$iZHl+A3II^R+xBQ}p>GnxQ!PSd+`ShzYBFs2x)&sb@|pbaNa zY&wi26!Iih@~6c2e*=cDa*;COXS76umm?~Z0!Y({mhnDkOA0S#dBa~z=yC57-1xtv zg<905u2h?(?S>&@qAMYwRujHZQT#B~Suspy#x#2&%>K{F6O+Etf!XeqTvg3)?`^fP zI4C`%H6UqS1Lg{UsS+1I5+zZ^I#;F%zT!^{SNtZz@kHMpHmC3~EpU{LLs6(>TANKwR8njv}{CSOn zcC|9bxql*o3{RO~+Lainp(uPBNv`qyDG*kC!^>w$Nx z1MkEVF0vZ3A_&u5ikY9|1|0b}$pgMOJBlhGjsW+a#OsX;YRNU<#{*@h3l#s58c6pN zrJMkCrw`h=;M31Iii>zuIl}S2x|Cus)9%dDB9^d_V1lSj1Not$@5u7Z)PO6U@jD^- z`Tm)ZwHA42%B8`)YKtS!@9`6PKCfhuy2XrRpA}H9v<5L#&|O~;vOzWk=OzV?n!IB> zDB&EjxwwCC3Gp3ul=2c+S&2f|Q6$PrV;Lxx?OiPhUhjPeu z^u@yjk`$AN$RN5kS~dbG4Pr3j`wEOj*Ya!~>HYv?7+)f<^w}ok2J4a3e2U z>1j7xYceV}>1Z5+kCl1U@}Mj^1=QH7rd2~|r2-vW@&MuaR(SLjl?GLf37p;*iC3QE zS_mZ!6820CrxbT#qNsP?khOW$_*fcN6p77uYgoVP!L}nAp4u?j`x|b z?M0^~`^8@KnQykiLz3_IqyK`yQH*qS8!yaC*jNsdx74Et&Unj~<)laFUXm$xxAr|z z3RB%{`ewK$b4|tWMRLuH$mT(9`Udjbt9iUxEC1$=ItP7DTS;Tgk#Iz#f0{N>)Moa1A~Jj`&TGC**bp z1Fh9=`(fJ8p14&2U6p-K?2+Ms#WX77T!$8-mg+EZ!y7MjZy;i;JMxMBZC@#IU!JJA z8J=9GNpDV$)4Og+bcD|l<6smzgu{ijvl>5iKoq3OPQQufRHfW2z)!w+gTgB3>JC+U zpDFsUHe%nMy%o9GBEViU+**aCLO}mE;oMQ?pX3f~9Y;`P_)Csw{w!2JVsHkS3bFk- zzYl(UN)Io!YiSfq?~U^}5r@u^SHV+~n438%;-dko&vrk?i237hpR*(f)Kg`?fCqWS zX!IJQ*6E~m`Pv?-L;}dZ9D~AYO&hn@DT*CQJh6N~MqyjIBZbtzc@L&B$>*~%kD-v& zRRm*}U=$Q7OcuJ>5x^ARrjI8K2!n^SLxU4~oZ9!qT|RAunYQYM_nANC?YRqtUbm+v z93ACV=}j5b{#>JSJ=O`+9yu5}1LS*E-!>JFWAI=iit27o*}fk7L<#4n#6YlG(l~z` z!H61>og_<(ASa3!9Zyx{;|8$f9{5&4pfsDp)5Ck$Lt{R>`5>x=*o1mWiYxW(Z`gLt65z4xcJ z(lMBS1t`fkEjPBufZP09^Mp%4dtSoEGT4`K&=I0E-vTtO5*6!gVqH4mDEnqh-jseA z3mNnJ%|Zq=*lG%aEj=#nU*p>eGe#SW^?8K_I@AO1b^&7=tbKR7 zV+2YEz76|Nf6niJO=q-buY;BW>wyzQgwR5tAg*z@V%v)VIfc zm$_(pGDjheSLLo;;II~?C&2b56B;#0LJJC@0;k;+YiKS&*C5G2X0qUbdf9ObS= z3yJdg=+CephXFmO(c8^7nCXz8DSyWph1BY^rU&nqO%krfW?Co4h5qkAV5$ihVLIC@J%Ic=sA;t|}zN=d2R5zmjfhVk5(fCX*$S zu0`)1d7Sgxn7L?a8+#gWkJI4@e|f46u5B5x(aG~-r_3eYxgBFUJF<*%hJ#A4DR{qdI{-R(z~1asI4UZ-4dSxyO9 zH-)b>F(Pmo!~_O*iSO5pDW%FIAcQoKjIv+C{#@*~Ywb^};9EZ}hI}m9O%B8QWsYx+ zK8?%5pbvZ~Pb`GZZmaD!zApS-0do!W3X;vK$m5D%%9I?*{8FIemU4INcLKingGeu% zKPO&QI?WKVu5e8@dclf(Vf|Cq(CaA|Megm`#lVjMh~(KTI6U$Gh$;M0I%&vAgr8z6{qJSOMzc6NP5F%aUD93gZo-TNUDg!}G3ALq75m8a9 z6YWzDZ1YQle)XY^x zh77yZP=2bQGa;-%vY!`INLLrlda3H~=>q-C=3-FEkXJ}Q>CgV1rS3;UQ=Av?B%WkY z4YnknaXv*aD>xDae4Q{1^q*AMUpIhm0shbkJA=^&UWdnZ=rSmzs)pb9m!Z;W8xZso zt(y%iG=Uf{%=JwJnWU{XEGdAFgQ+JZpDexU+z6lzKgeH>vz{IgB9qq7jhHFQDQw5Bs(F8bU(^;P9o z2m7%z{k(?-x6W(roe;C-L(kZ=2LJJ@neWt5<~-P%Sh14pz*;>pW0GunE%;UUcO6yw zaQ`yJl>eI&%|GTZoq{@Q3CB~tLcMDZT>Wan3f?p=VvQ$)Kyy8-xM*Fg?=XcL7~|o= zG_q4hD_!pWl0R8qHY8^Lv|*1g)%@M8eaD}ro))&PXbr9nI8J*26tn)q!xL-jQUkMS zJ~WKqFO=YyD@MC-L%W~{GVg%H%0HgPiEFr51Xt&^x>Hc z-&3;-?|a4^gq$Vxsj`;%c2HeMCMXtNsxPQ6#wknu+UtG23n(O=%~6?XFA~EqDr|u<|tXW^`h zJ)QA!{T@Z{eY`f`!R6P}C~Z&@DBp&~Aa<)6w>Y|SU6Uo;r@B&a~+U=yGuWOT$M;Ec#9Z0HuSTDNHNZe(JNc~<)9{f94p;8SzMb11Z#Je2@>9GHmvzI@_1o)YMTIFIHGdF-Nzz$M?oxM7thgwPfL! z*8}sa7jSz!GMZT{(?%>m>L*#))4J=o%gzroo3$3y#A}6eEl|N%^Oaxj2Rl9poE<@* z7R{9rEp(26NCya^{A}vWTU>-MXPk1D6VjFcsc9>_S@(yTu?j{RH*5z14sN!B{Z}9< zwXmx$m~dE1TAi@u-*psvKY-9_+o9KYd;7tj4mWDMm2O=s zDNai+{RflQ2PJHsQg7lXD$>CQ)Xmdp$TX&H?Fi{ zw*bhVtZe5rHG1Cjith|dTzP0I`?N@3^)d|u0bDL4&;g7}ZfRbziWD8PjqnrFjLX$X zzi%OAMjP48|EWaahbFbUth zg=Rai+;@x9Th8-1RQyKZWKgXU+yhUbOb z#67aX;RFhv7f=07N%lxKPjuT3YF<|;FJ(%(=3jM&f%|gsvQk)sW{w+CCcoa@(1oe2 zQOq8-{3bOWE+(Nk2WdVdHnc>A&aV5a;?x5HTx1`&p;T^?6(Sg{|jtlS5c>Wvx<7e=Rtn0Y9Fc`$s}cIe8GYme-@sp8 zxk9+2COcaQ1e(u)1X)!E&>Oe)2|*N9UHFip{e}LtDk^rPJrezXPJv*D1eULv~^8bnmu}#V@Yha2{|@%giT?+3Q>|{~ z?lZOL_VMqLr3C*QkClrH z!QwJbB^oZm+9P5r(04S{B*}DupNaG?Ktg@+7);eZ+7Hp9x>rfHd6+&BY%FESUuuop zO0XR2hi4_7$B5Gk5tgTCDsn}KGYH5Rz=C$Eq>Mv~s2v zkwFt&9vL^NU2(QCHAEF|Ha)~QY+q?mnnT01xU5SdNrK^gjA^5OZCF-~TZqYJ1L&gL zNHl=Wxce7UP=p3A^anS%rc%DrQg|WPQ<*EJ`9#uDR#|;fLTB|YUu)XYvd8?u<0p%j zYeZ2p0+kfA#^Cp~(r~=URDMaFRzm9T2T@7RbCKOlhUcB0Pn0`R6-E1Yc^z^W#4475 ziyiRcx$EC9R&|AFz%n+UPTprjiR(?^J;tx(rd+MPrieeM_gnlQ)v0LC${Ka2%^Qty zjr6bnmqn4=nCbtCLDlo|151x@(tgP50^PLdy?sn3XPo@i-5Z6f*Xzm)L!cAf%X?kW z#;*-zQ0Tw+6YtjWZn`eWj=f!W6Si)7kqdlD=$k;F@s=MC-A3y_^R=flbioB`3l$X{bzjjo&B2H??un&^Xnzs3b~nH=QqdW&YAv)_4}OQR`}N=wg25C z@{px}vD-~j-1RBP&qYR4jl$CCU;ghnW1I{+>~|01GP%+$fT~@n7qs~yF0@wrpP$Rj zx8bn)A#6xZ(wkj~_4tbg9!@yr5=hS53b)uTg)V*&ZIDM|V2ehIsf*flqHwUN{!e(1 zl5&E+SzVS=<5D7AI2nCSb<00EIpi2Hcs$5)vca7&%`|+mh1KP$hmJIO8+G^rH(D{8n1e{)ygx)qhalZ z0qzXYKukicBNi%~n@r4*ZC;c#58de)Tqemb6;P|_pdH5mlZDiK@1cGB75$9ZV+Qw3 zxdJYlHisk!ZrB{DR(0N_b4=@_4+o{)vN;oITLRnOuj{YI+X)HQ<)MVu-H?>;4OXoh znAm(^=#r|RANDPjVNJrB1-$1XjNb3bYiZhH9i_M0t)nG1Zb=Gw8)nhQaHVX@7quIQ zN@QA5$mpuKN5^k#TD^Zm?mBxz$yDcZG)#V4ykgR$z9N59`>0+W0L1@0Yi-105|=GZ zhc$S+Rx_9+iDCT2AM;{^)Nt23{K#2dGMk2|%CLsK0N#^ht2)^cLj0s2*HN{fK`p5$ zO4?$^tcrWkhS9#X2{y^*__$Mws*JgQm-v<2^#qoD_I>*EN~L7_{M?2~tGY<-3fSnF zxc+T$=+_KHNPOCL=yf788pI1p$m=i#I076O3M_!V1TO}^MuRcQ^kH-Dk)td7wkPL^ z|7ap(K{_+FSu1kFS@*Wa+S!1!78kVE%l^yq{pPwt*ex@BBf zHixGgft2xe9|Mk$1M94Jd-hYCMx4@<24mWuaYdBR&iUOSH>|zRuCwAzn-xuLZx<8U z^#$U{MmI{^64Ot|ho)~o#0P-XvO`YP<;V2bZH)dEPtlR*zxNeh2CjSwSsBp)$2CH| z@l0R-U&zj8(|@sh?qi*`!ai`l@>_<_?0cZ~Uyc+MUf;507_``sd;WZF-CRETLiu~R z4L}Q;_cvtz8hL!~Hy0cN!ed)^on_ni2fa97*F3$mI}yOEXtoKq(tQvd`DO@Jq;}W- z6}fI%B;%@$^%cGIbu@9${+TZbo(fTr5)Jz^*ZHMvW5Gd07*OH0dWNFe3U)Fnk+9(? zOQUwjW3^QW)2G&$u;EG&xn&!ee^Tao0sramr#Hi-W&XhO#?KP$LS%v1*JDSD_NGA6 z;m0(ufs^n0jYO$Ka6`jBj;!$lfVI%N9p3ZunLOw-v! zsQ*>@WT?mGb0bUV+FHUYx!+J`X)CmRC2=06PWpKcW8phM6Gs(_eI^-nG;6t`ZhLJA zFE|y1i6BwrfF`w=*sPF0BwCCi~FoJ6^UBC0{Sb~;|&&u{Qhz~`ldwX1& zNNeOIFL)6`z(fwtG~xcPAJu%VyaiZZL+{&Aj=J$S4{O*_DRNLQd$qYCo)l-69 z%3Y(;9g|)J%)b#`iCz(a`vSbKOTL%noK5D9SJ%6kPvueH7NJT-a{foq(XNjk#OU2Y zP1N)`M%eywo2+y8uiksjgWzA43kloT2YF!_SIkeE#lE-3T;i5_`M*snW0kxS>W?gF zW0iOm6g8z9G+m}NumFrL&Mm%<`lEb6LY{yVQD{ZYjgSdj=L9`Yw80iB<%T)-kZE`= z-mi6uqWej$>+4({CC&aeJB>GBHf<>HB|IBcH<=uRP8qjARwnLEmcdrIMblAGoFnPu z=kq5Gbdt|i)UzzGnGL#$z`|SBEn)0Q#^C*5@}vrd*c&7b!}c?l|G0xI?bsHfIj_Ly z%ay_&dtLW#VS4M&#Y1bxfjWOjqN~pHE>i5$AVAOYT!ZJ*b(^|ZckTqhzSMq@&EvNb zaLxE#(~Y-pfvaiuJ97*=FVPvK=b{-jiCZ8_Dr0)ooBu6={^y|nm(z3Ej*2Q@y(3vCgDW$c--xS` z>faH}=0Y7g|FEE26}b(kr-mw0{-`V#$Tsh1#r4e_sdgj?{yc@XBXU= zm!;E|GxONBFOMmoMLoQa%ok?n%={h!Qf*CR6HaGSda5j#3pGUQTsCjoD#^_ zZ$OU-$cs;IFA=0@;wkhdmuo}K2AX55M_q+v+HgJNXSk_&x3cZb(41|VEK-FZr?BZ2 ztr_>WKM30jU@J;Qa0MG?-W0m|XB@AV(xY-{351Eb9^qL-S0=*Jw~S?y#bwG)m}nesNFOabh9dd}f%kAV@#ag7TnkvOjhtzR zGG?XC#k{B@}n!}PgHBNDyQ=>?K?lq4nf}==l?5#-KL!fP@eI^B#Gj*4v z$WnnYms+7>$)`@7{Ttd4&d^@-`V=05`&OXYS&*+Fz%bHe3P{cBG z45gJf^Ng%=jEIZ_0H4v)ljoGqRznNWdi0`N&YS9%%)5Bz)>$=h+Z>yP*Luk1&}83q zM`ygjwy8fmB(Ob0uX=*qeNkSQG?#|<2_0OwMSU`uw^I2o3)rTLn&J305A0FI@O;D) zkJF1tmrU2c-<S_?|R|4L8qw}BlnWSP0q-hZp2=G zy!f_4@QQOYVrNg@$jM`s2(rHOTal;SuS+t8z0UcxFz40UB*&>-i`BdWbLIZo?zbeO z_j561wM(zJyl&8sU{T=J^Htu=`3C0z<^9`)={T0&gW{sz_UF>(-}{*Bfj&_Qrjxfd ztk5R@DHor3!OId5waZLibIi|s!S0~v&zEi0cic?qHNjzidBiH$HLLwnxBZ#sD3WlC zEtk*kL@yWU=ENga)i?rhW02tQ?b zPqh$(9yljwh_yZe6T&T|xaFudoiyT(Q|9Pk@S9;PdAz-T{hFWJI|lQRzV^ru48tgA zHo}vq;C&|77|c64o&V&`(@8xZxo?OudICHT z+%6=Xj%0zy6GD3CyqQ>&qQ?7f9_NMeu#A7f4G=(O4_|S^_#oot0L{c=m5iNuG4({^ zwBXKMpa@hXag-#8!#M{Y+Vae(M^E}R*e+{XQm|e$LTVlF0!)5R)8>xjI-i`VrwH>H z>&|nkYU9r8Avp~-#g}QLela`)40jwDmD`0}f;|1AGP{z?ErbQyrYWVQ+G#lTpr)Ll z>6W2E=0tzh*pL)>5XF?V5dRdagBfAMV4VMMtxx0Qp@430w-Y%D^X*Nh;~w_Nke2UF z_;7E~xpB8bqQ!NV$Gi7BZUCfk54hjLP1%+o>_yPv$sOMhx%h~4tB%!w>kM^c5?L3Y7#P+=bp=3|Hg1sz;lh-w z9fWx5<|eJ$VN<8_eJ^pD0j}4a{r!DS7<=SFHr2ncZ2%z5su7|eHszPO@NZ@TH9+^ij!yR2Ql#ZpbNoAE68_U86yt^I z_ccz{u&&bICDniB#;ITXTvN|^d&RG~A&fFeB&>OgG?mEa!|2LAvRG*d`XL$K>ck$l>i}6Co^a#2Gp5 z=Vsb>DY<{%8x1r?PjskVXGe$2S$2NYT>prKEF=i=8fcNBQ$kb0hrefKmCj+aBDtO_TupP^4;rglwet{(L zBI+v{($=~(ofm4ZKTHSm&Q^GO1Ah&8zVR}nn_GtXI0O=(NfD3Q z+?az;yJEuCF-%Za-%lyjV3N4wx%<_g;{l?7YjHm4195gi9L!@&P#cxGMQ#>9Bnvsj zcfWrUe$)`mX`xd>;Zl2)&@Ce*^FoeGV>t->*Rky)F0P=wuT_cNXU|_Utr)-h;neD& zt(*~ZW5tn{XOZxO9i1dslu@{xTY+-|b+q(De_txufmu3CTX-}NvkB||_~KtEv3&QW z?>RLvNLWhlmxo+!pA;V9;`#A+%jh&W#o{TFa&kK%{f4+=e>0LNZ~G-5OP`U23-@z6 zZIW}L_f2@~186r|A(qmD_Pgyv|`%06@KheqK5`+2`Te;rXFl|8V98ksyb#@!n0j`g0@ zt@#E)hj+sos(wI};a{5=trnNQSP6&Iw@$L?lKp}6&{_-@IB<;`?dXAyXR>ZDm6Ep~$AU)-z zIqs0I5HUwM>z#TlJaTOaB&xi80)O+GpHuSTDclJ1>_y`eHMJokXhu1o70AVjWc>)% zKM$|S#VMEJM(pMXuMW$ozVA0l@r)gJw~vZ?1nPQE9{znywJtL>sq2I>)NgBXnwEQJ z;n7;(kIH-FMf%geP}x=ysHTwj){h>-lyd|u%v#+Bu9=sa@EsR@o-uu4`8}RXH~>c) zelkvWU5VHBK8Zp|i^}liFG0MxH#7e8tGLB_a_(s7NHjX3g&z6V`-St!;c)~gTOU#A z9t`7jTM>3%x=IRk6Rb&Q+IuCm+H7Xk9bj(0PoZJ^dcZ?#huZ4~EjYg^aroeGhc#zAubOpzxT;+sguh8vWkC zuo`M|<#>!$ON_&oE0G^(P2y0M5K!>L(1r*UA@-Ev+8L%b^M$fgGa1{fvEDtOFElwt zk&#>yY(WdPAK07z=uY17R$1pt{`V=8olQAk;(aPj+x6+yER?Dh1F-4nW+{@Q*Eojj zAj*2I5Xr>f(nSEWp~70>VlBOBYzPRTA>V<@3$PvK{dv0ga8p~X&ZPIJL*JLo?`h}v z-fE?lFykuhZG&27qEQvPD|Q{6c`g$yKq4w8h%- zs~OMj)iY&AXS7$oyL))iDj)RADIRI!%-2$`&nj&+T=s5TyW3O;K^k%H8oEViAJ6;! zmgF6}muokL?UvQk>@%tqtFyUW3jd&l+db*Iac-?0s8$@igm^G#8KTZ0J~@Fj(S2z3 z(9?uCeAPijOK?mN#zvw7-?feWGlL#}(+S)aPd0b&&?;E%*?J15bu!VO`O+ZOOHEnT zE0inR}7XMditMNUuA7tcw;vQ_%R63NPr+V34b@$>ulof9o2~Q)zI-xh_r(yhZ zM#_qMPxq+}-9X?-$z_T;9+cR;A~xY*!=yKg;Fk5}Yhpk-K1!LUuw6e=(7;i479Q%t zsCwAyc#meHLfKf)>_@H&dsxGMhBRHky+D|hZi-YEotB7~J!d4lFnQdAbFZo+TkyLO ze&{aSw$U^)c|HZ}Ok&%7>}5(ao}nJXa5?|73PCl;;_vh^+dIMC>>6@-MGn`2)=`Xu zBPGLMzB72D%vK*WzLEREX=R3i*-)m;;LU=F+_{a=?)t-_Qn~J@7>r-Wzzd#DuI`6W znKDyfo8~6AU4?BoD!+$)1GR_uQ2}xD>D)kGyB<^JR9}+FfLZseHmIf;9Ch({{+Hlk0bk`NWpsLNB|gBrEUb{wbD{KIkx&ZW{G`iF z;z2vs)8&el+G-pMF23m#q|7}8pM&!W9wv0j79b6r29O4F-+_UjT&%-yS`0S+8nM4b zfd7W&H*?dJH@(&$H9MVH+%DIKiIZ)R_%35$^xEQmz3+MBNc?Zen|2{gq-*LTgh<6` zDfH$)&mQ}&u{FOUn4&I9+O_RwOWjmTI3T98-JS-D6)X25KtHGCL3F8l1V^DWx`~)a z<_MzT)#+dOfV=KgS2?}~QCb0%s3%eiJoVQgg;B@MT)A%N+7}E5zp}WrTwc0n!uMxl zAHiq!3!+L|$<M04d?6`%F4; z?SQc(%ikh-)aa6wLBX2O4F^(P6>)WAuGMD{ z)yYGj9~ePuek*tCDHJL`TN(R@4S#KLiXHhZHpg34YeFKv9qaV0H3~dmz-+!2uSqDJ zM-mu>bgBX}n!ZqVDQ4tyM;Xh{p*l<2@P6Mbp1SdlbC{JYaDvY3n?OS~ysO#wkK7Vw z126Z}@6TLEtfBnwk-xz3`Jf`6vV3sOwoyo{4B%gWA@3>FN|d)ineour{hE18FkV(q zoNrM+G_oN(zjGf$MCGZTK9*63Ivna;?xQ~ zvyBBXm47GNJBa@*J1O-F}*- z|LekIY~KU*YJr;}r)mXJ`(G|Vc)W)bm5=ipO1BpwDzd#;gFm|Ti2qvi(mXc=X43#? z2V~pj@J`lx3W&KI>xbek?Di{UjsLjSyT6F_~h{(VB(~(n{4@`tY?{7 zGq-`uJO7-s;=TOf4YJ1tkdxbSsfC#q!mzt<{6E25(*mYBZT-Qnt%O2xV~F`#gQC@c z)iZ|Glale3!Jo?Y^MC~xF++(kV#!48r? zhvHX{u^iaaf^+7WaMYJG3E&2ec&I(IGdb|dXDAZKL%|f>tD$LW@rKrF_7F_Kn! zeViNk(+S+a)Bz0ERF|ynIs$jkep#Ql=y~i8rm?WGfyphCCVKKXTq?THiSx8*S zM>}x+Nuf*K%dA?K^^mpiI(G#wP<6xD>kxqb#M3eo+ohA10|97=*Lp*o%7v5Q2{}0= z2O?C2N)8@X@OE4(Q9Mq1_r$&2n~~)ScJ(w9v`7eeig$z9J2Q0JvY@}A^)J^mM)ym? zx!34LaXXu-J#@#}Z2Z9@^h@RE8ztkIS&ZJ81sxG43W6^s@ppo0+oT#?#B~)!cZJBZ z`r)ytOWi;W;EfekIOIw{sCe^Z$hVRg1x9lJ*=&PabAYQbeJ#5-ZqO=T4&{eL}0@L;jHKQwhC+{a>qK5FT1JQ)867{YmsQ4QUWIx+K zlnhSz(PM)!I~aeFy9q>~Pr5)CfpwjJa7#-nY|Lr9^*8Pj@2l_C-7P6t1u%TuaJ4q(xjCrkee%#)H85tDc{l$i!_ZP$lVJsFG*Z~ zEkd;y-d_V6x+Z}D)CqC|Ufkhrt%{Pb)y&Lhe4?#2m~|zGj!u$Xi|exL2X?7I1}#j!L!lL0$K93! zSFlRHN^s(r4gdiZrA{i{!={i^pwz&3^KePtNqC@)Gtqu3O-)&UewdT)cmDV%t2a*I zp8Ws~XN2HVvPz3TrTFf}rOLiQh>XOSsrxUbIBJs}D{cQRalogG2uX_4IysGWrl zxs8xQTaRHH`&Ue#A0es!=QYc6+?rii?Gd7Z{vSu~x6O6i!v)?+O1lm)L|^MY|8%x= zJ*m~0cZO5yv?I#$JdKoxR4q4s=GS2P1=Gg&2Z&zS2;V+_qInTO+lLHvB2sT$+Hk@$ zcG$3d9$qQ1%v5^lUH$!Guni2k$vcRbg$@1W+QWMil`(q(qe6jYSvY`r)F_uHsLS z#}DP1@q4T`H&82suAn>_6t=Eg;vhOR()uQ}+wIPO!m3U)yaGwgvY)&$Bu)dy-^AK{ zuH+z8SQyFgJvm*}p{7)gC8kUFS=R;PazU4?F^PX1BL0v@N2{U3@Q-4@wjUWE{4;N1 zGr)Gd-5g%psA@C@`t<2#&b0({c zWqbajneicp8s2Q+Sm>}4C1?>)hluoc4{*Iig*SvhRjt7U$sFIfEkKJau51k7zlWCj zaTGMHFK*5cKT-6&Ocr6|Vq-2}LXa04l`|lAZkpV6A_4QCkznn6Ov3z+kK5L6wP?&% zXgQLOMJ+3iZAIYduA306v(1Vsh$x zn-1=0{;WbHa5mdpncXir@W0Dx&NI{&7KyxEKecM0^oEde9LtS?aJ$&vG%RnTJ{B|` zeaw(OM6-NzTDzP{J+qe{t7)o+sFn|FjQB*m6al~(Sl1B>d}Q81H`#=E;M7b zh^U;mXAl!6O|a~@Fw~xK6=y-|BUgzZZ@6H{+iXP~6}g&LYFvhShwcHi>XW4BcE7_r#xw*Q$OI-FRiGuY^>wK`Lta=o-Oz$R!b z(7o&Qqgp-dVy)8?THpDN_ZC-U-x3tM5cR zRPlYJZ2JY*>RKSdu(?Xl=Y0Mniv>-21eqZvu$5v6ZvNrvcYIed0Fm@peRaQ;rM39w zh@Wmlq*H(jg;_p|EW;XD{G{r)OitzTXkYuQ$M$kZ zcv8Vf>Z$}$*8#`gSlUNcA!*u(y$V1pl87r3(t}MPCQTd_nwKnA;+vh`mCv1`)b;yN zOV=PNcVAZUdqnxXCHlg7+5LNi5iJJ%t9&9JuuT;ZUMO@;boBBaI?j@aA~dU^Or0s_ zn7|YsY`k6tmt4xD4@F~jnCg{2THT9(O5ZfF$-Ga4T_gpnYRrBUF3Rx8Lo6N`bSFS_lqDaB5Ao8RayWK)pH+{oZ&QB>6 zK>`9b_1a86LypeAHb3fsr`LYdTdf;vw%UPinC0X^9Vi|+QtU{hN=T2>X7mM<5RpQe zOb--_h9ul&COfFd3`&8U68oKQ2khnQ%J-j+avD^z3CDGZVpi>au^-dMoKV4+%-iTc zN8x${HA_vM<^N53j6UzE?!`jN%y*qX7Y6&fgR8I zy!{;I?N$f*Pg_!qF|!`3OGZS z#NKJnNFIKO?!LrFR&9{II9lW;8Md#*PbY7AQm=XCat5X7Pdl`?+E`>YNWPzm+zZ`i zko_8y!zbWb@qTv5q@46dnkhb3;Q_4+w03%mcx_-+hTz}BM#mwHS$D&o+gnKLFjXsm zVE+*K2wx*!+sCHJ5AB7WQ>)M({(i#xLHq<##6%|YweC&RJ~e3zc>?~x)V4-uq5G6E zCq+raD>e^2D`GJ)<_|)j`z!n1_M=lxKobB@uF+gR92GuAHDJm|ss!Ft9gcQJs`>o6 zU$71wAR%n^Y=m9GXAFOAJQ=Em5zPxjDXnVs{bqJ`>?y;L?w%Y2JiI%IyL!X2sV^*eZ~(3k!zwu z5R9L7u--8NB~WD*6xbzrikZgol7Z4&!;`M>ypUiC%M}7#V|^;G4Fct(^aCIajC>Y2 zQ>Y%qFsF~i9dE?q@=t{gRcN1?%xha7@Loh-aEe_svCk19{%b=f+@!FA;%ihE+a@}p z0YuU|NfwZl^?e|sW<6?lf@RC|?Up?4rE0b5{(kpv?+*pTG9Z6c-7>1vsX89>=;170 zQgLGjGDL(&OejQmLOKmb@i@>!#0xmt>>++PdV)q+cC6(VypRgqEa&wP4f~A|R;Dam zJYfed}Uv92yJJ~s@R^uT#MI}_KESP7?K+BZoIk1EE@)RTiijY)C>%kp6x znlNIax)im;JkQQ4#(7_|jk?~xhCe@C{2T4!QEw(qS<_tyQn)+;&}7JhFrA z&%1qb+cCR{I=f}HQ7%v~pTaI(PhQv+Z0!bXU`#ngQf+eUv($O^&fhWgWu6-^yfliz z!rgAv2Tu3^C^{2)AVnGo1CeN?^8a4_bJa&jV||OS$NC}$UptU`)7O4qJ#m=PrvYng+Md{;%7}x+lB4WzT{Eai7~g7|8R zVG|CbAXNCDGj|M`NZ0R3j^x^uj;%%GDpcppCwlp>16_ z0xF^ohkVrfp`b~rQ^b!m;wJ+%K40NIy=in1RgaIZ`@vZ7-?NT|0Chfq0!l%KA)cm} zIp{>!o!!T|luToR!&kb zP)xxu!eu>nmhHXaB-r=oah?2Ok()`I@NBBkG6|2;L_te^(F7qgB{W(YFerVsrl|Sf z5MmUt(lX!&uQ1ot(mLS5zrC-TuSl?Yk%R=dhR+okfV7aZqi)vSkniZQ(zb}nrC#b2 zkG3n3VUUelIO}{};9X>v===N#6sCB8>%lZJ@Dl?lR>6T?q#eU3R!r(n81P_jbLaGn z*cH2fT*Jo!)i(Olg05xEN?4i1hprKu%$TPU~vw^-#UU*ClB<_2X?`3 zFej=a7r#QOU!N7PkwMmtBNafbZ8$hZZaEgC?1EGPazjFLi)5YZw)rPeX^HG+?!c60 z+4)=~Ww*6JO^$jOdpt7$Pc|2|y9b7}(Aq6&^V%uFm$D^&K1SYP=>b^bQd?YddXqif zEH1s*cGhgGCG;GbRCxwIoC#;4cr|lHL!d4tQC{XUSx~`LX{_s#91!MrwtwRIQ-9O9 zSEoZt7d?RP*0W$R31%WEqJ>Ub%2Zu7#?$z9w6O9U2L}~=TY?IpS~}D zSgud*w1%>E5?Ai#y};JB>A5p5@Z7JPUEOF=sdmAw%B9M%`M&^wm0sfEqdJnz6A_nB zpT@0;I}>yw#A%cvq*&x)MRf#(o1)@kXl-zKtlE2QfugCifY#x?TDLtC0)nxJ$3s72 zEMq((T3gb5prM))W9&FoQ0CSVwYGok_wo7lbtn$@n4S@*-6Gi%P@6`uT)R=U?+1jiQ?IcV2wKr>AYX?*PUO)ZR(Q zvG5a2jsJYgj50TQ-WJV5EJTeg9R?-H~ub9P!738@iW7LEeeD!wZ;2AP8Ub6QgKThO~p8N${dTMu8GJ z^nQAa9ebiL)k@kDal=6Zp$P{8$Q`cezGygIPa8T6@TF5soy62s4%?oIXYyd*FCsmy12Rhm(jQ{mm*&Md<+12LptvM{&h7^=^DyKxk zQ9+AmMDRZ!N_uE&9ua;X4yA)+jv_>V{y3p}EkGXR{u4FO{4OxE@F`!Zs%*X#Lc+Nq zQczzZDG9PEi!`(YqjPTJMkw^$#Nndf1|}dTHjHOK@L9JN4kA1epSNuQY<>Ne$>&Mx z^xATxFJ90aahSMicAg^Uq1FvkR4#n$r8ut`ZkX>xbQJ8r0`i*;se%$LV(Kzg8FLqg zyr*QQMaNlcQ-)@1z;X9Q`g*dvES0LTKonLY;M)U@N?XXG^QMg78(E!C{0_XXe1qZG z?aiCmVazjfX|VVsXwlILmVDfad*L9T0Hk3pa#(st&dw%4SlW0^zJBif64PPeHSSWz zvO!6oZxt4Qc<2MsgdVq z%C8GvHA}nUfpfqw7wl4`w93B1V@D=qqxbkjEB1y=F6n_jLzR zhA;GP%pypphyOg%KL9Apbe^(Vgkj->pRvC~%{(?U9XC0)4(b^d#$-IWRK zClB{Z9L8{_>7_#ppi5(udE-N6URrRt@etdYtQbzcO6_~_|4;wFM4?suP}Q{HtdyAj zJ@yq!_f^s>ggj+`u~IVUjiFDJ8L0{gG$t}FCTXI<-p^6e0MBj281|d|)wSDM*!S^u zo?Q9$PS88{XMRFLq{$z{cgITz-|m3aznxT^DRhuWD~)Hj^^cny?%aO^@24oq4gp3f z-figJzpxx<@lpZoy(7U)WW*6qTRVlPXW6po54Ud-hA_W3y<@~?@OEb@!hXL z{Gp;OI)xZ7aA+nn1IB{G%gNghp}yW>61z(@6Wu1t$G}BR%}|+62CYA+`D==NVp3cvU8gk|3+W5(z!G z(hCz75}!LtPcbF{9?V!t)Vm@Y$u}f2r}Gr-3qe?ef`IpKJ9IZ9tQ~4%?Z7DQ!?z4+ z+lO2h!xURI7j^lTu2>{#i6SfZl>H=cE&EOeUZVRyl zFgY4v@eSJ?cX^HLjjX+~q$b~5++Kn{b&L{FW9o3}d9ksBmXK-DJnscO77_XPCG;mk z%zT-V$+S^<1Y7(Vv&H@k(knwg?LzLxnF303NC1J{yE`|k2~6=bf{5T2a+kYi6RR_G z%!FUn6szRsnksZjcPd6HEo7Z$ooSo`%!!Ft*UgLXiRXnD8+~SQfP~okm>72ZBW^J= zeyBFu(emv(N-}YJEv(1rn2<8fYe)|hI6PQCq}&AY0BBa!$58==b3RP|rhAq6IX>gMgbaJe?j1Y^Y`P5!ey`~>fw+`?EtWcf_31r;y7>?hbdx6r~6PcAbmJ<`0m?MddQ`b6nw#hDzJZ;x z36mb9X5llSZSw3&_Av)KD^L>+Ze*29(REs!XvWr5Z+2Nsr*sXbyE3#&r6A;N`8=*zyP*9wKAg^zDDT{Wv|3QA$$VcR zy?T|vHptCee&TWEGI+3EA<6=_e7;BZy5&Arfdzyhg(M+?6FFE4AAIY@uVdR~5qVSQ zw_2Tsk1ZnD9TD1bU8NgHu)oFbCV#X;XwFG>BMoUGHH7^L}24C zDt~zFPJpB+CFhv;NiqU6)fVhrFwrf@lLVk9qskos5zR&+tgh$1wv;&btk7<6Ce=9T z@BPP%i891U)}fUQUi>Qggv}TRr$!&^5+T4gui}AZb^{v%aw!hJj;2CJ@C~`ECrZajIcR@U ztgH2&kt(hH#+Vt&><0^edaE~HU5k@6l{E?!v83g#w4M*@aOZNCkf{3k_{2}eenC@R!ABNK% z4f=grBN6Z6!^?-r{^uKeyOVfJ@G}yu()!jgL1DV}ZZ8JS^vj2swUPi#DDNa*6MP(z z#fjGbjjiqgaQ1-+xdr4AY6-j6SOp%&D645m+Gm=B(wXXkx?qF+;rZ2?5RVbZq2a{f zpanb>D2%P_#DMbPWpfu3?B=2(#Xa2bFYeezM?BfUq|ktJ8<-yo)L)Uh()7*r7G?x! z2z$N#xcC}-b||g^jU?|AtU($i_e2;fK#qpVm%cnGwkdri!3+I%F!M$1%wdQx0!3Fq zB5D1CAg{v;OmW7kPJ|S?`UeuN3biE(b2+a~N4W3Le+R(|#oX0~q2vFGr+fR^YCIn2 z2a7}86wm0({UXX(y!h(HlJ3Y2&p?LwFfq#&Rl57#( z^;2qhbZj#LV!(?(Bdj_pt}brzFT#W5q14%|X2>NN%t>Yf@xdv>A0oaW)i0F(U1FbZ z6kK&i;jg6W0U7;`419_m$8r8(ROwf$lgd-$wxv7E*p+>boX`x(K59iS9hkf7Q#79E zlkiy4ZT}UkaE%dbQxQ8tbARx0-X#YbSt<{^7IG)83U0s0Dvn(dqtZsvI~j|$bpUf&nRj1Bh!~6r?CV`Xq*)( zOc#Jq!6}%zDgRw8LGUH{SL<3VTq?2uE zDPnD%@&aABZilMseF>dwBa?&vzn)7zZyUWj|V#O>i&H`GLg6gu+}b+ z=ykf#eRZCVh}^&%c=X*URsQX1Z2w7cA(Vn!xX5NipKd>GYD&H!*^v5dNr9A(%PJk; z>aR!N$ILFl(-Qk(As#0)4pLxV_QZvMz~c*r8KFF2V$JSa@*X{=$EmJB)&tk_@_B>0m%W4EZ>Nb7B&f}(gr3mw1= zQ{IiN?KFcXuFyuVxuCc$f(_@}>YrbIPXwLt=WF$297GXL`;0~icbR14S^wsv1=ezq zcR-V{iv z_T4*71*D{2(4>o&eg8$n4X4qI6Mw2IK^+XAGE=zxLLM4sZ zt&ru)NKfVy$xR}b*VOQZSl**C?YO#sA?B*6zVBZ5M5kQ0!{2{%sW|*k^?zwF2H4)cx1|#8A|+@ z2uByzDx#*5V731Dl=VOnT2_J4G#F2Y9>CfNE-fe7yHh#@8z{4;ZUWA{i@P3X--o8Y ziCRwT%3T8w`8d;#;-b#LS4fRNre>MIRO<#tdfEvvjx7Ht2T-Ow46fZ}~iMlUndxbqa^mcHAtsprw^vuQW~JSE z)*!U#BWOeeZ}^(0#jfs*@g)81SZp7OiKd2$o2 zL1Yn;o1I^hgDzPW)ph%Dg*V!`QXX^di;hTL;~G$qXOMa)luwI zBXX6mk~~(rS8cCQ%hM}G_SXNQ>Kn8J0hA?U+qP|66Wg|J+s4GUt%+^hwry?hef!SY z{fI_YS6AhD8_)wmmkP?AApU%@y>ekAcG)sAamNvNTtNt{+*>@!*on9wS)+g-i1XBE zpZu!#;*%@a^%Dc^?B8JWDj~&G-On7o+(V8s*P<=}d6)8v&gSwSRFQQxi!#hU?Dkjmw)btQkU4i`;USd_I;Kx-4CwmnMieZHx>{#KSfYAJz8U$lF}j`a$$K$Sa@ zqXp4;%MG|PU;Z%vL{tF}hy>;50Sk1uW}gmxx4eQ%pY1D7Pbhty)?sx}>86d5?c7aA z#g+YWJnV;`#dDby9yojc2}a)Kz}+f15R(Vbb7UDSm>dEBmjrJzqdxtPp=}zE(DrA< zj;EYwC9uj0C{`2!2Xhq7dI)&Xg84UD^byeP#;Jwk-HnZCq0diW<5RM~R8`a%S?l)m zEnD%{<`TX0zgZ9Ik#Nf5V^p3M+l|OoIr4|qcJ~qx2L7hXc*QsTaf#%1=f!W{A@ifJbF8hZS zFhfQw|NOGGfrHHi-MF~?_HETxjQUXSZuQ8i%6JVxJ@T4Lz4||L-~ZXrGlDhS94VEX z?`t)QiP0G_zmcjgYP%Zt1xLv36Ev!$imI$+X>$zR#R(R7)^`mHAn5)R0)0#`HWuP>_O9Neg{X=A&g1(G9YOEsTjwK z=4kk+%3uEws}`nQt4)hN=U@~jM{u&gUI0+ttuhpxH$r^P3c;Z^CtH;-h-Ex2N~e(=I* z4N#*v=X);FH#}f|PAJ=NS2$Qhw{2`7yvfz>)enEb;`wK(y|v}QIZ-exEDW36;sp)% z$IxGilJi>G5(8_*A*L)vJwFU|{o2@o4o)FeW8YIJg+E*6`g;uNfS5BBIA&uuw~>1@ zij(ayRRn*9zsBN(92udleB(EnJ3b)m;)%(Ui`O&Hpld>qx3fd8bTi$>IheGcou4&E z6nOZ%9>fsB4H^1ML|iW;hxj+K5j07^5BOi=(#mDId=7z2f~vCp?o z8n_bn3`ife76b+U{cJ0FRU)E9) zGP$Aobp9-4X<+C!qxkgrAo1M?creyEd|d|X<($?k$i9^u15=3 zVo~R|-jOd*6n`Nz5Y`FK{$1`P*C!KJRxD5ih=CP?$n#X*Gs}@??iJ&k>aH%TNE+Qp z?9}FjnDB4&)EE*@G;EGfrKg0SVba!3d_DjveDKHtPx7593SqAUb(W$Xt7)-X*R#Q3 z!EczmLBAAERMzPb~Ixo4r#S{k1;E4L_i@|m)J6*4h`A51)$xOmQq+T ztAyF@vGBTnv5PICZ@i&fWZ~lpJ~Tx#0sQat>F9z$gZ2?8FLkPYdmB~rxJd&;mEEsR z@on*IxVh(FRP3KPbkp9r%UKB1?M}4(VT_#b#U6q($y+Z}p4+7lh6WRO?+OxI?OC5D zdw{8n<=xktoKT^Y(Go5|C7TcY)PjwsV?C-4%w4D{LzCv;Vs5!#|M>+;f`cs>J|cj@1bEYNVCLKrbg19boOb zp-`l|8FkAF-R6VK2@58;@*B`218&gCsCLJNeb?k4aqvBNU&9PTA;_=j1()YA4f7~Q zEWj0|ZHLz`<= zLzYJc)H}5AwRn1&v<||7jaXuUIsGO0|0FFtn63e@T6~5O9m)foN2>y2SBd!IaRX{< z7^&;WOGdSXK|(j6fwNJ8CVz)$2=5XT5 zj}|8RSKGd|J;M&*L^LKY-K8~Yr9$o_^4u%q;f;un%LHPDq9Ta4033p1!__;Yqo9d? zPz7LV!YkG&grjxg_bs?1l@!O8K;D4?GeoKq{5|latPh0CM>q`i1RFvseo|9EWVgcO z9IpF2qFMKi8S1n!+CrXRM^B1liXbMan0To8vDTf6hiE%=wX&FK-ApfK8>e)EA9V1m z9(fU6A0aY;TQ<~_1FBZ-O*95nO;Yi`Mj*NvV#`wEbv@{CQk&c}GXYot{e!Dgeim3( zvMLMmxur@PJ5uUWW3W^Ux|H41#zTi&-0+&6I^B_O06XxMZtS(XF3bXhfuejkr)}|} zNGUx5Y9^KC9Nms?gzwZR0^YI_ztvD=A2okG)xWYF zIJ}}AB~1kz45a=Uhd(^A^GO)#BOEUdS$SrpJa%oeuBBMk1Y5h}xw?)ny>cl*+I_w% znq^wQ&q+G7H4h~H$6x{$VUK~%>jU>xj4*v_tSFz(62i?+xD|9MRajU5c6{iD+J1f$buiVftsj3Gv@-R55 zEuR|Ha?S&w&)*5B0lxZ*7Y2QWy;2nby$NR~;T+WSzw3d{qYAItkHeD4m#m(}*Fx$y z{_#wv&Yj}(6+a7U`R$2joA!5Lmzt9kvF~k{7ujRRmKU7#x_gDodj^7X@x_jHLb74b zJ3}Bd7ed+=5N(dANl#3m=vU}2>axaZ9Vu>>Ue&-r^H>}~yUXCFGec+h&qm$g4Nq6-`?x~J&dKT0SRM} zUJ6?t_@X?&)LAyqJ8EvvupEJ0Pyn2`vo|pP;v4KSbT&fo0ZH2_Y2IdBK8@zQ+_9O` z_>%qDE(q^S-rGkU(er#*7zYSf*`}{l6jQFZe7q|}D(YO%b)VooB0=<>PK)2b&OBK1 z1Ybvby@wC_i@jOatvXhaSgM6-N(FNALf`}BB$4NEwmO?+A zp`4O2j1-Qk2La>D5Fp&6-~Iq}fYJ@Z3?YuGnp+7I5uAA~pYjk$Yxk!_COfxp2A+}q z1-<0^GaA)m4@RKU4!5d?Kmqb^JksY}^#SD7UL=R%l$fzdiwP#Cex3xqb#f)MxZHn7 zp9x9rrEOMNeBB~BLDX3c{s!S{WTZ6*qH2pt@~ciO-X>T74dITKaL4aJp36q_>%*Hc z$cEM58lP`~J&W{q1W9G$0pxG`9h>o_=<+xp3WkD8t?Z|-ayTcv*=#N=uli92XE?Zr zDGn`~@rMmPsm&8obPcCG`PQz(O`p*6(+F~Cvi?rimnuY&xFN_)+$jOHFCU*6pYeuQjxSyH|4ZusqKBsug>jM2`RV$= zJ^)>pA*jxuF1wM6WMp$Q(A&)idL6}w%k;ASQ=CZub6WQ5p+Dd6GvtRVQcsso*knH5 zOI#xb&=rATwCSSyp1^^PT6;DTf-{E*JN5u?*9M{KP|bO9E4CgPRIw$98FPW{E>iJ$ z68fk4Q?Ea3A8-uZ)AyTh<7Ylz$*#?bs+HT;8V%N)eW3RF7&zb%!6bh{Z0R5+Mnf_; zgY6xF_Q--W;)7>l*{)M6J#Q-8*S9~`7A7V)Pd-eKv(}a*xu~Vk;ve2LtX{G>nf)?< zCV#$fUb@ff8T__83IM-dWFT&MC(8GyJwh_);~kVwr&Y3a@i|w=pjjoi$n_UHY9g{f z$#r?6%ezVm!#W|hI^e?15PY8~fI-Qe66bGCa-qMmQ|eqV7q6A9J&!DYL&jrO($<~8 z>VdByHXCqijx~ezI75|ZD44ar*jWa2QALdXuz@QWv0R}t%UcL>493S zgSF3v*%E_E6e4Sp>v5~aTj2*}-%uJKn;eyFacdKfQd#$c}Gi?tC^Jq+s+#uVU+}qm!0$NkK?VEEq zbQM+=o~tWQSg#E3v6U$?f(39c=`O8G(&W+!JD0Z6+&3#p zk=KCJ@<0gU^?}f7MG_~ISJerbOH_>Jd1BJ;0}!Z^QW|-p3TCMVE7%!0ki^9bVq==7 zkpiPC-#CCQE5eq%+Im_99ko@7aa?d6en!JQLy8jvRsGr{b!D&o~N zNATCOX%K^zPgMMr2n{es4j;12;K8&OW$Gl>00=rR-%$j)o~;kPi?eMH%F^<}Q(_U2 zSDJT(Yv1Rzk=0lUGnU^5nTnV5VK*r09N@aoGq-J=Fz2qEt{x+6=BPT^X5JX-#IhkO z+7eg=TKfHOw%HU^xjHHKshKB}2V6+=f(5v$SWbM9 z2352O`R;7eCrV_1xKN^mz%_wQ6bcVyNyM`M|Xf)1kr z${SQcBxPEvw+9dlO6WTya7kn$Jjh3q{eLFjvZ(M>!XJPJ#@hm3Bh?ZAF$53MdgGBnFPkQ*0%kSXfgh)d@;I zlz=5eltPRl3NgmWJ8XP-K6`fCuBTykd712pKR@MQQAVb(-gqFuA>1Nb2j!)$pPDXx z=s(AD>CF|{Cr}PY1tsl3i7ajcomblA>+4*#lIf8SZ++#XO{ZfOlX$dUKAZzR_2l#f|YtI)yvwX6k=GC|i`Q-QngS@5I0?6Ejz`ZiNVyPEl^6PG!4Qx*;*Fw-`F9$FR2!q2o zE2Du5tfLX{r3s%e{Q~>=(O;_xcN(+x_jtIOfHt|Q$9q5$Zch)!o`=evzOJ}0&U4F( zx(BVDkw~|lpyHk{1WmtBk}M;o(MPzmUaUzLPu`_mf1&b0_;RAbUUWc)tY_KXePx=N zlKnQN1wq(>uN;k>L8^rY`4Qqtf7Xpi1i1O$&Wy@$s2-cSUJNx zVt4}IPFSgJ5AuRPa)i7bP~64I$OOe@%+44O(hRuXjNROvv~9N~N*i8z&aS|GwYuQv z8{*Qn{4tH=OkFP(gLIaqt^fsvySKQm0Z0A zCohie-uVgQ0vA`gz6?uA<2bh$)&f?UX)i>@w8;M`)aMf*A&A60V+qMIEv5o<3g{p> z9m_08ekT$%9aWHQ#T{|RrNWdw-wf_wvms4@v9q(E(b6esG6<_qDu|Mm&bxLME9M^$ zE;=bixBvlNb~RRvc9>a8uEP28^)7*GQ(Prgu*;Cn4;akgti3hV3FQudw2LaPHmsRc z7;Q48lg2JulWbMn_0B}nBDpNll|5AsOKJmZ$bL?~@!c+ls`HorA+~CgIfi^B!gcF- z9lD~3ddUZNY@?$9eZrOeMr!=DrKyAA#O^j?OeAz?KCBH}_W45OGM|xb2)1Q|iv z_P2cpk(Xu?f#}mr#uC>GNVp3cHPnKMsoU}lS*H$ju#2=9Kp7cBR=qW%I?d?+?FGIE zK^SpPCcNDm^;R!{kDnP9fhox;pHP1dpI@Kd{BA4NtA26>gZqrZEU6~WzGEHvxgVok zu}cra;G2lon8z;{Ehv9dq59DqsDi>{*O5SK?2bcbPo2OCWQyGh&#Wo_=no)~bc7;o zJ7FEYRE2evL;38u!=2600Yg0&N8p_ad^+RfED^e=P6c@_d9McQnl8tFnq$uo7?{=| znPYL!M~o)GfrOhR$qJ`S-`DqHYY~8UrLDVQ-8p?Bm|%XxPTA8}kGw8?B%EU(p!jN) z;~((vO!d~9sSxu}9}{}mA|wP|!EhykQF5Miq%78f2)+&th{MYe*{@(NL#r5B_`sgk z5!QduEGAIC+G+rvd_vh$8=C6YBRKDht1#U*O$xV9$Gzq^LU8e%uCQ=$xG3riL;x7f z+=H#6D-*XLkSx|9Mu)R4?syObv8seWKMI@vM#diO)*7&gL0fnkp>lsDEn8m}1CN$8 z+E;50zBjJzNfg07-vw$ir2pn>%^2sKYbftHQD1*o^7qyJykg4!oE%u!iAG&WzaTX5 z5@$uyFHZlKzwE7%L5fgbw=+18|3av^2|&3&_K4pzjcVrwAI`^!-ybHluxw{3iPj_% z+)E~r+ROl1!^8%SB!h;2nuVrmQ`AKoZ2I&D2&%Tvq=>kUu|xo4X;D+f@^1q^eC9M8 zHu2^oYt^CN@C`uP6p@x{aIEw|g~+agx()ZkRZ19Kp3wWFDVQ=gzr!w$cekC{0Bj)a z({&JSV;F|XSrwD#>=Dp}$yRT?a1bC}2#$bzE7KRZgf*9poNt*tsCqRSSAqa)r-V+%g@P%DM@tQO zwxo2^Z($^8s^T2vjkNhYnfqKajDP=9fIHUwC1g&fs$hOazKw~MwaXjIuks|oIdckZ z4~D%IXqnlhmerXdtPz{FXy`75*{p;=Zqt+FiybH;Nq^G7`#`pWWtCvvT$ow6?JZVd zW!TOThSUBLY`Qh1X?s^EHG}PT{+|GEE(Mz8kkEl z^)-BFd{n1!$uY{m(LoZXE|A5`GxY1HC($mEE(>ti0tk({y$I(X=%x@gmVmCO0dl7v zC_O(C$}@{7cCV}rt)Np{GBmc*j}l?Zfm1-@?*&|HWMW{UBS-+OXNSo-hJ3Gr+zNa? zd|~)Mpq9Un$m=d+r`-1+^g;>?@t+e3n9^b9=QxgSG=V91g*U9c_8z?)cgs_fs04He zQjT#S)=lN#<}pcBP~pALCB(#bCA_8cc~1dT}mrJj~bZw>$W{CrUsHSya9&5x!y;nl;aQIw=`wXrmDZ+tg8EO z`eUG#nE97WT*)zPA!n9_f+58@v2s^q>s?X@ZQG2yomPVA@x@7xpa{%r*Bb~`8k;td zeJK^Sbfp4xQ)2bL$cV?w5qTX7k}pAmsYs+uw({j1&RH8Nktx2}?9Dq{MfSp2h2E}@ z+z9bkpI0Y61F)>5NiHsiyLORD^FE_sGC~9iFF$W!22NRE!(|h3%?d`581Vamq7X!H zML%n>yqVB$3lN09Q%0*%k*S-i?R`!0fgrKA->k!$pG$&qw!*~SBs%fsJQX$GaIp1j z;|Uje0hnEbUs*p2cYeW!X=Ru7S1XiA5w@qZ*#-4E7eQx03)4pOZ)}SNL{9`F7$z&V zz|NzRphnoevCM&AA|z(z4A~~G7B4!eLuTN`6U8L(^8q6KczLvmfa=Ti{hNl z(MQM-X)>~cMP8)oi2+B%k7?MYxW*J~*-}8@tpcDCM^)hKC$}qhd{-(cpCJoHdvLqn+sr`5i zRCpt)2v#JByz-ZfDt6aOYuVgpIXTT}#mt1Q-~`vWNCn16#qDHYYpO_06&S_O0^R~~ zqB(AoAIdVV_Lcs2>tg^uMDgb0i66%{)riT3QSBiclP|v^BhyHcaOP~AraF7c(C<`< z6=ZA{S$gF(!l32rR-6qE}#WV~v zLL0F5js>PAHz1hF{77e^f?SDq{#ajnmP!2R(+B2sYzp?`r#nnknoS)cs^9!Ss6pX( zX*kdX4e&3OMUP3TQU1Kk{amsW6ZORvUgDt5^%vB<{C7UStH+s(&MHY2bKB=i0zpEO z>LL+**yc}nEE=f6S`LG=L<(W6-9K47hYm-`i)FeD$!I9tS|i4UH84BlM%+}7nXjd0 z_!ttDwz>|rb`gB&HdF2pafP{mcu`oQLjuM zA^@czFm^?q2fCTI?v?_mHdm9$adxQ!FXr2w*;g_T&c-xh|7gZ-Ko4IxOvR`=lFL0> zr9D>3?18DQ!v~+U6qDwD3}Dp~daXUB57f*J$PD5i(u#M|0CKGjT~5?%s&fZ?5|4+| z!({P1iKdFNdS`1HaOh-YdBGSyhZ4%&&gi$G={_zL4jV1>+_tyA8mLSXI(qTP#RJT- z3>}2yk}W#R=FiaaQ=0v%^JGYxQc3zePEfBX5N_54wtgk8XuB84*s?6x9PdiA0F*~O z$5xQ@2mo+d6?nzjB`;P->^s!z1+~Tn`vP;MJ42{i_q|IE`ui}3`>rT=alNUtzI+AD zRQ?u7)mt?Es*UBMPun+IR%GSbF^!oHDkrS%KJ z1U7{*@}w-P^Z@01n#)5#uK>_r+;&~t4|u-_RQw-+{p_x?9tU0`T;A{|w*f)_>V+|^ z(&zwDr1sA+8bRDBA?^jpi1jXq?<@r8=1TnYu|_Wc^Cy9-npvGgnd7vK)OdY?5dV`g z%B|k<@kQoGLeN^kj0S~-yS{W7c73pTw+MpXe>G$)x}5sMP`3!wDe+Q3^%9vaRVYOD z#_1*&a|BauY0zk@#el~OZLqF2`UVqyXH@^ns!F+82ALq5<_d=nJQnb$61i&1J=pU4 z1g1$}w2mZMrMSA*QqWQ=*W%aGy)TI6`oPY03+7ORbcaFSHUf+m>|NVsn4Ix4R7bEx4e(FlV@kT6 z$bed9o5hF7ScKt7t=!l40p*lbTWvzKpv%8)xiqW4ob3#i=ki762aVM4IpvCc-J9}! zmG^`$^G6HVpn@b`oMHaV`sBqNhQoToF>fB@S%lYqP9d-r~Ty){?i41X@q}hj2s-% z{2!Y;s2krO*N8vf=eTxZjTLj}|10CLc-V?u@djotDE^yh$C~o|h z?W6aX21&;sed;?Mw7SzW>JVP7ahl$5zm34tJ38FeE)UGoprlIvpnw7Z(wsmq1zMmB zbV5d+hzPTni}Fo2oz~jJ*d^`Ixe>R9Prr@-dCxx-Csz4Qz14u^GxVj7IZN_ ztY$2ZB-Pj93aCx{gz@u+=UNN5RUe7zF{n&Bo05?%paKLI)LI?b)gHV-(|!WeP^iS! zOV%TZ%+EZfi?r9_LK?4t=y3&+n~C$FbhRb_hg@H)9b$fzqti}fNP4VXhupaZ!Qu*0 zy%5TOCFXT*q0UAZ{v(lW@HhOlx*O?QC8U%ks82m+qgNF(u+RjLxpd!4mT-Z8*pEBo zTz!G1p%FFR9;M(9cpe8XS7jYzQek~Yz?$)IfFWVsztBF(D{1-o>G+{y3tY53#2Q~VU2tOa3a`mhjlbp9rBlY)gxBY6pH$C?!?4N)oA7J&j za(IIiwI0}xt>N`1>v^GG9vfZxckXmH#@@ zmX&N5W0~O5id0T5b=csVzd0q8xV=@J5rU-4DpRIT{*;Xkq&g$X7?qkN6~OAISYB+E z*c1s0>E-N}Kwc@%UP@6*Aa-x$Xw?78xTMq;GzN!51?gNoGhi&?s;7%}4>L+RmZLv;8W&ZOj@xuNGCG=Jv2b1!M8!X zVnCF_R1iu6DmiUwv15;>a@3WS-9j7u6HE`vI9vUALvmQcLwNFdt6?Ac;`91Ad!W|t zAZh+t5gUsR_2Kh@Zmbq{zvWeMf-wfQG(i%d0#NHoAizO3h?JitsLck@?yW1m#E^5p765!nPboh! z)|zDCK~h$-e^sA=9(3$vfj>q19KaeboZV}^tQK$){Xcx-0a5~94i%fif7${&X;H#z zGAlaeaIJM&MdS|o+ec+;tgl>hytzdeH3C)Ts0j<7Yphsr|g+DB5G*VaX8fk+!o!Er{@c*H2p{f@!dy7k5 zGC0DvLt?X*XseEy3t}0TL|tfQWg8lD&*lU)r{hm)2u|^9QVSj}*?^YT+s*D(C1L7Y zS^&n*PAE*h2jnY^Ct=93{xCDMIbixYQ}0QS328%;!r*hx+`?iu6Fr@Y#_($do3gbg zEQNychgg0N?(X}=Z?M#p0mKVjeuD{OyO-x~hb?4o>+LN1T+Nb9ol0=LCBDGD zF*@-4w$_ThUeShUy2+TB>fe4jG0nfvH?IB7-hhpkNoMW&NTXamk%GgIYq}I9s00$7 zuV%9}38Bh(!6^5A+dS}!GL#@cIL;lcuv_%D!VkZ&K@`3V7W`-DWtRlF#2QWJBBf6Q zDH!2)_jW?-E=A58qgt*fdN6`Ho>~%+2t^E88;*({oG}?$f-O&xQiU(YUs(Z2ONtnn zJH`aHzLFwh_NRvP5=c~sCwgGd4_3SBC2V>WD%(3mzeb;s7u`&Z+Ntf zJ`+v=JBENKPxR1*>i(cyPN;}xvJzw2S0O?dT{!Cz*FfsIBmgp_0jr7Z3-K6oS&?uJ zrm6NXnNXh5yNq+l3w2g`M)wRFtPk)fbbvc3xglsnT5e?e)MVzow@!qsGF`AJiIO*F z?O^VPlv!s31Q-+;g;-v;X>o<611YA-#A{Cx07S%M4k9=@h`m_d$mO_Z!Q+b=7l(JI zh=v>|FZ%~4Q|c#IFex}kR>t-f21afHkJT{aElFkd(a`_ZdPMKgTqV_%z+P9X^xmJK zie(B@zhSA%0*rWti|!4gu_xZ_P8OKdMCUp{X7SXmT@MB_+`^PmAx1n`h_qu<-}I|CGd9mb*v|hQGNLyCJ!k{KIzU?-$jdmzNd- z&no1WczC2nlIjePw1rmT0w0JV{?+l^+nThv-54oE&gF>HIa#opvaIc6u4R3hrx>Hl zr@~uLo+_90^hiNC4^9*QHOAmEwb=gVe_(xDssx{&)J#bV%AFTt%SO0fp7^QMLMNRB*(9 z9_jf5o*sf^#vs4u>bk?4g&^xl@|0=4aF}R_=Ine>FY{tWt=B@PKa~HhenWGkFEY-C z6QKyH8xoYfXAJ)S%oW;p`tmQKlkay@8&M1e*pW%reYxhjUnF!;eYSIi?%YMv* ztsbih)zF*i)3_8M*Uw?xM)1=#)nRNqfpoh})a@?EnEN?U?@$MvGj%@B>eAWwQ!FB#gr2!DfQJ@ME@K>_N?HqUob{=6onj&B+wJ4f_KQJ z?h=M6i?8hA!Zb*s#ts%_|C=!k#1fNB^7XkWrs%>6QXBQ5T0s@0u2BH|ujoqRhWqOD zeI-|aj2OO-t+=!krP)d??*x5jpuP-ID13hEPu|lA%yAi5NLm$(Jofp?^RIdRMYQrE zptLsJ+j@qoou#Q{0jN78oghK+LOHhQ6e&`B0tTb(jG11>B^&POff+Azj2?5=SYtbx zl`c3l{Jwb|fV-;vLbUlFHqs;>xe;Di(AM(9Jg~<>*=8JMclruS$l0V^C0Lopj5lG- zOcal)V_to;lnA26{2=LZ&D-|SEw`|vev6X^6^HP|(xNTvqfu$HPO9?gd?-M5m-&`~ z&yMlNG)|4?_xpnO%akws$E-1g)<_PehQT;?(Zc2p5@T|C)||Pns)1%BR93NozR3@} zpMQy*55h{%2_DYR+=2iL*wn?G(xFOJLZ-#Bh*}a%ye`{nQHgTE+ANt=dhd@hRV}ae z_asd`q^DMTM+sXEp;cabB6QPTzGZl9w7~;9UyQmtl$q}<%0;y*`(m%2W?<0I9S2TP zE?rdC*B&J3tn*Jc$HzcvJO=!LiY^pk`gC)lY2Zd6YnWfktaOWuZnwW5>QI(+$TV51 z4QR}$JE-uy(& ziX~X(1VL8|E^8=SPzO5?4OaX$lGu5AM{DKZQ;b($PYJ`{lRH(wamBMMG&YO|)+3g) z4gE)k66@!3OS~Dr;OE9K;&l|`B0mS*HvUefgB@RTI0Uz^u>wX-(x2uaAbHPZn8IX2;1O`SeH`$?xE8_SbIdF5i8SH_L2 z^GMb~#b6+i@b5h~3CF!L-o0}S1kh+(g#S4%7I%gr^8F{g;u~@|Bzh!MysJA0QN9^> zCtNCzMfC@s)~6aE2D2$4jo>XDp~;e;NfK@QZ#d&Tzm2Z;t9*iJQAZf!nqOqIE-yP> z(4h;VOG&C;sj@qpEKxjPLZJ43n3V%>lSn9R)o#mxhYmBdS(2BW!$&w-WikocCfw+g zNgaJvfQPus3{Xyo=$Vbl)D~oMAoX*BepOOlgjW<$y4kLxIQM@E@e1)V2y-E%3 ziXc1?9TOB2Iai*^ygaeQvdIyPU#bxoH*9DN4Wpt3^5Dtbnzb!?(K(YTKhi7FvRVUQ z5fcYgv03~Rn1rPN5rhyIbmv#Ij=9H-Pxx;_hwFeP30N58=cg(Mm1H`sglDNSmT1lA z{HJAj!K5RUljm+*)?XiF231&GvG>j`4EVz|S;`p}czH}*xGrf^O_sJxWC2O*CZQnz zvWT&>_RO{h?3&k5Bd#4dx>nh;c-Z)jtV-!Oph~hTK=nK3T8g6^$_I5WyI%g%XOw7X z`|PRsDL}J@M|m?~RkQ7h#;+L6Diz@Pc~eFqBn_g${8BCSenYl(lakKf$@gsV_6&e^ z>tW@Jd{U_^fxOqr7qj-h%-wubPP$Z5`r{*t=R9eNP)%&Qagqsaf&0+?a-VVdMm!nT`sdSQ@8Vb6Mh zfOUSB>Iqe}qFeEOA!coP0CZ`!^ldMc+M$JlLL`u&eQghj!@(7Poy_z}JxslV*ol~P zeyJlLc7~%hthreqhh+(>*j`$Jm5sl29r==@G5f&F^C}*P7CCe_Pf3^1^QLP5L;0^J z<9~S-ML{tYzqb&2;_U9g>CGP*;vDf^{O)_3Wfj`tOys^PT66hp;S(b{qP7nfWuQt5 zRGkzKTs>D^GHw?!gpGLxM3K`_QW(708@>pUnX#9gbJAipgk(;6{3=fe8{85(4U z&rd*+=d1wo)03u`2SF8vGRfWIE+Tn*50O&X;?`~-cREC6lFkKDUhP=eU5k2tASoW=H4z33 zu|A|h158)~-SwAvebw6;M&l*T7F5ZEtLS#j0!-}1rN(5Lj6Tbw0$cz=LsVL7?gqSD zwk45!kztOZq<{#IB{!&~3$PnN8kBP-bZAIj`?s9u`c$O>;ibbltji1GK@u_lapV8b ziyzy`VTW?~n1psT$$|rYvA5X}u-_}z=#!kjzsrLc#|!=<>K-V_MM2J)NouLB3UFAhR~#mm^nrj27p9-8FsbtvjkkS(kG8_b<*07y zZ(n^?Kze3+4I#-(wn&OhFG#P!!bf#)ya-}TiU$VYR_Jw$Yg3g@#P$|ABA)}?^SdUF z-!ZClvx~u0ms`Qpo0|RSS!&(&9QfSJx^0nMOCw_p&SPJ_XMOC3a_ad3X@)TXu~!ZH zxw1Am69faPYKGS^uY`ah6)Nv^+m0)SH~@_8=>)1R61^~%9A zW)durIA}!=$X03-PtuK!xwk{K$zKw-BsNFrLD){XD%Uv~Tpu3vUksugBf}(Cl`+`C zgKoF(v9$q^YYBFHUg)X5L5axk)mRdy+7-0E^+&{69K#qg$YnEO2SPbEi;e5UbKe6o4<8Ni$?= zR_XO7ahThGX)-cc8*mCj#ybYVt=FMb7oijz&eaN0g8)H|U=UNg`IZ13kxTlML{j>u zC=B|NjzBEORhK5}!?_YT$R2bk+FS?BrHt0zp=`0@M%wu+!UzA(==nqYrhT*c*1=Z# zL(JQLs>5I4_AcXcg1Yhrd&mnIIWmRJ{~0m2_?%(e-@k-G4Hkk8aP!MHW7xH|jW~pe;q)uT=m`izL*tkbuYg~p9U-&?jI3Q2UP(|kz!vr*R2mF0 zk#d%f*wpQRDA%AW;n`OMgWb%WUo2}EV&=lknOrfQ?(u??pt&9p<$V%Oes5;lWL~2q zXZPW9JDvK&hD-zRWqmTV+Al%_trdv-BJ82Q-AOZo`W1dpLgp2L^((PNtUQqEO(bJg zVT!fLl>gZ2!>aRvi0N_krxs_mR(f^!g)ha)y)V#-uq6yH*S@rY7{R9@X(|PtV7D8f z0%ZnA<68R|dvJc07&HUDSebCxsYdt7#FO(dn+;i{=ncdM(pNk~ngvY|$y7nN)|P#% zv8qMwp)J=RqBvU)Fsz?Y?ddb)tbZ`}!=}%r$$%=#>BeA0da$2M zG*{7A1S=qz;xjgVVa}3tCM`*3{aLhaTu|jRE!C$5XaK?q&#K4QEvGd(9yY1Veh$Ot zI`2F$Ik);OuIG?#%JiC1?7n904CM!%X>|ee3L;Vh@WLZ<)frS@} z0mOscj02Uv)`oHcVJqae(|KkhNp9sry;v^D?*9e9|cuKTdGrKjMCb~ zURbfsBoL^ioS7@cvoy*A7rq(~(aI)=a_& zV_5;E1iJ_*T;@iLM+W*KP@F8bfyQv$w-Ago`&O0S`0^MDFlsI|Ir=>d8U_NSi2|%u z4I1&7VfoCqi`>%aAmz=|E;$KOJ#Ee*8xfPsYb#E%Dv2cW?mGW+;E!ek!dWo)6|C(u z$pDrX+v`QuVa4bW>$9$am2l22Sx2S2OrDKn9b^W`iSco|Zl?=Hf2O>)D-Ge;gDsjr4VxKRP}M|c=kK)L>#BpXOu&F?9R{U zkO%^$BA4$eu<+foDgOp?{lWj?89z}o>igIUsOI;EnhUD7S5{*ZkXn%xLsI`9VlLuk!aTrJTFa8$$&z<;3J_$U`ca=@)Z(8j0k*m+d5}J~ z7_nSXpZNbzpHN~fSOaIwCv{FMfSs@Ns#zQkC99ok6eT4@uk)!r)6f8^6HnL*rR>y; z(kZOm76J5am-eb41`nv)q3L%N*c=JMy!9OPf1Ex#^P2o5jTQlR8s4&=b4{Hpf?(8< z7D50JcN{(K@QBFU5qa7D$3JSq>_myhT5$$fEB|mj>B702%KVV1($Y2sW~TJA_5{jQ z&$mjWX^SxJVSS##af|~~Y;^)XJMt5idLnYKRZDHZZE+QbN6Rrm3AI-F7q-I)%Uud` z;Rvp6UA+C997W-weL%3o7x)xm2d>C^HZP)5-Enyvm>&HBI7xzg=kM zlPH5*@k27kh3MdkcsU}?wa9r^YD4Ywns4`n1xhIhTfQ)q=Ltz=hY-C=5)qtb?wc@~E+Rp({_N|ZGX-PVs)`s=*`FQF^)q=yi9d~wPL%v=Q2(J-5u zmr@!P(8jH829y-*BD8b-|2ScuF-_{j;Z5d)f-q$A|3pV zRbma-^|_p=C*kUOVP55XrE~v%lPKk$y`SCUxF4zot^nyf2#B9gZ%!>Fu0_-r>Mb6r zUKv>wEcTRo#}Vv>UXqv)b7`RrAdL9?O&^DvIj#8QnfLB3Fh7(7b~r!N%M3Wy0IFQ* zaGf#WlO!pOjWZ71vs?!xdz?w;Pd>2%w@5QwYl}df=r33bd-Spy8mS`1=u(1vK8i6M zn=RIECXgC8w`j4u?K~DY5kJFl69gS2h1{ePt?V}mfL+bi22z9c;bZ*Q1fs_4@QUMk z(+b1mom6?#gV@$*LuU1P3g7T1sx!T_>(QUz1X)E>kJ;|g2%5ZDyz_H_ml5DhlsGnmXHsNjvN6}2- zP@1j}j=H0;e2oY->x!(t_jo__#@uTYMFKXinT*W*`sBs#QBW@fFrSpI)(}kIUKxP+ zH*4QKScvGqCYU~#D9lkAI2ps25RgepvJBvbw!HcKh`&mnGcNLIU?_4o6x~RY*IltP zUXJe$Y?Z_U3}tu26^~TQ{jfjnNNabL!!5YMUavgvs%%0zlDC{=i;^*w(llD?0`(gR?Ty!rU%gZB7?2) zNl+DwJ_g`|EHz;XGsJCIWw|q#Q(CdGk(dAyiaPfx=GLllBwi2n>ria>G&bU;-~Ou+ zvfw-sK2j&dX|HpiBlRynH~yICRISmh%?F^~$PcqNEAK>Ay-n`;W%npSzg=nwzEoiL z=&OYHwF$}|S!Pci&bf;I5!O`s|E-S{Q~_>D65Bx9Ss3Rk@ziXC^)jNnR3TzhmdZZW zmrq)6s*gwA}DSD$PKDR^|%U@SV5$lUt!b zkR9JgUg~ex9rb6zH+>IzuQ;t-;6HaV{tBxvhsvG|^eRi(P?QTT+wwUeaYK%@G=axf z%uy66?^)6R3iRt+uc%&;@+Zuj0Ao5d3eC<9%r&`96@-y2qd*)nE=*`U-A$i1F98sx zY7xf(Zay%jzF!7LLyK-xR1L-md?0_!MespA*^aWBsr_W>X^p|kKjjX+Hc3=w#b;I^ z!d#fvmPGT~W{iiBlYb;A?P^S!wf-PcFNH<-u<{;dTu4{kWlXZ}ie?FW^0t61)yK<6 z30N|jLQS}(lb`Oupxtyse5KG~VqyMt3kXhW+4dfevH8js${^a1N8MA8loZ3quPl;< z_Lw#jF*Ao=e4mJ6mGgY0`2BgxVK3TmhI@HU>j^pBCb?Zyz4I<9Zj5$q{+RAy>b^ki z7nAE#KnEQjd4$VdW45NXzP70NT7EWv2*LW~`ZbXy7Wx?L|6%5St#6}|V^g(?XWdO! zKNx76K1Lo>OjBj-LT<&DW##ueh4_v^TiCfmJ;|(H)u3MMMYl2Fxn-phYPE*(-^PU< z=HQ9EXFs&#%e8LqW5w)7vyFPUoxO=}KAs}2_(9{9>k{spXIl+P;ilKn43mnNdH*_^kUG^9(i;h`T#+7|v zJ7g)75_sZ9M1z*9BbLz>NcyUuD7$3=S_v(2t07WnlqI7}CrU&vlJZUu($^6jrnf7@ zaCrS$L*qqH3K0orZ-fWjO`<30GM&h!HUDr+)6Z@AXlvzy&>#S*-4?2IO+xybGeqQ> zF=(#gk5{*H&js0}3 zfc}GGa7&92W`x6A58{mG@nnAqOR*vW@rG7Lo5adYKrgA9ev(3i2UtS_2eFrI1Fguk zdDw8-N{qA`0gJ-bMCP8%$ewOnxYCW1PSECa8=n%Zxh+O=jqYHPL-Jp9`qpS-q-x5i zym?j@jpbz*1`B;g?&cFvb-$qe|Pi<9L$rQdhfY_SFVK) zv8pkznhfre%IL7wBZG;jlz4*BwB!17;fK!u{zX+Jgrb~tX365Lu7p(%nriu~Y`iS- zINHXlWf)XxWMJwF^@FtOmrgGX8_mLyVGD1#`9&Vf@kB;6=1^+XW5V#iF|PM~lB`Y$ zA?mMW{0p^EC@4Vug&!eA76EKnlVQp_C_uJA4y-7{Zr6SyZj^c~y3m$0E*`B4EH9zA zd?u3WOk0s_h;N_sD$j%wk<{jmfX1UYO?GS#zh{}U*AV$x_3Z5-`>__N*h-w|{+#N*a9VC`{H^?M(f>Wg+f+I;_hqkf9X1U3qzj+HJ(W zk}r`>E@S9Ec@}U7od#5`XLHi93fI!a-T`|Y2)kkrT)>Q|6t>=X@pL?XZ<-cRW5Ld9 zRkPR{PyZ}R^B-l>H@TqGw|37%?Q%BnO8yXBNLjL=fZgLX$0}v$+h$a+Rk5A+f z7Lq-)GC)ffhfeIeZ4(YJL)!6xHe`+wP+5C? z3pTQ+x9~UH5-MJYNZ52hCW|^Da$d0nzuh-`Pq4)C=VFA{(-?d7ioUH92X1bc{4qzw z8gKk!hTxL-ov^gUF_hx6h8O>#%jT#=+?t41)j^(P=;FO)jo*d~@Gb&2_6&IyHX5*7 zmuUqYzd6N=95{r(wE4qBi~iAK_{JG?hwc$35}v(c9g*4VJbLVrQ+!5HDvEXN!ht=M zs+R^eZG~D(3O+h>pYJ$f%qNkI;&VYz;fB=~I&%&DBqNU{*3Q=}QTBY>fTbzSDUVWn zw6_}Qsl(JShFPyLGIx>OHn9qn!wOwsg)m}~nYw3KB1plTtw(~sA6LScrUv8)-h8s#Jy2{vqT-D1 zogqZ#d0aS%UOQ=h1guS`41zFk1p%!Ep*-SpqWF z(RUrsG&n@t+2})Hw99+8d!KtW{J5W@=I}8Vv*<|a57eD-GjUGT_A^YU1#zq&d8e%< z0@&%@gX953UWcrr15C*~^-yapI*^IR(K}KAGeqWbG?S{#PlKt;Oed|`O>w6H8Pfym zmxk6exvyU!VVX?0=eD$;TVVzdt+yXL-e7A5OrY4uOj*i{^Y$yM24`M30~rMTa9Y$L z75_kgG-`9EJ#W?8QOndUca0jWN)o<+H0F%X*yf6XtR$e(<40=~NwW^mqXkEVwlU-T zN}aNJ$63MxX3Dg5fm&5{x6X3h6=>tqu|VJQo!X~qRJy?J__YACnnjQQ2p|vGf1Bra zZr*&*@S4s1R#uTSDfK(!UepezbYkRGXc#wHAxIrU)bV1Y@@J=+yioL;G%?VW$6M;3 zNgFe6gT*pr=;}LxvYZ+5yQ9VT+|3Q-e;AANi+{3;;Khv_sii)x#e$v7h+<265=K~w z5J}8{6E(ytB_9CG>#42=byetHJq-qO`rlH6fflr))#+^ z2nWOw&2#_cw_MU%|7twuCg!SwMbRm;W?K0)r<&`~<(%YPnuehucEz3!^~VXcuz(VPGc20)4h= zAg|pHccPEMx~H-CwwVGAyX6TSibHr?Wg@ovzy+ZlaBCv*&6UKV7=oA5S`h))??bK9 z2;cUUgzyt^FGutqA0bu(i_3^)l$bqqAl=}L{7??KE=RZ8J@Fdp5zTxeZg~cE;l1V~ zfs(B&tonvOgoIC#|H3f*N}z*Z#)D|^d=5->XghYXc`>F-DXKg0ebC^qYdq1*Q%>-) zkjLn5LXG4xTF^Wk->_eQlH)U^^(z}8*nrb4WYSp(=U&`p5;H0|TTc)x`2ZVWX-w!5 zMC6sX)jHwQJP|Ke5E)|^owi8x5vYo!3h~kdc#wo8#tBeiL~6mi=D85>^RJfx0&Yk2 z2ptN{j|DPdZF}09Frn%VUA*EWRC(7BbY~wWL+vyO4cpx#l##m?r*ywmI!%8$-%ADW zqqG@=!WM)w-K_u|0$&PCwwj@_Z%<%H+NlHgm6b0%Lmf19o_qMq*WqU-zX3_w&t2iw z&m+737DJ>4&^jT1I^}-NAj{b}5qIeGF;~b0P>~Ki3CTRNJ*_g7z^#E^8!qHOncWkR zABca7nT;nCL(wG!a1a_V*yONEtHUkElT|#X(|s3?GFD*YQD7Dg21auSMpsE`+rR0f zFS!HXwAcxArS*+(6w1+vNR`3rjiF`D3_>lJ9xP`)Yfw%JCL156<*nHsu##TQu27=% z@TNi@KT9Yv*z2t_2R<+(MB>9o7(Am*qdj~}3&>TI*BpSZI`vEul9*_rvw0QG%LDyE zZD5gT;*Kw^T~nDSo&9F)#?$YU`$MAreiD1`3>FNwUv!DXqK54(U+*@2OQegYk zmZ1(NN$|q>UrS|0*EhpQ=kXL-;dkgD8aiy%Rn7t!>}{DP+_Cu=wBc1n9)7v=m9>*{ zd(GV^JQrG@34QF&$&v7}Mw%dOhx}o$9%{MqL|xy-y!?$OKpU&BMzH*Oc0;tzA3ROb z+^eS-WXwA3xfwXd<%d#0<7>;r7MTQE9a(xQH_W5|*7L6|JE!PjUmM1lKDg%C1)2&X zrH^)`30QRs?5v48sEv@c?p-qlXqeOxFqEQMtamnK@*k1*M=6+0Qrf$Ycge|RTj(pV ztVuor3h6FukI+SaSG^gMQ)4-4rt*6(bpid4FRyGg%0h)U3=eY2ljA23kyuvNv_CSXnf0C<)}dy_paC zuZNN}EW$AhJH<#pE*P>LQ}itCmAtAke`;Q)kVEnGnA~!L4 z_Y7+wWHuY^xVN{=zzNP-e&;@~@Nt1>QCsQo>}uE$b)VVYYD&R1IvNf%--afXy=D64 z2G$sY&ZvtYc2msK9r$48O3dB{W&9_tYPAh0`}1BdAtPJ}zO{{hp%-x=B=GSV()cIK z0P~CNfvMpDlN^v|Lghbuk9JvJTe<+*Wdhd!K22Efjj2Abs6J$pkdXjNi&Q82izEhS zXV|p$M9uIPgBy#m#{EPzn2r9=qcTJP`v&3_P5?EGr)1MucF_>al-V7swv5W{&TL?P zS{&gTQ+ThIssQyJ5jWbx2~KU&lj#7rY=2W7cy|n4wJ;7pyZ>l6i?^=hl^cC|=t=vZ zboW=v`C`rsS4MrKhP&#ArQ2KczRyp9+h)kj_Y*&+BbdahB*?9u`HvFh*W3YKJP$o( zsZ?W=Eol0ZT7RQA(eR9O-{%`pvYmR&9*7u`>AW@cOf=y-DWQCbtYCGq{4Ymguj}00y7B%Y^)CN^le_XAhE0$elaZZx`6enfMo_y~-^sTBx5$zv#l1NZio4*-t zyKQCqj=oL@5QwXd?_%=!B5Kl_jlRy0)IGN}|9#(L4UUNEGr;UmKIirNeBb-YzxTNv z=-K)aG=B}a-8M7$!JEP3^(l)X@JzwY4wJ}>k1!&KIeyUM$VVK;-ncd-wdTH1Bcr7# zX_IA+C}L42DaoI16R~}af|k8D7W>QOf_t8k|Hc3!m}=8ox~F=>r?6f+!sMTgjP>|k zzSW98V3VW%lIsh zV;&bK{iP$v{Tgmt`f_hn;i3ciX)pR&$Mu>_eav&nH#e2#vqLwP@n9qwBiuPdo?xD6 zv-T_Xm zTMxY~s4pz+wpXLaWVaCMAlfIU8J0$>`<|J={QHUXN28biR=z0W%b;_N(aiMvTk&kizo)V>RHE7v=HLT8aBaMa_2g6*;$_YD$|*y* zxW;#KiqmLEfrBbCEl;|DfR({i##*XgwQHvK-T6tbKKBb+kjnZOUc^fr=Rw=}n!dQD zZii7~P_n`oZ!rg7f2+UFJsaG(`G%WoVVo0qK&&I=h-@tTAWEQc?H>5b!9^4PYrs;; zS}{5?>j|zVJ(d2D*7VD51?Py9C}li}6v}8Ln!4hZQK};%85Ae=GtK^JIn$s}N68Zp%(aR9Z%wE9z4gCvC z-q)g7oz2L0)jGNHHbo8InsqYdy}HF54))yvTBZ$N9tlvs|WLd0Z*vX4YkBhXXN-NVMn&TfR7znC+Npb z4}CrK1Ziz);8gmO!6yR9J8}^JRoc-8-`y0&*!F}u4`Rf5wF+Ya-rVGZu6?548|U{i zuD6%e^R2O3C5fos1A5ok6`pe*_>)i1MSDuC3*6d8_pqlcA9fo7U(Ef+M8zq8-v@zY zSuWPulIMI13!VrBIiyrKQ|oWFh0N3LiI=*pjG;YTQ$Qqb!#&tr{@mOIi#q(A9n6en z0^zp}D`85cnl{jpj}1_f=~R!k;g1~bUTClC9+<|i1bC!W|IXx^3z%F@_Kj9ck<9=EqH3&xLwW9~APk+cjqeD1sWTsZxo;mv;s~*Vh0f3RsG6+Pgc9cChqWHGt=`6_$eWbI^RB)Fo72rk? z-BwE)ru%-jZVD^aCjHB$Epy)q@a(g5v6o(^?2Bt7mVTlAVVRY^t($fPey@)V&ZfJe zeZ?J|?|V7Fi3j5X2U~MgArB3F4p!J+XLhG8(x^TjLnJd6L?z}Rck#g|0Gm=Y+ySno zl+2`*HR9EN0`JQr=%yLnjX0$In*i318|Q?}@({ORgFX4ShtNl}z12y_1|el>lyr?U$bIeQ)O z&bh~YH%D=H=~gv%xA9v1<_;Y4;WJA$?y|1&sa8n`nq^{9JOs=@0!yM#370n`=WGBP zuj{27&>t@i0>_5Wf-U_2!h>3Y+fVvC*cPo=mq~3dWOj23HQ-lTFFYGhSy7V9S09c% zSnHP+2i;h*#x5$uK7TBHi?%jmKoGpM1!qcbK41`xywoqe>w<{6K!~0NlAvMeB^w-uXgx9#L<5cBpOV;*O8k^D0Q8G zbx7>i>QQNWYpzS}0kDaQBuS?)Ljay6Rx!Off@X=66h#52Xj>n!;Gi3hz>aI$=sOXZ z4g%i?nwJ6oH(Xs$3$1G&@_dS!KI=2Zde0?Aa1|Pwap^4Dke!Lflm zpx20*gO_}5NcvEA7{Mv}7-6nCB2J$p|Iko5o#_`p(qHk%bNY{e`pPUU^QBPk(xrQP z9f-MPE||WK7|G_yN6$9?maPj(f{ApyrZ&r?eQfTj?7e=UhO!&6d6#{QeQe@vILRW& zHKmsBD-6SjR$>YGnUtgPRySX5ST9|l+uZry4^b~=YI=XZyAQlLwnU332>j3c?q5y(50_ zT~5?H01Dl}zumw;f~|PV8#4eErveJ$cz&KtXwo5ejUIG;J7`6$uZZsE47f5Y`q4OY zEBaC+zHLKSoE}AJRgDs?>}#1lZDpA9@k~Z-y%rx3)8b47t84c^JPN-u6gn7a5a=oQ zmt1c9g-o=UH#a~3+?D4-j|Z32HXoEwO}Rc@t&mtXw}Kx6DbD*GM|A6l|vdhHqh7dT&mfXHdxeqpg&y(Iy zYBgWy(=rYWeSg{)Ud`&d={F&f!6Zeex`+L(d&e({AU{)vyA_ z5t{S(PC0*y)^Wu z2DWilHe*uq^kA**F#wwUclO<3DM(m)=}LkYH3bFRfn35oBM2T3pNDZK9m*mCy{^tU zH7(8PJsfvN>!+*Ur+L6d3L>z6R&vvg6EP>jamCE`y;sEXd}(#+Wq^|%${uThm<|zk zwCVED+v?GSeGr1x1kT}EP?v5BRTxb>miywJ9*XT0nr>QWZ}zKdkPF>K0wRXg4P12Y zewWw0^%eYMg`(%zN+f#nW-I!J-z#&285d%<9t;N_tdiMC*zA3uTi;pT!Hb(8sG9~= zoE>#o#RJb@ep5h<%R?XNep%B1tIz}Or^6B3VN|c>|FOCLq-E83JU$`pubt@i@!EC# z-7Wlx<9{1f0aN8PpK}6QATVV{%on)CaCrlHi_+3%z*G6OZfLoq0n6KwHX}NzX+zE}#drjw3~Hwd@8$6; zD9-MLb>`lyHV9b?%a|cVqh@Z|RwT}?zo#9l+a)R;43Bp%=CmGO*Bhn${6`3~jTV!> z>WG*zMTs{Q?b(}vQr*$Twa^}@Bz)iHD74SXs7KBG~Vmz3VT z-j8l;r_d}&{EO#MSl@$%+|tsSZa*4$j{IlvV%P7Ptu1Xub#(TmRajg{hIh@&g}k4k zj7Q4U2~v9HewrVmw9WR43&oeeu0wh`ogpR?a3)%rM0yOjT}8Qk%{UJx%< zJe@SPe>dZg7}#)aJYWq-f(PCQ5DdO&YQ@__?C~r_X#McH>?$h6%L@n@(blLcW;|u{ zv!(lQyb{OC$@>h15Vz^%!^Ib`MR^~{^{ana1vS74f15)IJnkD)|J(P_89U7=$03AT3pkoO^Wz!>V)pK*uJ`Q1Ua{OV1nZJyRo#j%#MgX0J_J1+is?+BpS@joBpF)4?GPeTRCePH}9sdJr6n0 z*%&QG_U?ztEoyzPToyyy;!Zu*n)Ciq3|wZ@+qKl|-0ibsBF!@+(E8+^<^+-B$?qVM z_etyF*9*y%(*?m6_)^l|RL1F=)VXS~l_dw%6)6lXEAD<(ho`vmdRh^2-8Yt}DYuo$ zlH}b$Asi$m2kvhfbV&gMcA%>}%E=okKP!MWBmiM1`?RIvZDHD(Z{6o2x!6k~Oqo22 zIS-=r&+k)?S?G%bRS^JQ0DVF{Z(n0u1q|*2fZ>RS##rYHb*WzRSk^&y7B|e&j8Gg= zgqLC4IRIq{9gy>?=3H0ULO;3NPJy9?*Mz9F9#XUP&R++WxYa&rq zGG}~j^0skUyh`$Neh5SW4J2tp3K4-O<+%Bir=o;GOr{!B(y}_G`4(C7A6T+cYPrOd zje8NRVBmU90U$6``Tsn6J9`m)UnZ1@RnzEgdfygQ4W4s@9%?`$NV~7N^^S^nl=?E4 zCSJ_=_NIGy?Dyv=$G4mrhqo(=ab4)jMFwxo`dRrHr<1sX1|pp)q2K!@TT>Z!8L0s3 zOEBfFAF%0Co0vOGk@a+8@i8T=)JrHJ7OPHd34vZJyx9{MNLN3qG?;gTzf^z5II9wH zGX=;o1D@%s;_t)eo-V}Vap4&Q3<0eQpEXYUw`~d72tZDgB?ZsUwO0BBt8-Hw38#4i zR}}PNB{i_Z&$fT;?YL30M3Sdj6H4XDGqXJyv6WH^J)q@sdxB2z5UpZpbnBs68;T?sG=@);_hx(?0P?h50eF$=al%h%*P9Xl7#h6Pm_Ng;jj5Q3Wu6ylrT&mJhojDZ$gS)z9sP_f)W<_8H zf)4&JMvVa_3moK|AtTy@z>V`mJ{g16g}4EoB-lL>1D2F-?{B$hNvDjMY@>KVcAC(j zWF)WXvU%c|R(rFP;x@M$xqHeLt11SVVUs^FG-dvOKRg1qy9IgPH&wI!pvemL-qW%i zo?OaAQM>TP$(3HFuH5#O*tc#=@wK^KuZ69&Mv_O&6$KA}$=G({r1q+60qe;2zSN*c z6I_IB8}Hgv-e8Vy%lk=H zLyT}wM9U#NsR`J&9K1cwsg9)M^`nEe#krZNF9shfV=sLEqLW^1kSkpaZ+K7}X!L~& zGkDs3#Z~0bg<*SJc_dtxzxxm$WAV4J9{91E0IN%6| z@$OL97+B$t0jFF1_^n&ZH(1{LrkI>~w{PR#2>;t}!}s+ge++2ZsNn*Jr{3mLq|~J- zbpvc~Yn**X9-^FTgSlEu*$#lRC36wj+gTxqm+@fV5UqyK0UweFm;j0f2`u5zvsKd%4 zGd6LTI$s+;m4cC%NfRn_&>_nWkBtu!Yit^-2pbm6^=aa7XE9T^-RZ`cYX?EteNgTa zptSFkwC3u3$-Yj`vj`s%1od=@y$m3P)V)7b>{V0u*9blkq|uHLC&?j2HDWS<&jrdt zim6n_Qi7nFFMG*Vv$eymsY~JcLA_ubRslky^ z55SMd+7>Z!HaJ}hCheFg>2exjx{97$^b&0%4l6^5Cs**8_*8v*`E@3Y$-NHdq{4(7 zvvix&5gD-?0MVjvD2F4B58(wfjpp1<5_j!?)A{>0y9+l!hYr*8)Fk|n$%1{RlDIIR z=6;y2+nf%W*9gZkp`$1WpZ7-G zZ7)JMFM{UTVSJ)Q8*L7%11q`?eA{5&C8(hU0CHLe)Px&|`l`%oIA1|rmd2u#DNCwU z-mx!3Jo~^}Hi}nG1s&<$Y%===4 zUodpZaRIG}f~e%**xUDtASqg!o0)DKuPMo!?9m;2;2?T2Plnj}xHTc@vj@(eMkDHH zPY=SGdf;a!+>mWCgjhWEpF=M=uQSOqQ_3nhd#(~ARPv>&O2sE*o07KyWGos;@yEx3 zm4A>Yeji)z=ighg5jyYnyY~;XO*ZUrx~uS?vy6^opv46S#vlgnR@Af3Q$KaL{Js%` zr?E(i2Pg)-3u3V31Kl-j+cdps&_rl|yGjk>~@s@Q|_?0$(!~qzu=L z_sc>JZ)#*BCjG2s9HgiB#((>4DT;oPjwSZ$kM`7BN8|?&pP5{sa1H-|7coIIH3r?y zhJ)lz0lU|Av)k+EZPpvE1Rgp5hgZJ=yB{Ux!>+k3UeC+X&D`ADR8qV$BXrRQ_{}-E z`gj-aJyY`oC9<$@F^a@$gouP$hBlRM3ufxM;b7QjxGP-ae#7JDQZ+tY6F}ck4JI*p z({@(aE-y!!40!IedBAI!86FvDy)y}Fq9IDws9wCh1me00u8v*V!22BumcIe+I@9rG zS{Ldh^2ds+Y-FfLBbvKDU?6Flr?ve|C9NERTGO_NoKDSi`hDSa=_fg^0Z`07YIPE! zO+)MR6(u1S^FrKQ2AUGWQU`KuQ@Za#_Y;!qDHF#Qme{jkKm5#;;i}abZ;d3)$pM%*0AxmHyXqoj;+Z zVW)E1bU%W{W+XP9jimvFs2K<`DtlH9m1K!G_);Vtq;YVV%UBfT^yT356u>)Tl+|AZ z&-a1Lhxg9q3wYQ#cHus+8qarAH@*+xNQoe1F7nlYOBEkGszWt2${|9f(*yoXsbYci z3(z!?&j8Tx(!6l2m%PXTw~YotX*+v&Y}m!=JzI8yL^NyZ)h z%gs!hfr&&;9P3mgwfwCLN8tmTxdIa(?P)xqF!)4VnMM~{>p;{_>|pEy{HWX!FDb~H zk>6-c7$4}%hjQaQLs&RRtF;Ts1~dJAd@|QoixuYkWX6Gmv5&|9g1w&W36*8{MSiJ^ z;0(|0T*11Z!Mf}X0Eg|W0}-CF3F&HponHk-xm1)@osV+mo-KcXTugvU$#k5oIL{TLp;`}n}|J_k|OnC!k{W3CPMS7rL=1zsydl? z!n#9nCU%8$?aJ9&B~Xq2-z&?1?JbP80=iXYLe+^gmIwPG6v@>y5Io=gY#)Hwj=MdC zt~S&_ZnvwEINukVTmktrpH~m7^mJ0NvzJ^|5zo+qmQf%&)ayUvvT{anJSw{M1@LTc z1E&oGO~s)tQE<^D?*Cx+n)%2J9;ppjq8O;Cws@-0`{tCx?5!Av-3UU=e!QS?OX1FN z_VH3j+|#1eh{N@H+ao|qB^Wh9TWX*_O&Dh)&^mtZ&~pGj)zn0^zN&!dNt03DcOEW3 z0AbREvLv6@89$y98+w?B42d<(1>=3c;NbfEZpWoFBsnkhUMsG%D6{|)rk5o{UfFYh z6Qc^6Q@qOUktwMdh_p~b=DfqYVY-zMrk^)POVu<_W7>r^A@OgDQ+ekv?Creop`gw< z9KH{a&f80$vP+;3(Su<*-;9ach(UHb%AkkMCB|hH!ZnuYT_XmPwcmreJpdIrMwJwz zIsRyMCj@2-PWMRV4(UgQ(~Uw&%<)cU2}C)EjGlbZr4p|&qHtnqn5uXz1mgBatl@h@ zbyWsYdStQoE)2sqj8a32h9DGi{IftpXl?Sh)t$V6gNv5E=8bMXew>8SUsYK1s~ioy z!j6<_nu)STS;HsQ8!7u0d-kC0zK>G1KLxbNx+2>Ng_ZtE zOZFZ^gef#uyv#0^)Sb5THUh7D>@!ysrXk3i=!Li6!P3xZs5XgOS*kK9f~1qPY-AR{>FjE{lgCx75W=Kv>pozhgaAS7 zk2r<_ZQa1I+AgT>r>focR&a)oYrF6k{II2?;8>w6W{n@vy8g20Ca~{nu)FpXahZ9? znB4+W2_8jhB-j(4TCisQmw*#LFf!W_7!lq)?-TU>1aha|vEmz!lId93EInXE20>zneP53 z+~$q`>c|zQ&*2@b7go3^-Q)9tx{R`7{8*I*q|>w+7D?MGzH%m{dnQD5&5gJUFyicW znbS?8=@wJ;Lt66&F1n|uR3_`*{N%_6&4k>IxZd$Ot1eJcsvO;0zwLPSVXOAb^7QDD zn}Pw66dkmFedhId`F-a3?TWwc45@uTd9A+f%bq#|<7TP$b~|8!W+4^)6q+?0Au@j< zPBtCYu`b?nhCa8PoeeSlj~0ND>ipJ&C?1w7!&vI)r69s72!#`|+B|*GGWXBI)Fad? zmh3(jNOF@05V3cI>#pmH;t{NhJ_FV}`s(U^=gW_M@T!y-(w=L2i?$|l%MkE*gM)6q z!QXFbGyTTteupmYO)wb+NbqTec}n0ZtV$ah(Ug2faPwb?fe^9xzi)Qx32eYY&iUTx zA$wkF$lKr3waNbACsY+iB%ixFZ#ghf*Y*H+V9@n4;Cn&mwSN?{w`&{+TeC%3?L0t< z5YMUkwh6&P;UnlbjgGfki^9JXk!2GVlpiXSl?V|cQHeZ@NRu=^2&!uKO9#>?~7BxZ3Pt{&(E&wp4crTQrKU^iW7|;GoG3~$t$tlKl)__KtV63PpJ(pXH zYqvAWlXh1ksJy97EvYIwm+YwC@X!OKPw~^;5hGqvrAZ6v z6KJ#@5_ratMM_pf3k9gt{cnWezXtDX&x`*B48Q%`&55t3aaw!EV$PV1kw7r@*PJ@; ziq1o`2k*M;&3c^N*M(pHNA^AC*-BMY1S`K z8TyQXlWG&hEjDSMrZkF;GSNyQdIL~-=WA?olurhHeWCckbW|43%k_4co9{=pyB+>F zH+7jZ^x!AY1F05ojOWcy#%O$QT%5Fl?i!>D2Yz6`t;m-Ecw4=bcJg#;Z}G=CLf_83 z2_Bb7=FH@j#n{vm7sNF)HHr7K<|d7JsNf7`GDT&(CPI(uxB-(%7@Blv8P~_g@5=6m z^o8prvG#;05fdnIxG4vpMkFn>4PBh^3ku# z-kxRDDo%5luzzfm_3qJMo(cZk>cc$ZQzX%m>md#2c|#pnGShY)DRF$nhEK`Jg2KrN_&O3AR~UI;vx#eCup#57L~tfqj#Nth4otr}%Ky=5s-%o>H# z$I4Wd3VjNXqF5z*Eg{8fe$9;KW;sv6oIflqRxqDY+-PTt-XBAW{S~9CASg(z^9--& zc+=a2-?5-kFlo`J%oSLP^Bp+)J{+0SZLB2DKuv!A_hmu)0A;BgqI{%4ic%DKzur0i zoWjSg{x>T}*^zmT%3}WB$zzGN>^2I#`raHVdSY7pR3w~U7ZlzzPi(!-yMFE8cpu{?AkQ*r7bc99)M>T29%Un3Red|M@O_Q>WwhkHHfeQ7Eic1w zdQO;~^vz|5cM!aB`+gpprdvsIo|@TD5E&;~oYIM^#wg~)ecDjn<)6}3<+ETT;b5EL z{1R)6Q+fz72CmSD-81Tfba@o~mrj(4IZS28nF4b&hqYLYvj2him z4bEK)c@+OO3{7w;WxUV)uPmd>W9>nC)+ulFY(qBPQYxPXa}6Th8mYC*1z7R3NLm{6 zf+ijhfoS_j=c9x5h)TY|A1ZB*NKP#C2TyV2Jpn6IA1nzL=#84-kuR>=nkk~(a0zPP9Jd$7W z(xgZMHOB>;ILC*>bLXJ^d+~klX~)g5uu)DHOii4Ix~s&$YR<+Bs1{-d)ob?Qq-Ss0 zs>XkWC#dBD2loE!YyZcC7~#<4O}NgO%~R@OV>yxDbhfYgyMRL?zg|-TYIKYutn4O!oW<7eVF`%lK#H4Z5Z7{CviRXgC+&}l1g4e(tLQ&8SKKD>^OSH!Uu%a zu9hdU2=%QRDR6&`>QJTro-MGwoY10$=T7@x6-b#$fDJ1FlBQq6q_$B5$CH*bN zit(%0G(4VAQbQaCD7+ZIj0g?hsb@xfe@X{jpZWxbE0*!Kb-X0jo~ zKyj~52l3?iV(7SCNtXFT<)8C$RgeBPB!)_UNo1T<(uDnOPxcvRj$n1{qZCm$4`4S#!HSS6uuK{{NaOqV(94y4y znMNtGmts#G@Ff-ffOLIiO3?Bh!@AVrdKrY5wJU45QD*g2EQxfcHfd~}DoM7dbJ9SH zWTO*yG!GPR$VM&xXAP8iK(yw!Oz0?})>;Cw*L77#_czq*Q}LA7Rb;~xX>$vjie?PO zLqTM&tx6q_EVsIUuzs}`j69BlM4j%bU8xuOyU43pY>mh(zFJG>CSZ~~;y9^_<`O5I;uA>$bXkyw`j zuRbjMyhfle3|B%F=z+FUsM32y(B?~_U3Y|H0Zf;lPi~E$H~e%LauTg%_RNK+c`Qv` zx|Gpz=0Lp3h1l!0t@SI6e_%>YH*`XcJ_|#Jk%u)h@9WZa(`N-la%ZBuTp3w9iaha{ zoJgM;=%;!+ViP&#(LSckEERR16H160iYV=9h)e^I<7{nAkkiBDd@&Kg!&LfVObV6v zy5Doa;P!DCV_B*eW(`hEyp!!@{VYc(?6mH2-Bi326EUKT!<@#HX(zR zT*TqnNENMEb6(*ykAHzwraW<23w>d9G$TKo1!7X8I^K}UBN_&}t+wpMjHr+;#ggIV$^N0pR|@-u^)<901?1s5G?^k3jR;wHs=+$8E)%`~4PY@b|BQ z7A#S2aJF9sJ_9Q}`vzIcf-2MGF8kWeYsIP*N`x*c9^GMFTkRumG6g-aA=;NX*bIoKUa$4)*AYS-z-=nh_u43Qx$&)>q;W z{!VN1&6*~w*kFsjy^z}5R*qfJj6VoIylY(@&}S-GSCSBUz4tPt@8QUEDrU>*C^6)tF#%?i9 zai`V7h&}jaQbHK=e;;MGgaB^HQo6}o+7F|I9Ud3TgelUFhS1d1AY)bt3iQa{x-zK0 zzrA8QeNcY-;}oefDwTY7J`07p8@WSn0psL&P_7=KbUbah-ubV(zEoU^F9W(dV73}G z``dg#_k77=1e@R^i#KQ5Z5{s_j!_=&irLxL3ENGTgosw)$wmXJ=)+HHNmHdsuw{fv zQ+We zz*FDP1sG3GyhckhH>Q6*e6Ir`^8Bza^I#E}gEPkgd6&>m=SD=sO8SiY&a0mP4(8x% z?Jwc98ER^HlcfP4wg<6TKmZPzx_C)AHK2kq-0o2|#QjprdSKf8EAjGeckLh6l7?Jj z7EI4hZU5JV=7B5k3TKsMnFES|H&WrL9I?b#zmhRv8a2X8wRs3LR2NB7CA>$DFOi5y z>;qA2UkX_;?ydQHh>wXEy0V&6J@wUa7%RzXN1C2!yU+iYckBuJ56O1mi>ZnI(;`>X=L=Iq37M5uAP8}hZhlWwC)tN&Jy4^3| zeq3*YwSO#zK6Y-EmC>jLMV+)Qc78$^G#SjGxi#n@&smH57MVGpaTKNgVg2FDY zb3q3hDrtg5y=KV)B|Jq$##g+l8F47f)ffV>wwPQM_lq6Q_gN=YfL+`Wr*XPkS<2JZoaWp8Eknd`Mhue=@M!Hn3 zwOErAAa z7o$cldv%Kbu_YDgrbq61r;jxYifmU(1roHVtF}lywC+Jars%uBITnHY z*69u**rGeqw9&j3Vi*7E%sTw9mQoM*^e*KjVzYjnMLSg)bY%W5Io!m)DeGF-{?(-&gkwucpn*6HBUh zHdg#I(^VfVQqo?82)Uojwc)_XYCZQ}>$=+R{ZZllpW|t{U#`br-Lc&pk0i2kz9WZ< ze~;!*#UGFnI_-xg4)623fRe2Pil9o0G?1DJ*Q?2xCSWmClXf5p^bee3f3 z#FdLdO*Uz!zh$u2qWlp224^ z80@LV?M8v@C_m+(Z7Uf9+slbo#nH%_h=XR$L){I?i+sr=9ubQ7`VeobZ3YGkO}YJ! zEnc$u5($v&vxW@ypsw3WtBNlDFU+@~Q&+o_;t5hO=I6Uws)nv^xPvBf#i52*+*4A- z%K;(%O|Dr0xHfm?1YIK8B7W4VD~{-0ZPnn!$?s2tFF2@2l$WL+3TD=NNq`#!-0`w} zUKnbwdVMFL`br42$XPk?^@a12W+Cb~Gx1j6u0f6ZjL^f4elb6yZR*avqG@A=01)@}bmuw5?t^2!U`@Oxj*Ohf)jc2C;WYoYr zBTQ}itj>rt;5aWs(vwHTf7DP!h!E^dVGFEn!Ag7;%E#~!2 z(3!I&$t^qen$QTTf|=^UNM3&s!{C^ld0;aE5UsNybDd%YJr?@vkl*x^S+EMlFJg%$ zVi83ZWneMthTAmxyBIv(c=`{?{vt1R&9tJj5%BCuUJhx>+_2Irh;JbXOyJ}0QKI6X za0E7&^%Os1qA&`0J94k#p2Xl8RSc0pnAI1vo>N&#UYXCa5@m8kf~X^>JU!d*F6mhL zf~!8ZOn$qMk4}`4?B9@7u=AP#^L<|S?Pu->j>DN`2dYiEdfbrjDMj~i z@LGeCR7V4GKXiQGp4%}rT5fXrLb$jVvF_J762tpQ`z$8hZg_Vm`qsQwze^Rgc`pqX z$3kJr0yGB-rd7}ESzxjb*_ z;r;K2UmWj}Z*+D&3lG~YlW@Y1e;3Gz)!ojv-}5}qATPGuVYCcxH5qJlCm?KoL6OPi zy3Bam2#Faf&G-~of4tz|OyS8RH)Ijny47E@=T$ljogYYKdl1BO8HRs;&+YcRuY@N{ zj|<<2Y*07qh()(SAc9p+y-SUf&|GkM2eI{{#1HCt2rI}mYx3nMm!qSSG=GGqd&s+x zeL zgM#2>_8i+0!V!O)$$^p7plM<5UqI3;A}7zeq6#QQM~yX6(0o<84Ac66S6XO*@zNVD zH+Jsv!Q1)EKMQI4g}e@Ce}b-AKl)POjP$ITiL&#CFLe0tIIUd%qDYp>^MS3|qk7a8 zp;y(c%#p>5AKp$dE%?QZ7yFJ*+8xiegHs^yRraHdaEpcmwkdSd!n8hUXb^vq*rFj* zXyN2_X3`bhmoP4n3elCo;ebQ7;M0S=M#UN)Fa5!v0n5ApHTbX6E10-YjXU2&`mORm z%kd1RXIq-(W1m(_YP3kMi`SBCHrH5X{|?k)kWkweZ3drw-pt5PA-o0Ra`h;G!{@qk z6r=^DGs}~&!)x}3F4yUjX~Z@`h+KJVG#yzuN$*l*teWuT4+TcPzRv!Lctw&qp(uHN z(BRE6Gx$Udai}Z-ByMc=?=zl>v&>e0h%5V4X_D9Ll?gjDD6ybmfa5X=x{_vkvW6qu zBXpvZc!;iC=gnX3fhdeSVoKJToqD#+>`3w5vTET&&p+fWsN&a0b~nVQ!buDHyn&-i zWa^WG$Y4^uD7KfotloCz@370^Ma=R*v09DPg4avSe(ej%>yK&DIku2Jg>hroHJ18A z5>*U+Ga;E3OyIc6X;E45b5*MTn9#$FCKYU_WsONa$9U(0#Nq(uH$Lp;I#oBbb3?{2t<(xO(WGndjW4!ItDH_cGI=>(R-R1&%A3NoIPl1hW&3Z7d#s=KN<0nyeyj{bFl+iv%Z|tOg)0xEWd_^j(vX59wq73UXk~O;# ziamLKJpsmnVKC`A@$EwZ@`CF#ic)nf{1{I)9|t!bw3Y@2`8-#Y`Z7u~BE+38rd;$( zj#bPpS;#!ntf|zuUT6*YMkfj7iSVt*0s7j55O(#|(5qXhK)gq+I*))W%$gUVNMF2J z)Nu3P1$gdDThp0`EBeGoXr~kJ?y!?zBDFdmRS9#=2QeHp)s;hXEguAO+g?bVe!Knu zjs@~X{vC2xQ5qhYuw+OGJn*8YSnQ^M(}Z%KLdPD z&)7(dn28%S)>(w8>>rcmRXvAvCj#8ja1n*{8V7st>mt}~LQ2_DW(hhXwh{S4fh#$L z4xT5;#kj~i#*c>BGKW;n2DCjJ!g|+1Cq5BjRO<~L4%@kJ^j}++(4~m0YBrWfHMROs z%{{~ZL5D3?F%+jLV)wtsGOL%;c&Tgq!L>?s#?;1x=BPGO^e(iK_kf$FcD=f`JaJfj z0YS#u-N@a5e2B0k$dQ>*=}9gmcHHld_sEuVMBwtNNNzQvo?C=gdMhS-;emFA8C%wQ zM`kummEhFA<8VDNVmd9NF8ib*ssfqI*96}AT-DKoU`F&CHOX^MeSvnEbJG-a1UkPi zNKCoo_o1qP+c2I2)j;a6f@9~DFeSPTM;xAF)N5crGV{z_WVpj8SC2{Gp%9QuoyjnO zujZ9|yJdm{QyN;-7Qg=NH*$}LP7t=xheF1tqMt+H!nWF99b?tPYJIf{`0r*xw$)0~ z5RR@s>USZ+H5V=Z=+$sdWf)7K)xo&rV~KfR+K4skcZ522|J(u=&@Wv^TjnuR)5qkr zOGWvAsQ=x)T^YEH8h=J<$}bp}mh)adry*our$z?M&?^6x6E)YHe47LRCfpLA5AHMv zJ8P>m4#%UHOLzY%V#!lZb*ojw~sCc#AAH$eB=bA*BOOE9CF| z6gGcjXDRa48|%1W8V)I12bDA6Nf=`-JhkVIrREffcNn~R3YLZ<-^w@WnC$N%QcOVLC9f%#HpFRRq1yZ};P&}8E zRMa!gT1bw1p0CU|eK}0`>0gP>;wn^0V@9G-Zc8`7sxpMur9ZK(UbZ_DGAx#EAO#Xi zp*1PvpzGh2GjWK7TkYD9GCHST3pP>$n1bVHWYVq=<_knO z#~%*DYs3QsfBS_we^j!ZdX$~frG}Q)rD;^CGiFg50aWpICr1$C$@x%2%9{~dl`%%s z7&Ff3NVQ|62~N$tLB`J{M#A2t};yW|lUQ6`{BG6VA>%A9Meu;xz_u5cyy zMx3Zn87i^Gj5PXst!J^HN%@Ep#2l;;;O7rj8Up?rQ;kaCoL3gQto~!?Mvo%#?!cDn z`m(Y8cW9w*;KTW9v@+Ft1pYZ>p>YR*tX>neGZ+HrP=37r;odq>7rpxAuR?@ZU7*&tM``r4EqfVIJI} z6nRls?LafU+?FrIR0lp{%5yCf+hY+AET*0@J;Bgsqs>SUEg^YIiG+GE2MNiZKehOfO!dPDb_YZw5Ug!GI z9t<>@HzA?FG$2j8LJfg=YRSi~tTwzdK1oi_^-lNxpjllhF<#B6h11aBw6!wT4lTy6 z%OWcqjOvE9uuT5XTFfDRGdzTM9|C;Qivh32b+H+&Pl`)VV*)?nBD21XX88YR%g<=> zW)R>&r2fRv5YlO-OBk|?OZlwBQQf6s{FUjxQ%tCbC62lI3cA>5~kzv zj8)0V_L`&(G@Fx;hD&<#F)c)l68$^hf#uwJ2%{nG*!>8VVtSX(&Z%MRHUk6^6Q~($6Q!KZslAkIZjT z2e6WodA0}jxFy5I`(RGi|IGqOzw}?!$*x1Kwe32b2X2|{b>Gh@CZ)*01Le+Q$ez=S zyOI{`4oYRm)TS#2E%R6AE+~g7o2&7(SSYW6+^*?KJm*;M? z5FBl-_J;f0^++W4amGtn5~O?EEMO~YI&rWXkU(XRukVYmlHgfX4519@VjZ=J(F{JK zG=jeS2o|8sN&z}LlZF)~VVG8ZwrHf3_0sMSE+#^#B`kM)l-tvoh|-90q^nzqOWeJaTr|nCV@R40 zLFT}V<#plNCGVTwsU2)+DWQ*0V5@3=qz|j{hhAudWcI2MMSRzNskQ=@kO7CoHBue` zoWd(VoT%s>ef99pmhIRNrptk$_zrl}%52B4VTax~;#NYf_cK0^o1vPUM=NI@vumXt zaWth$b#oKmUf&ZzQ;zhhw|KYy`k#nldf(=(;gb>SvdEK<;&|yqax8Cfl9HUhIc7A1 zN{;&TWC?_Zx;Mr~Y1m6b){h!p4Y64DKF#c>{A2-U9pH}!-g@l>JKBf44^4b=NMlw| zUtXFw**S$%Y8g}Pg1cVeoShx<^bW2}G*Xh4aM)1pBwexr9E)6DY7$;iYVP1)fEV8} z_A>kEl}qRFgg97t*4uogMn}a~#o2VsaYdb50dezLA`0<+fBP>U*=gZqGSZjWaI;{goYs~FBROoAcLu|WB#It!-u}V|7F59uH#(KmSh>Lgvx{v4IxJ!( z?ctlqMC_;^dwv#*C=dS-$X5}qrZ~VXpIJjVxTDT)aYBI@)D-T#N)fc+!)u5H8X9Mr z7hBg*(3pn*keM6(pVaWXBppWYo(*GP1+vlPK!LXiX7krN6AC`To6xcgy9`NE2u4D) zDw95Z#m-HeG3_mhf?=3|7|bt35>D1$I3u`p6NwDnB;q(0;E{b<;Oga$s?VKr>aiYg zNVsHT++fB5vv*FdCI-1{2eF817L}^}z!aRw&N2$FLqZ<)=jDqgIutmaQLdSkU!OP}YGY{@Wq#FY@$ zpNix*PWnFgC0!3rMky+MskeM$Q4c*fc`CLJqZbq`BNyCe-$U;U5gIgD@d0F@{%=<1 z#T4fZj9floW_`t|t#F%zd^1!TZLlI5ip_O+;uuhZun2mMl$)XUuftwJ-OCh~X4c$o zLU@Jtkuhac&&QdWsD{)MVlT{I_%})sQ23W1uEk!QF;U#-7`0@SSD0GZb@k3{kUns+ z{6IzTEVOH65Kg0+vcTp$MLQ`RJKoin3Nd&&__n|L#P=t5+PBl=*Y>OF!Mg~Ig#7`O zR0elh*^nh%;YRup~`dRu= zjBQNEDC#k7+!&)+@YFVLJaWi;!_e4yJ7FV}A!k?@%uNc`!-QOY<|rAW|+O zHGzbqLzWWjo`Qx7I+1Q@Q9n8$O(C>sLoLD(P(fYti|_EW$E;=)B6k*sHZvj8R~2w( zhL-ux1Js?%%TMXY2!pMc`jbMP?85)|#a#6%#Q7P$AWlf-c5K0`_soL2&C-XVW*{#O zLa0=sw0ym?ggw!;gyeU<%iR)2$f)FUmnI^8F^l+RO0u%wm85!JE0(GbOHsB_$l~|U z)08DUxRt5%*$+zYyPum8F)YJ6%?fcOKiuN`@>Bi|34GacUD@4-fz z@H(`-IcV|d_LG$1W8ls4$W5!TwG`Le&xa2MPDH9O@V3OZ&M8P&i$_1UUXvnz(N(wE zbT-C3l>*aM%?{~qxkeNU{!CfJ&aq)lB7UP}Fub0b45oE76vm$Gu48h<7d@J`&@EY2 zyN!`TVv&(%zvX`s-y%^Ul{FFF6I5Z~RU;JnVyCH8_FoVQ7(oF(JI+x_<1MzN7o~%D z6!9q}qwG-4gu(;FNz~0r1BXlMOVd&1G4d#Avuo4&f+IDhAGnG|6=rjsc$VIv+h>FFuPUb`giLnW{DM8!Qc?yy7np)q zd~j1H#2RqBsOFeBc3OT%csK$`G1m^}s_D{fR2nSc#+0MI#28hFy2`K)`(P_+3na<% zg&#`sq>g3agZOFv4Hck)NBb~DXFI=k=Dv~>D{y&)>kc}as_HNOUE#wCH4NOa=4L6< z{gbsU8Iw(&Ici%V6QBJ4X>s*56vFDL2se7ed>TlZFBY#3Sj#?tTLOPn44gE0C*mQF z$S$f;@cty2F`IE;qSJ(qbr6~eq5dOB-)^F`2&uu$P}Z|D)nBi=cz1@mB_4CO`OAaz zudojwrN1O0RonAiw*{jR+)nxdY24Z*E5v##axJz)iSRr-fqN@l+l9;30^IuvEoxeb zFm67bG+D;jVfn>DI@rmS5VYj^1$>qXidzqp)<~Txaed-64|KK@N&0P@jXbSJJb%hg`zf0(kBmK6 zVWqL>smsF~4{HrgcfO=Ru1=YmlEO}Rpw1q(7d)Z}QsXU5`Mau>``Sn- z*0TFv4Z&d(eEd!_W0Gp6)1CsU`Q}6AI|;C=o%k?4H~e1E1zZ%})Z;c=NTjHpI1P=- z6+=5T8Rc`$RQUpgTR7?h^fv>imEWQ*wF32Q(_8VaOi2@(7bF~V!^t5_9bH?8cY!& zYp%U&-Kb~ms%u=s5E%PTTCN`lMmwiN@lIOuy-!F7S~e9tRcB`aV17NB?paZz3+h|& ztq;Ue1(vgiFKXu^UE%*@5T*;ZB|}tMa1!+@Xv*H+ZY@Cbs)U?PWYK|K-(oAbPXSRf zCH!tXA`#>c%Nu@T3zROofGwm7(vOoOB^5u=k&V(OlC| zSLU%o&8H#jr>f}YXA|3J6+tK@5SdaHpC`JfL4wte|dmqFx_6IbShr65EH3_+{+wfYfI764g8$n)&PK>YB-4J zUfhe)gI%fWhc?;~&T#n&=(7TK1?Gn1;;|jJO{F@zpIf_T;7 zAH7;XT&=}lkynqnKJ88Tcj8KY-n*apy!>3Tq2JxAg{r#}9C(8&Ob!ScM0f_`vwS{a zX{RsTfAn_WgTx3j8SVc#fPMShV)|ic)SI~df%*9{=`(HFM1h)D&Mw}--|Y4E#NB6^ zA6F60NxH@cBgPv%lr0odCsvK);|J|rqRN>`V$S9nis#Kim2{CSX9nX5_`MI?%(n}f zs|8mymTbcY0abpuVa=_W7ceVW^IA1F#@j`#ZC4eLoV=nzyu3kCo-#fr*sZEa`bZ@} zX5OzMzXl_3Se{H#bo8M?Sy7-8C>zA?c_GOGX{hc8k*TkKO?$?vn+>koaa5m7r=n4p zrAX^gqc&owlSpSZwz_H&08_4y)s{1m?~D#$SG_6K;BCY@+s0tyDl3KLzTrVQ^>*NWdzXv+E%0~)th8Y| z2ZLTlXg08OW97O&X$5~%`vEOu+>v^kopD_gVF2t3P=n>A4|D3{F&$YcFs_CLY70ke zoC|C6^4&z1-Z`%vsl2E?UDChAPVI7xfA-w2Pz_HL6Hr3D}M=Z_y*ma{rUo zHVl4$4%!S}xtq-I2Q-jy@`6S$j+Ng?cLCqxq}5gR(MAD{>pSI@2lp7UUfNLt1X<|# zgu^GZ`y;>Ss<6m8Xiyo%JLYT}bUc&fWEE5;dFkW;OiaditD>bXRf?0fXjB_QQ2_U#Hke0%hRffQWjtEU`~zI&&{`{W(mLZ+{gX<=wHkss^JI z^>-9lkEY>7p~}Ti+B5D*f55QFKdj|G_g7Z&H!0?aKEu^N&#BTH8mFtu!9^UgFimcz zX6vLF`AZObzC3%K#Z@!KNh*u=fR|N5g05XYcSHsZ!xS0vC6*=o6CX=9BYa?zW^PYNd$28rCgadaoS1YBw1-c} z+MPdKVEvL-Pn{2{_n#r&*GyYS_QifxEzqxV=ma8UXW)tJB2nrd-x4R;xeIAWCFE(Z zlb-<V^#SBXq)np|efPv{KrQ_e~PQ;e~6VV*_mLDK2B8b8*J`LbBcHK6{skUJF zcV?pPYl!gv;fZ52MykwbS?}Chy@=qVK-stX!TmHdUnY2ra5DM^1QI$jm4_b>+05Mj zfks{RMWKqvXO2Rl;aB&4YML_fwiLcTYw}$SYX%sv@tt zBAqJH{#9o1H_7PXd}F=`m?&rQMkR(h&2PAe-vs!LhI#YmA!0+%L)1b0ob9J?? z%eZjh#g@6sDK+1eHd z;*b{&!$=F1r!w?SENTF>p@Vyrr~+?W`w?%k*=0*jGpi8{^>>VvykWYoH%R@_&TYOq zC7*`c3C7ogEjuq|M^quBdKukH5a$04TKcccJy8-w=W2v2L!3Irm|2v)F7uR67`u5A z1990COFbuzQESMDTxrz+1g-)_!~y<_ZwC4uH8?>Jr7hK;+~?%Ukuy!Q;<;G}eU3vK zUF}$XMUy7FCOs3f0SHvox#IA(ObiB{CI}0-eHlxZ`WndDStlyZ6JJ^yOHOH98It6G z=I3cFKjmuv{Dh|54Cj5z$f2xHCF0_-ec#&sB#j}mvV^Q8m>~_f(y-Nq)YHHPBNWKs z_K6vl(i~OHUbug=aN*xA6lQoX!lRNS2QOyE zJ)~RG4vp${KuML!bNEHEJZ$zhiiNp=6_(|EVngrQG4u)*m=@~EhLV>mIi1_69_D4E4PVD;r&LoTxrLSlF4J9YW+js9ArmHsjnl#6YFs?^a1!_Cg(&VQ6hkQ(weq4U=l)YF-3vszPnw-!RQHJ-+5vZ>?mJ->i~n!$IC5Ow}@$Mzc?NnV^zNJ(r~ zj*$t-_}XIF!U91s=0TbL`Wm>N7CjZQC)%#U<%#dLK<%@e@kMWbFUe_Z*MT^kHVo^1 z%#~h_UeC!aTUqBlC;LV%_-q3?GtMK9$Mj~#)pkfLu@I;jD`M_Ct>}afxdwPz8vAc~ zIuMB(ndsD&x)Qs}@68Aob;Or8IUzvUWU-<^zspf(vHDaKY=D$G?JilysPjj8B#v{G zAVWBtjU%tb<1N}u+>int8*O%Ij#7lP^6DRp1`yEX(ZwEW_JW+Ozde5X*XD=3=l?d2 zVM!(<9njy5AXR8Fwk*))HB9X2fGK-UNKJ;N3T;nBUtE!mG35khNU$fIG#9$Xu%+5K zp|)5}HJyanevgVdz;k~IFDnGE7I@7X^zmr|bI-(q0|Y7bnH5GALyg$&CXM=LeU6^8 z60o?351UjlnqcoJ&}>7aS)#>r&EO2WkulpvI2LWqMo%58etR*_?;6Veew(icwT%3{ z;py&ol#{{I=XQ4jy#rZ6|!oLGobA3>(XjT%X;5FJ;IEU4W@X@gP13S#HE|fg4#<|miwm(dTcWk@F|cwYslW4MaOGna zr@vKAI0LoHP|y;MlJumB!m5XCQ483fMm|C-dxwBL965|mD`pbGmJkoRPwOWvN;EvJe{pLIcx$RP}`{1&HkHzx!s*{ViHjZ4x+9igogqQzHJ=p5hd z&5nX#1h{DWYTTB~`pap-t%*xu^}P3y%+f?*2!*Ici#Y($0>KT{pk39Q+T0#ss$~5` z<^;}fKIoxkmh}^=l!%Knf#@Ts@C&v<-*Gnh?vVNXWB5jMan;OkJ;KzB?QcVNRlzy@ zj$wx&+`8Pk5|eh`yY1%K&a3Qc#5@55g)TQpuKjZ;!Y>PuCFyC#we&rdfufNN6A-d% z@*@((HxI6+SI0_qc^3AZ5hgTnY@dpspdrX+6V0vQayJuY}ys$ij+t$)g&1 zgdfSMVZ6jKlWu#$0G5H*dWV;_W0hLH+ZicAWH!(yb-%eo9rH@2DyK_EjMmAij{_O* zcf*U97l+-Gd_VNTL*|DjL#WUv|I7TD&t|T@OaDho{)f`;p7`yzpC{e75*v^I?mI00 zn+3>3-hVq53_Exyt9o=p_-k>`vyy$bv%M63D&+?n%pk&vqbyruT)zs~T!%RL zU}dymCDZ513#zU|YSktXdYjOyy}xt_8a3!5^;6JNXxDXwo}75nI;GwJvT1SLC=4qTibr+we@}8#Cd&lAosmvm?)uDn2@l( zA0!K2r;^t8d4U}WADVeRT4n}!KkZ?8;cV%Dt9xUe^mpZ&)rl8|tdds>9bfas26^>Vc9u{mknS|~{e&^uq55{- z>)Pn*%ci^Gi5KswvZUUrSY@Oz;iY{ME>qYHOy}~Kw0-6#_9&ZQfm z+nvr-a1qnE?V3DZTD1U!i2ApIPFq)!Gw(ne!kS#)7sy`(9amohC54=@5waw0z38ji zlFrIqmX(f+VWsHQZ<)-~8HVYZdYrr%tQG5Lhs(-D`jonHxD0cD29b=<+2e>xz0=wkD^wOYbm&3sej~E&zSJb}Jt9H!|M0sS zZagAwpp$XHxRh@Xn3btK>(24lNL~U6^Ja&8FKc$(D+xvZ>2ea9^1oJDA^3G`Yd+Kr zsFbC%(QpAwKC834!E*mTMmN(i<-t!P<07SfZG_0Hh|z({DMv)n+e*=MGb-0lhr`#W z#%cNAi)FoqdFbRh8a}g*MXo~eB3$w01VfxY zYwXG%YacpW2jd?UPq@NTW`8g>Sm9_6T*F3FG6uIE%(@KLG|J>^}5)m^^&r+Eh-cip0fKkYZbgDd4lcb#OL2 z#(GvlG1|vo!>9d9HryK;C-vFkWG3Lde(7VaRuK7 zm5(cM(51M8w3D}tj?MAx!dCJ!??;5vwCQcRspIpn9=4g#hYK`{%1BV-a`C^%SXBf( z;Rg?3@9o~Z7e7O%tVMpYgv`v|GpGm$*s>&sRr7!hPfbcAD3N=4iHCd|RknURq_n@4 zyftO-d886-Efhh&yhj6#V!Abgq@Or}6%fi$@i`(?I6?ErABS!1m&9zi|J8SYfVETk8(OoT)>D*B=m>tB@N{t;jC*@3e zB2Y4;fH(xF6T3=@M({Rd78N&ML}gtJyU3NQ2lwjTWY#YjaT#NdGt7V~YjE4SSKS($ z>`IdO1xPsr1n3#Y{vso*)8ZbZ1WTsMm zowkB5!+ zUMmcV6g3c23vswjouvFkGYM$d&R2|%dFNz$Z=G`UnxJ!QRoq;4ehN?FOO|AbzuJ8^ zLeGBxHh%d$7aR55ok-aFUUzyd`abXE3w}2m3c7<0ElFA&9$|^$cx(&&15T|o``M#F zcReVi90fCb8YEyPC%}#IM)r)%X*Aw&01N#lW#{SXN8}ZY|DiyTv4lFwT`EA6O42_B zYlKxW{OmO`D6L9iO-SXWJpfDjHU7~taF56~2W$c>$O>f#CvH5!Y(=i1AKZ!2*`srm z%fG(px|QI&`x8nH`<69nL2>G89E^6@zw1bnJxP{7ZPbo)1D`Q6x@dv^r{>hvOYBbg z5Wt%GLY*jWD@_Da2U1dB;7pS$yL=OiEvTaNZSBB-gS5xS*C584Q=L8i=YR57L+%iA z3OsaPS&*|nUbX0TWkgWcT;wvz?+=ZuL-1MfE4AH}XYeOldjEK-fcmg)q9LOxXUZqg z8MlEgb0X|fNq5@uWM6l9DV=%Nw_1}vUJZYAt>ks&(D}VVh?Bm`J7khAhrN3+kdL9(5m@PcG^(}6IIB3zc?$VH{HB1CheoXZ= z8zT9av@zqw&`7f;!H*+kRmdZ?VSx?>+W9)7yzmIb@0^nQ*{8YAWE9VQNMEOpaWl_= zHw=fGkPf3knQ0$gUI}kr{g7saVtJl`<<2@&?sniiruR4?nD7FxFERB<l+To zJt^^`Okk^RM}F%11(7chd+?G2;^7}DUZujiR{s5vo8+3WCT6}=lO;{mKdT?VcG;=T z%NgOyJYf8wIcWR}tYT@saPjo`^~?%rss9RrdE~<1Y4^i#2q%}Cf}QC3mz6Ijj55mS zVZS!@+Bz#{*@}o~4yzL!GPJx2W#bM{*1xaq`3@t;xp1)-HL$^7gz@U2-b*=nAOm(G zK*+r0sdE%m@w1s`o0#(dZ9PqU(iF-8zcnkK!M2mOhayL>&s<$t)0il5uFx&29hg6Q>rVvrBO z##XDw1_DVK5Svz>3f+w_-r`9-c4+Xn-s#M=`lJa2;72coBLk%WfVT_YoM-U(rL8_L zNSRI(g~uI*dVu9^>N$QK`$5l#D;Xc%&|(~?zsy8vr-r#=g_feQCQUG`A58EM5qTg$ zk)hz`ne48qYgy1>cO`<9s~DYh#IC*TV-Wu}~)wAf;STU?&7P zxj<(bxzHn&lIlcaHzyv2S(Pm){WX@MwLKQXd+=576|=$Tuf zmXVA%vncGHFIq^jOUn9h=)(wYAHBhC{I{O2?@xo!*(&Qsv=?0l1M3@#pFNh4RVBe) zKAhpIywoMs2woU!KiRKW!+Opg`hnDW!A5_=tE)lPCU%fr)FlUjM&*n$Vz7g}JJvF= zQpc94cNqNFB4L4>$8H_Z#vsZZvU|*~s8fD21{D*QZBY18v{_wapn=Q~YVy76ziY;F zes2$`b7Xr=CP@Ew98MRCoyxB1Z`pq0vyJ1v33Mk(9J>J>n@~a~QDTL}Vw<~{TY1Q9 z*;B{|(ul&tzw|;2g};ot)Goag6i*+(i8iQLs`<#Y=v)h^SRl3FmwSM*@S+qx#?gJK z)1^(;FeYmJ)7Mp65;cdfET~dURGT>k-XxGYOlVeSxZmlh1}`DN)`vA!cn;9jzRs1L zQFSI&^jK3Oe?L6`=MARz;!!cLg;t=3T?JTW>cbaZt?m;357^BgIv9%r>|A(+|imvO6yNzwzHc!yl zw#^fxjnmk6(in}66I)GV8;xzY@pu0Bj_>u}xAnBg9%r0A*Kf@=A;(rr(a{}pvx*}c zdTS3s9-enBbs~J~)tN&y>;8_GDU1e3MPJ~D*P#``7dkxx!D7M}T2^yx&sCH*VSaQV z0C*{E2!KMh9Xh*m46m3G3zz1>@MknG^-$q!6N=qHi|DL(XN% z7ML&Vyib8!5+}nfIbOHkCeu_?i1d7qXq3qK?4O*2YX@fHHdjx0xUHh6?4bN5R2}q(4nAOyWJN$)!=DyuOPRh@W_;ViQKLa7^aCbxTjXO3;?lp}dLf5k5D7-iS&v8g& zsYzxdYj|eq_z``~13V-jpeq#Jj4PU-++GewshYC3)WL=P!m)lq{P>&LaTB-0kGg_9 z!;k^n;j8U#d~Ea&6irp~kd_uqTEW%P+gbcbQ9;DDSht%V3-VU~3z6LS0cr%{ z7apa{sifSHwH%^+GqRZ!9C)C~CE{a3g{OXuNxz8#=Gb3f{45B5Qd{u+e#E1|P zFs}xZa6&Xjhk1tC;gCjaN`8s0k#fg$PT=tDaDmUPu6n%W% zMS0iuO*tDblmo5_Vlex&vP{ngJ!`^hw~=8`mfbxzE|TVtYRz^JC^91Hcbr^;dzL4FY9){p zMT0Ir^L;MF}PJnhxJARoq1 zEZenrk(s&*7%o3*aJ`|~%u~L(zL5OpS;_KC?9t(_6O%Ms>g0jL=%Bf;ILAX$-T~n5 zi&L2;4XcH#w9!BHg@5ylhdY5?is!82%=e3<*$*x72=L8h&r|{>PINJ25z^Fm%#OXQqwyC1vgU231%Icgl|{EmLl$)OFeey+`chFD>F$p*Hf z6of)vz+(TOt&ti^uGo-owkaf?2xI3VHSqRcPO>{AVAgZJEs3N9K~Wc*g%ou(L5bSm zIVG#?iFE6tS=G0itquO@%JYQSAt|p&2n_@i=5!9sJnIHmI8yWSm)VY(5G$tNDF_xE z)dAr`kYky_41qYEv3RO^`Yq;r(^|T+FMxTZ+5>Q}s{m6m|2s~(#ZPn$7@Rv@gn`nS z!2#LPk7C@nH_F65-$d-^Q&|32!Nx~_m*3BUA8Z-u1tICBv{s{J^xV$|fBxC?*Kfo; zm!ne?Cs2L&OM=8eqNi*4-B}7B{!HuW^LOipcX97_`yGnhoB!Q}zxA=vPWvP}l;P~L zp^bN_$BP(?I+aD>Co>*Kp1#=;XZ-o%$3r}%qyK(&;oq)C?>nfn&v)6d;-)dYE$lOI zCk~F#%$KA}%Aii&?coulj=9*ljrNz$q(pkx+u#ClL^33D@Xwa8zcDb2sNH$uj z95HODfhEtG3kg^pi-l|!hp!52-3YY0s}t1_(#i}%kMdB{7clD>vvpgMbx;hY3a_)H z5H(O&CnhCcr;l}Lzs$VuQ)Vr-A(%U~w0i09#Qy>oavgXm(v`Gt>b1?^&)%0q)Ewq% zujS9lY)u58@G>c*Yq&LSMA`7h05j#3E+s%e7iYh}7t9LzpxQOZuOHPfk8IR*i$zuy!4mqS=k zSe7KMC{@+WX(p;fP7eFUoxabtvO?wKma#ch%@h3Oqv~yr%h`SgUidCB-(Jpqu(Obm z5BH*f3L2T7@!Ap;Mlca3LJS+-jd%6sOW4zD(_#gKB-gGBLKUf?+0!~h5BbUQq zP$o1=!9w{z66w8aR%EN0O6h)TgzE|e`c8lYTj8>+$U_Zj3F)DER?t^#)RPXAuDOgM zUWg_pwth0k|Cr2TS9jkO`Hj%l{mR*9|#u3qgy5mJrLe+#JUbwBVg#MDrw{2%g~ zAegmGqTzn(zX#IFuhZ6PK}Kq|B0tV425IXPe9fE$5>(ctk#pJakwdAKEKMQR@@?X?OA2X{Zj6Lx6{qxIr~)sgn8gHlYe`LmB#I;xYVaTcKB>5P7j z?lAc$0K%KgIut(5T(j0_O2_jPA3AX&qPMPX=nx=d!i^vSZO9*WIvMDCBxJ0S2lYxy zl)V@S*G-&ZG@M_SR+i8}W20s_d!qz{_%<-eKL+_)a-ux$bu7$&)Tuhoz0~$pY&8*j z_Q8W>XQ;RYhQ#W+q&FjjLf!etiN$SN0^jLvS5WSolCqYu=-8S zj?!eX$8qV&`y3xLM#ob_wzYtn<>u^;z*MRJ@snQ)q#I5Z+aOfBE?n*zGMgjY1?4XO z&7{ow#xea9`A;oQlManf3XEJLNwXOU$M}}a?Ld_1Q`p7J4M>Ncg0=EiLGt572;BJ> zBfle<^Yj6?5OSD%a;i`j<^6Nd7eCB7%^~G z7<^w~D>=@<5co0)(bRk-C=FE)CDLBM9dZyZUm{cfEEcrd-FxY8>-VTU3S2-)RHnL% z-A@AfEN8PaxpkFHA%AK$D-egv&O%G9TN*g9RtuYLr3SzMH> zTKagC0O$FYZOkvvL)M%_i(p_1_z`C6SVt#WDZicxMfSbAbU}v8;V?(4a&ol1x{=Fl z`(wj9&=nd!m^1y2d#K4_Cy1Qi~3*=Fl-feKNDED^nCUx z;(*k?+n;D~D!=<)F}Ogn99Xk83)&F)@&qoJs|wkRPajjZe(#sF$FY8yd#6`nMT|k| zsmGW?+`}w3P`jr|QCUIFd^C2*aKSNyNvx^n05Wb%+}U*fC^+6Uz4Flx2FfE^R0xBV z3Afr|w;YsM?F)f#0v_a5U-@)tAj9a&1hEy7&RtOfzOHHNy!{q818@Gl$mmVX&NZY3_YCf8?A;U$qQiNcV46po^`6CKYTRgh;R$Qyc>~03 z7$z7RdI99qX=#9;@v@Oe!7Chjw6si7y_TFsX-bp=fN=kUH`WWE%i4cezds2SEj1e+ z+;=;>oMqh%vB};Zbkz$({|Jh5DVoF7ZN%{T9q^g)<=pJF1q8(=k_FX{KnoLB9AzUsXcQIO zOr0(E4rs&rK37iJw=NcBk_k&51P=Ki`90^Gna3vorSbGLZ~XvFOMgpZ$59){Rbx3) zxBBrGVpeOP#XCNdEV&cSSk)jC8{Um&U$FoAqYpk!pJY)Mv0`5!4X*`>ST1Z#mc_9_rvj@`9e=m*GHaPs;Nu84DqB-o@C32e&1+kVyFI1yme>Inq2;=4Z7C zgd4cih&O=d2%kW0D!ICSD8h(os*OICId* zey+^TqEGvJwpv>c`Kc>R>~Hvv&A6)X-6_jkB@<9l&C4%pUhg_^m%x0X;ljXo)-D0Z zOad=(=8(7$*B;eu1dnbdioGXz&@N37e_wp#8Z3`^CbH5ogV$6ec&*wk{IfAW{c`$S3HhslR^3gUhkT9g4{RCAs_QpTnuT`^j9S=&oCjs7Kps z2l#zC9{3JGgQrzX57J4IujsMk(^x=8C?GY!t*Q_Bv0Adc?90DCp7!{^T7b5{6am1n zp$EGm)qR!AUgL@m555#D5iXI?o#1`3qT!;ArY1riaacH-N5R!sL31>3b)_;NN6I5x zXLH!KU)Fkp*#t%z6^IIgQs{XR4!Y#NqK_iE&u81z&j*|Yn<}fV?%%wC~^A7|*81^Gjk1s_O?Dw$^v z>QTRTFHWUC4X=h5XVA>yPX#Q^)aGsC zO?qmDQBWYn{PWhK?JczEpExHRgU7*?JFz63=^Vu>Q=Qmh;7?R8wk;WC;D^KyIqU=D!pi%%&BYGL@Az3;M%M@0!|!Vx6rB@hzv)@q_9U zGWB5_3zQaAh|vV&bl6~;N_fL{;q#3jXoJu3@-92q-jn#daE<&OCA@<+1C}YYIeTdC zn0mW0rl;n^^wp4*x<;ake#}9slr*)KAQ0qT0;CJiLcN$&Zh$BA!qU)o{sru9AVcsErt7IV^cn`jltB*tS9@jvKL4k6R zI-dxt(ptvNFq=JBpFAE8wtWtgNcN`?cJ>AIG}gp2k*V0_IEwthFLP%qtO9$~(tgZ4 zNEc`?Pn&g=3$c_$=FU(`_E)uDI|Tcdnkb}|KPmHdpY$_1&D&u&sYl=Kx(oX3tdA-S zIw3L6^*7GtJa`NBn&(LPdNLt1MaFNIV7p3Qnp5+gR^5)sIL&KQ#NRb0`=?%DG*uL1&F7BZl?> zL2f2+|>ogcWG<0sc^1kLPKHiKJHp%zB zaUY~uC^@VyCw2ytWsp;7)~@Z_G`M<34H&9AVAquJwzbEBBavkNS-A=1|GHT_rUdH% z(=(MBFf13Wr1qZzmaR}{Sj~KFE#)Twe`D*_EJFrz(k z6oyQ6V>|QSH#30+!qYYT5#X=ypozPSMWl;i@G*Ww5wJ(1V-HF{<~XAsj<|PPgHd&% zry9aWAQORB^@6wed~77l7_hfyL^^XD_S;W-#KzC;AzJN9pDM2SDUU_LCB#@l76WK9J1lhGxb^p87gX)gTiJ1!PQBX^p{D^gD2&s>*V|`R6pa z9`I-|n-j1cDYAKKn`uMxF!r_ZU5Sb0OP#C=ILFHTAPvs(YE0IBc;i>ZsDag19OJ2R zig$I~j{7%8xy()r5#2u-@x?jJL6_YkHdZd5RNCAM@77jJXo6`GA4A7a}F?(0Nz-)D^V1VkflIxuO*;+XIvk0bIBHk-gPPcL+mfE>|(D*1|V zeLkWyq9`SjGSk5Dz7DdUzITAT+^Ef8^1zjY zg)7olc$cU*H=VFh{@LV8d&#Z2ruKZ~7NT6C%p`e_WLYQ(q_6)O``(@6E1IX35dkq( z3B-0s^_ZpAtnpENmvU(tZ1nnK@3I;G%SN@ZxncO;>)#3CS2Jb@F##vrcVrYOQ_sna z@cc6-<77q5e~K+uk4USdWhOC{sdI5yEp|b?+Ac2#uMK}|>wkHP+)7X87KkmJn?mZ= z;`fj$dq2G*Pl*-;ssJFlH?M|cjl6pXr2Yir=j_f4nA3V>?wW%b_d@ZtIDYY*7 zSwa%=g9-jdYQ&lXgpjnUSO<{=C;Z;X&}=%@eDvejal7%EbdHw(ruDm7%T%>st#soP zjzKRHNV_;0MVl-}r`=+JNvW0Lb1?#We4t(G;5)Vg4=G zwyRW!!ZCn{Ky72~I>}hK)G4^wq3PXfyvWowmNayWC9a9-LK|q>>J8ZHg)!v6Rx~lI z5*U@PdK_e{>86Rp3J676;39TZ?7;44?6k>7jSt59Cn$@1#T$=iPTSvb`dKUz3m}wlg3yB% zcBd?-5i(gt<6;6?PXwqp?#=y6^P@*#^_rw!R<1=TV+u1x8TDzCh7Trz@(N-;xpX#x zdrh?c4xR!FPp^&_y^-=`RDueXcL2WHcIgmtWWuAV%W&xHuTY=Ecippi6dpoSoV7U_x1%}u2Tq^1S#dd~Uo`BqqI zu?@jyuaUkHcwF=Wq=rsggt^S<99VvpQbk49wf_OlyW%4G%@3||S3W~h?~77$D+4Eh z)UYdw-;=DvER6qnHfyrtJ>9=1F&hOgnV&Ok^8|(Xz-l=InpEuoX}0UK;jbsxMyk=j zq7y8e$a1wN0<(=pBpT3W{e1DlXarTm#bx9lbJ@KyOB58Z&$(+V?>C%5RUzcOF{tYV z)`msz=MJo){ZTqiSNAqI(HZ4Q3U1D!oX={gpN@iBW)zw$TJVWpwD%;=Fd; z$#ONiM|{T_M-_z_1eA!o2;YtyH$Nlx311Jz2w5@Q0TVGbC-MNO)SrmWz5B{F9fI$RZj%y+fKzu00Z&ZY9Ngt; zyv1v>pteS`P}5hNw2Z;k+p)h~3ojRZpLwM`Z!X=?Yt-fDC#P1PfhS+kCI2i&9BsG+ zl{Vt-qkoY6vL(@|Ef~Osk}v`nh)}a0-7+@!o&mkR9xb0|87GAUk_fOk_({4W<|}u8 zjvp!76voo3)4cC&)P=Sbp`BI|%2l#lI4Lu9l1Al|ia$K~jJm}p+5Mq^YM@DvFVWin z%RDZ?@Hf4YXqD!O;XG$Pb4t&*2+9`<7r3|7zocke z5j7U;jOynmdRTisl+xT=Nvps7iT~Z<3NZ2N$Bd+`1I%T3@49Kq{6H` z^J5HZ(evI#;){>-$i3GL$NFrc8#K5Q@U10?eaETSzox%m4-WPHr6+iu9;)!!a`OJ$ z7l8Y_@7+@9Z+c)*hgwkYa->8Zg0X|})!X3p&yH$nRljS@+~@M^0V_-mRTQNRo^$%G zvsM*~?iz^A2hI8Ob`d#Xu@r>8Caa?K+&{L%Z-cQlS~#^omW2)EBe`C4c$^V;bZOXP z25sZ0O`5SF7JCUY*`j7DG$@LM4LF1YF8kt+xAU*);Qu?F4es2_7Z>2DZB-kj! zqR^ql5>c)Px~;FGpNSPv2~t}HBRFe=0&!406!W4c!i#?`aT7i@=0e1o6spq}gIW4` z$hdiNkTZv($r?@_2+@ZzMKEYStO>Jd#GprLJQAs-XVFQ*DUvCvRb7ma7CgdZuggGG zGeIlDX7W+lp$`G<{VEdH(xvu!<2TqNIdfiq$v|$YjW~9G%8a)OZFA;4G%4XJ3T&G2 z0yPNB9`ajdvQWn;Z=o0tIQ~&RhElO}D0U+z|HBc^nLx7E=omKt`?eOsVZ?N!nlRA( zIQfHMRg=U9wy+!y=OCH!+c7(T6R~pKGZ7vQ|3`3TDdER7S85<%UJIBUgno?Dd$DzGoH(OhJtR8mA|Y% z^4-%rzyjuISE=^Hzh2ahIK!JC#SQTGU~&flyi4Xxojb*tCjeqAva*l}4Or`fs>z>@ zAbvnY=I(-uN3k(3+zXTBIPbY!_dVgDe>@eKnMH|d*Ydzm9r6SkpHj%x(p#LqymaoK zISy=c%O=H+zik{`uYZH#3u{#SPH~;NM>-SzosQ zif&ed*UlxTdP$?WD+C7$t4ivSX}|hu$d#FGFCrP5!Vki$77-*wKOKK9x}DyjK9 zGLksx;2uqw8L$F1;lOn;F{4ir&s)$zJGcqg7%M|zD_Iw|WvNHeC6nbubkOz}oxB(! zKHFm54w#>i0#;p!#GE8exaQ;1k^se8ShQ%c>kn(lT5BAq| z6LwFAv9O6$NBE^@v7>Mq^{S=fn5#Sm>G?_z`0DHzA$hA05OXN=LX{`wuB=()rHgDo zx}U{PI=dIU_Gs#spu~}8B(Z#|l6o098|l3mVT-fL6qcT+hUuRtF<%Vr2BE5SnK^zv zaYH-R!g~knL3Db^Lcw}$0{b4YWXVW{ru^8{Gg3X*c7=rFt(Um@{LToswa1Y&|PB)87W*7L8oT5T#TZ3FiF5a*xf}}r1 z1L2z2U7glYdRB(4^Rx0L?}jO6lCNroXS+zjpg9pK^qh_`=?pJ;-4h$Uc}o6)GeBPu znqb9RA*7W`tREI`XpCm1L*-azZRZqrz1-8V^pf?frkJy#2UaE#dF&Sj)l8n)w{IDc zL`2XGabPzHA?-i_b)hlDCI);i4pwahEq-{f=UPu5b$qO2wlw)nm1P)Rcl*!UP8EZR zh#sUmgXOhlIrym7l6^^ZDDwM50lUZDNC-3BR<;(|B^o)>bEI%2HCnix@xQnf@nU*K z>{VgY7&``PJlvEIBl16lW#cYV21&H)>p6e!NlMA-dx6OuKGzMG>-QkIVAO zI<*_k!2o%r+FJ5a3_c9NJfl4(h1C{#1by<+!nXr|{mye#AQ&fH;3L|0>CGSWFv^pd zE-gsGNvNh|WxlZ%s~dR1$8mdsDD<}$KC4mzKCshWW>gjjXG>px$+y;ac|zd}#fXqY zOUj?#8Q98YdUr=!(g}=T3HjoVpXx=2c@yAkN($9;*3y}~!~uk?yHd>;()uYLF5;@* z>adt)&KcvMm+}VCETyQ)&2b4cWNClzV-QI>-=ZH)Sg2&*L(ydbFGj?cJIK z8rlF7XRF=Uw5d>P_(AL*z8xozm6R03E%Jc^@{n4*I?Qnq@r!!lO^7}Mwl%#ZB@i_+ zty6&>@!Hx*;3L?E0Q=_>ua2p+<&%s8TWi8v{F=MMNjRRAt(Tp) z-dky9$(*9`YtG}SBj68)4nZ~2kjDMXH_8WgttQa|wc|Uw)A0iJ0$pa(LXp4gGxK}P zhMGe)Y8FJRxhkHiz%9KLKw-Gh)K{6%BzZN0zDdC{Ww;!wSz%-bEdD&^!lapR!gC{e zA0}E^R%$`xN<>*wNNZXtL)V}&8t63^my!o`xCw=(_5k&%F0KqFAfdDfN6Kzpb!b}$ zqOYeg9~Xl5D46ES7N^45o54$yRDJ0xG3?7-vW3s)t1v!@o}`ekxL%tSO%P)}wluee zNsUb4%rsb-8#k-V(#zIdKu}g1nz{DLOefCDk@dDG3XiKWMf0CIB-BHDa6C%-w5W{g zNVOp>d<5|QtgFrwcUZSgs?>IM4-q%FNWf}P@+jgJ9WS3}$(e1i3?i%r{Z^suXbu@M zHZ-rUwjL_JS(R4bUcqoi4S%-*>F=Ig1@+Xy#g8Kt05#5uTc zfPH&2Il16aVuQE;i^9<_2d5Mr>!v3lJXwg~^n_rn;nbf%}fyrY>@ z-rd`=vEHp=IBK=KJrAw>9r*~2%)ISe-dOY1aX6sv1e=M&f9;zddrjJ4;26TFh0NAe zSCWaIxRq~DdXuU|%dZd9}tAWL`3+{#;erIBalwk*Bb_z}STEtXl%G&i!gK5s2T=46$h z8Nd%UafGM$BA7%*A_=rb0?b=p+DX6ck;LrsxB4GRCL#9^a?2*igsbZza`&rRXZ7&I zZ@nRfc1a(aohn4Hc3U-AU!IzgYFf0X-1my@)*D^vR-qHoS0r+cD$$uZ!*d6&6*A^Y zJNpI)awl1<#o0GQgzu5DHB;SRR26U&WwDxc_28EUPh|$)d@Y$tbp0-^&QXQb2%~mB zKxQ|UBD{QIb|f(qy&Aal$$Jf)0)trtP15fAVGv}F0ZeT%)}8- zXOcmK11mxKoT@gD4k;2_e|8u9uNM{TP^JqNeeR2tk)gq|$Wuk` z40%eBjTL*tebbOJ5dyte*QQ*znNFDSj5Uo+@;{8Jo5~o3>n&b}9|z~iX=$mdpvpAY zl1ii*Q+ES=UTs9fu6hh_duHBY@#L-wYcXA3-qDBlo52Ck`+v=t)BfF1;~HQ>w6ABp zo8U-bl3{!MQ8H$QaFj3|r;acbt3xh5;#`fK7x{_6OFD2nlGY}jzdPc{iMiOg;A8D` z>zNpcoBL%`Bhd){ql$)08PRMB)|TN@Y>$Cv1dLO;X+XVMOY3So1tJwrOxn}F^;ta7 z{XiF{u@*Ue1f|&Y7O>P6=~`JtRZtXJ2$k7W{aAHxiPB(6xboV3+{@9mi&y)ocA2l1 zVW9d?6i8Neq>VeGywrVm2wkJ|`{FFK2cSJw%@ntEY-yscC8m|P=f}Fc4mmRsKHFCz zgRU!I^J06yGpaqM`>|pq7K*t9--o=rnG4#hn!5xCYhz25!pcltNHHQSW zG%h-Pw}kc0ma{tbfh0y|WfZiinfyq&b`d1e;N~;U-osV_)DsvuDHX#1rvD*I44iWb zzhstpQ5=MDP`<6V_*ZqLCurOeh?CyXl7iKWu00*9&mahgxAo}Z3Tyw|;g(gyag?GM zHOWpT^krhZc;;ODXa;v3X-kp7A9u&S!<*gAoqx8wl>BPM_k+#Y&CZ=fk=pWRai#cc zp(zQ$uRS?gs!5Z_wzh$lKjXf&jlXDNB4r8ve)`RVFhB`GLN@-S_ML+N^r;rOCt+&O z*HB_71{{s{l9F`JCp#!P0~!tcuI7anA|`F6oK*2QS(P1CTHK$YKswOx!lP0@Gevze zf^{vNO?c&@)JmIN7hz|+z2G(G2+Hz(Gd!Sko-PlX*!tG*6WXAFTR)m%qoXC$vXD?W)6Lz>lR3jrMBkX(c~EJLTS z=r#3=0HqWoP*xRwa3)ubEqkYR*Re)+;`~}n#nh@Y_M}L>r2Gh`qDX3du6-=KZIj)K ze@wl%NCyIZaVE^on>aa-l>6oTGlrDPaS}nk86v_8>z6{WbqrD0Y;kZn1^Cp9?a+{Y z4t3*v9@$b!_Qxs5byt*3OoSjrU`LiQ8w~q!&(E~{4sSwUM)J-v{k-e_IUB@lLGg8| zWZAtJ(VGS4<-yaM>pf_H9UX9`=5bd-uLG?Mqzy{d9ld_cBosQC|#;?!NV zQ1^NTx5+js`Zb9b=B^a$!Go7YH#Lz~ouCWhTKW6zTehL=?Jj+?$k&8mM9o@sTET<6 zF3K)r2Hd;VzrkKqJYN!TqX`cZP$kG!`vn^a=WG(hsrsGlvIa1IKe5_&`m^IbkxQT8 zN9qX%6S&f-?yk1L3MOI?L>7ci1EtRczmt-@=U@UO&_dSqly06bwUyGQ6CV= zYZp82fm2K&l9nW;2Z#^Ed75Hb6|#*ueo1o29fRa$JcrkhZ`BF{=tEoJW6Q&Bps+r! z`W@G1f>pn(3%~W+vR*RBuEozcu0p1+2OgruS7{KDRfXu|YH(HptJmV7NDJrI3xa?| z1O8(5Z3zsf1FP3U;kGNFtHT<JT~qCSE|>53cP#r?Cp5gflh0EmfuBn2m=Qy?NCGAGn>3v7#s+BtQ%2WY8E*p zGbb6!e3>ECjh*eqmp$m}voHgX%sS`!B`sJTW}gbM#Rj}E4d_3UDFxrK{wGl^`K;+b zi%mAMHG7OGBVR z1m8p!JzJ@<6D{rhLi8J9(mL%O^x-Hljl|u}5$B$LK60`qvvF?H2j4eQJ!~(oZ6X{T z1A_G{a57X2C@Uf6PvT)ileh)y?j0#-h*Ov7n6N-Dr~2=Cmlda15+Yf{lZ~2_BF^g_ z>5#2E&*oBPzz(5h?($9=MiwP|<=|iw?{&lEZvN1*P}$6uqwB4(gL$q4KTNoCjvmSk z7J>5_a=|e(pxIwMe#4x0A?{s-j2RS4Qj{UvHm*ViYl2l_u*w2r0PI)E#4@PXwI}`o zt#ito&gpbQ^!LgtZ*%Q9q2Uih`XjQ3-cMMaHE#}ZY_+xQdvBhck&)QJ8-rB`0%#?) zlh~7ziz{JuRGI+CvQhgnL$0wS%~F#&qX0_-*4uU%$$-#gx5&FsX$TJNmcI#OW{A{K@kDGU)0H0hM6b|-v=F%%1U zl|jApU`sF2Ca`3C26lIA9p1}}uPFvDV7!UwK;SLU1B9TVLU`3MCskzc8>em)CwnuuI01;kwBFGfiKD|c_db>W)?8#+&=E_M~3FD2Ci4^pM?5Mk~yfQ-X!1n z;l6vpv*b-hp(G4`-vSUAv(=!)OUPd6mXo&jY$OYcj?;Rm5A^44n|=L{M{uGw`VhlBIVeV zLX_7Q5`g-+HH~mi13;d}qvFzWlA?8w0zi`)L6a9U?Fg1(e0@?75-{&Eg-3yjUx?Gl zrHmv-j~EUSN^_e@fq%Eh?apdZ)#Thjv$>5+@nb*=YP+ItlqRLby~5PdUed}Lv&+Pv zTZYURYeJPgxN#btF;(1?7V6V!<-QocKyY%0h;;o{oSifmoYT;pq=Kv;)+tDVhyARU zwLiXF<%q#05h7j(5#Xy`0J5O^ZCxr=7v=4#-$0r^>s@h&!^E$soWv`EE8l4$o>q;- zaz{X^ym#Ku*QGA<8?jcH$Jj-5$`)i6kKJj05l86pqAa6S z?{nQ30>1*^14j4lSKo_vOLD6&(tt$lKR@PH=6GR}E%E8?9NxV@SeKVeP!WyGMg*;A619zS}dU;-?;wBaxvsvUP zrg}GzK^!$dBRRx04LdmRzO?^$cn3Qz!3(hbd`i}1vJR|9 z2c!Q)hZzP4s-|ux$~=57#eTIU8AtDsiFvuGCfuc^X@oGiU>J&)BZ;7dWqC$Pu}Dz? zA|GtZTRIJjA3V0jra)X~gruH)vWl<`)-M_+V;vv%W@!q*ZIoPyhG{ybX{y9=NJ>!( zso{bcf7ah+7-JP-3zKaH8d-GkfV>Wxo_%~A+}h<~`K5cDz<4ZvB_HO>!up@A_-w9Oi=LkSSGP?AI(|NcvDB7S zS_P}X=39zmpLMll#lNk!w(INYHidWtMe1Au_CllaQ~>_hq3pO#C&?lL1vi z@J#rr=UTPDk^X}J8kx{Pc$yF$e`o`-&$ zGi2;+E&qPWo~zVfC5B>o6f?4k-430dNa9i9$(C=ktr|}UC9vmi>BPSzh4bZ zh9;U{4g5C0;TMofQ(C$JKZ{^QA>G zW=qT%5#+i46Y~^d@ODGq8``>M*zoXxDK$c;r`g)vP8CE%VzG^ThotO(e!#VDb0q5MC^mFiG#~(u@xln3#?7jHd(E$?f;b3P2oetk>qgN)rqmedqpp*BZK5Z=HL4#4}RgqHuo zMzE2CNt|s3)W6!~K#HBP?flCI?qP+D?d!q@dpa9#F21_=?N5;ag+52wlLUonj_9k? zi_ym&CDSnx&Ff@>+7DWXIA@_hGo1VF#qAtpic#ZKzOb;OjuJk|<#z_%oY34YxN%^O zT7znla(-x;DRXugiAXu61lZuPUbQ$y-v0~{_w^4?E*EZ|x0P2wy4QhF07AahDl>sn za%aYJqmC%@h9fPjfTcAjN*V`hm%-8A^MEr5J8oQF8bus8kq*6pB_j)Z-54lY{Et_g4g`7I1Kc zmo#&LA^Zi#=PO~B6r3QEtc~#|)(mD%at%I3b6v@q#SgQ^)J{OX?{YD}TQDNQ5lhrv;}j7Dd_ULqlYNG>*0-l^gcJ54`b6nCnL zo=ae@TT)=EvQpGfih<@|59%XQ-Xs$VF}>)JXiv20jU0n*U7Nx_AC9o!So0T9l=- zbD7BhKVP&bb>*dob*24z1o|&z3F3@+d5_74!%j6T+={+rN33-EWAP;) z?L$NazXYkd_oFWi5lF@8BI@9Yzv};GP5Qiss^;RRW!fpnnr~6DSWZxBkZ@A)Ps8tU zfFQJp!g8Dc*&s6o_)-J-q67zvk%F^8leelRpOSBU6m4wJW%y6zQ}p{aBydc-z^BjS z{3!QJ-Fcd z3I^SA6v;}Sn#`%6nKNHIz(-mI+M-rUTLrN?4W_#p<{GqWo*)%lPl&s0Sh1ew-T_4= zsGGgtld)vz#G*LFCNOs3RJ5xIBhuJN(WQ~$zal)RLbR^y*j;L2{Xmm zhwA%nlYF{=ij;oHtLtep{rXfrGeIixWen8X=!?>Y)WcQC?CXjG2El_JA zLb+*ep&(W@v$lW=SIW?|->PNh_+ni1K>N8eyoWWUx&Aagm1F+3bCo;r z@ciCR?h!lPowq_-r$SL6b<4|=O-z8QYl{kD>4qgWY3y=Rrp(Ms15CnxY83{hldp4J z?U>VQ2#u$9QuK7Y=Vwy3L%!gqR+a*?qxZS+quQH%XlJ&^#c zj}H@f$L;Z|EeR?_SqJ2*Um^T;K<*3^{_$Py59N0Rl)B^j?@Y<6DpQmKf{ai_6{0b; z{2PM^*JKiuSVMOMsebWtGW+$LBe5ac%8d@5g0mf7_{>7OD!E6ODJCNww+h6jkL3U9Ua1|HIc=1;rUeX%rdU-Q9-43GVLBpuydP2iE|>9RdW0 z;O_1Y!QI`1yDeK=D^FY1RsZ|{(A~H1ch6bwAh~kc9YzPc=}kQVCXi^FVHbO*H^YzA zrI$aFb;n{VtU4UXX3A9eOjONcGR3XwN9kAaye8C|6Ut}+yRGi9$=GU==xN}=v{}>Y z%F_VbK0cXa%9+o2tFl55TRmxGAoCt7T7GT%5ARL);)ICTG}&fvZ}hd!kXW5cT@m_J zNv4$0y=s>utWQhWw@$)*!za`-4Vp*_v=X1dOj|=naplMKz&_s>1xHsQGS25E?1iD!Mikmt@{9o*T4(q7lcku0bDJb zB4;mdo`~K3uf>P|GVPA9KlIEj!lVg)(+EBEEF!sh%TUe%5nXl&KiMYHSybN$ej9xM z-a!!ix{T-eFAS}3dSi6gf;UZUk^i5_5RUgJ9*ZUJ_g4v{4+rKqmfr*+J?BOlAt$|v zQB0!9o%^_ELq)95yVAz@-sHUcdKPwsXX2}FFY#ma|7ye?aa4p?t-KB-CP2&ADk~L;R7|#TUbB>bB{(l36CLKiEQDRr?4!M zq5ZZgry-PT?eSlJm$IStW`QP@hSEWvpc9%2?pd>IdC*on!HGW_D$M-STw@gSZ(66=O#PevB3M>gxM)^x%+v`jOr z0G$Nf4Qftski0Dy261zKj|!wB!_Hx}{}{c~JZDIO8grjm3i2LZ2iH)0H)75-X3jKT z)*us9r`c>Dx)v_F<_Be*WMtJXVNeM`GkP$z)*U5oL@Fyd4$l`7w%B4cpo)@ry)9U%jr%_t-aA4~uvo8s$P+m*w3! zYkpEcM2qyuT1koI*jV*4c5?mzP6mj0LOFWFxTCc#@1jv8Jb`a&HY-8({p9*I18nwW z=c}HP7&C;_A%EruLn2HkVge4lz?{{v-;bX;GgM^@Fj}3tbt{)6s9i@du6LX@>RbxOpDzdWf2cXh#i3l2Ms8*!JPnyTc7pab0#*dlnNXi+BG(n*Y zWoc}ymclpCB-ck?mh$l=AkTPqCmE$nKJV|(u-J6NtvgWtC&eqe}PViH+o_^Z4wGN!v7BTTe zkjF}d`opLHd8FjJ%vvz7#!gO}x_O2AOCQ4ehKe>KKo~Ig&ThaOO4F@<)}hPsMOg>6 z{?`hHaDGs&v|a&?ol(0IrCPczPH1-Pk_ z-AiL3r4XabjAwqrx=mltop*ja7U9@%p8Ow88F{Q1B(Azss zRTvNBs&G`I26>uC&z$nHm2<1Bqxxq+P^;Xz7nK=KC-R#?6FakV*{9V%eRPjS*K4dH zXuDEp4MwEh9MRo^AzJ!p z(bN_78X9c3@tdN{D+6I*|GoZuVG zG_bhQf96Z3#c(ajL?w=!TpdpK;a>K1+9It%`y&4yW){yf4BT<Xl1oN%d14nun8c5nOq=9_*&_sSZL}y27K!MzC>uRE|DGN@$EmF45Hmz*EWpY`>&8 zH>Vn5vUZ9PX&s=%4LQb6rb#-^l6P#53j+fY259b(H0sURRS}?ZQ;tASq0=YMd()p(l&QHwD zvy70ixSoO%Wc^Qx7n6mgI1VK&@;^e~^srkTH}V*Qj@4SxOxX#RDH*}r;T%_D6w7r&P;!NiiM4`s;sCC_*V39!?V7#8Y+ z<6ezyS}4v9^Ukn^ng^&OeWVEwIG2a|HM4`y5&*m#fU)xJ>B#?TqRp&ko)>#lpeuPU zi4^%+Ie`8;osc#92dEG*Ab$0CJzohrz7Pz!-lHBj_=Z)^^?%P0T3u6*L@Ua-rowzU zA^)HLVjs#=3TTZccSGEFI(oW78~4`lE2_vTF+_-qkiw` z=|x&TuL6<#4g268SbL2T^ZMX+DU0CuHg9PyDf_&iotbuvMTP*NJz0&L-6GxPJ@ zKK%$pmi?$iB47HA76Pve$xIjv{8@xP{5OHQ!G!Qa{mLcoM0Eiixu zx4PDp=aB<9ll?tbwJ$E^2KF6h3@=m(sb9S;Aj^s-Yvf{I!N(oe8LgGAQDj_)BUNl^ z7Wj`gf1QGM3KnPzZT8N18wIySzVww{{(HrVZihM#gb?#)7B%w#9Ea-&RULV_>ovmF z)KSSOP3mD=C6>-~TM_zv*%~w7_ zo$1?OI_R)Glc!n+e2wUjBS;H+sI_-&Xv*iQ30Nxmq8D`9;m0C8Oh@Jgdwm;~l?R}y^PB_YP^4nf zW%-cesL>U%;|p>^wQc6pk1fEmgpvWe;2+bA%QqZ?eP5(B8A;y`1ecz&+N$5|o3@Ye zIw2#FO|n&Rw0Rxj{|&$=eP4qVmuBGdd;HGE#~!}6_<_RResO;JZS@CT*CnUS06TQZ zKAFIe*Sava+nR^`i$Mmb`%OP&=#tP(_fF+uUqQ$7wV=mvj5)PW{Ib2|(fw(>$C*x& z>1Q3rhr#QE8JdIUtVN{s{)oY-tYA76wh^t^_41YHa+xJxPD9|F2_kUB3iDs)*Xi%8 zZZcI8S4Ts_aMJP++fAF0!FlA$g#+>UGxo;X@;FO<6u(})j4r*g9`QC}l5}l)ak+WA6%;pf#s$FkQW|*w?+gn1Bxf%b zj1qB7I35(UyG}iBPpHhwEV0T|bKNB=BG0+@W9~_9 z$gZg>!uTl_!mio0PT@#^io{7H%C6Wjv1-jO*04g6X6D2^^VUikRQC9d2FD^CYLZ>W zP7`dWsaC z7^oa{jalT_N6gvd-{H?c>W5QOc?(I#|qf{n|PIL4> zUd3XGFz@i_mKN~_b&Rd2??-^$6stu2c`8~|c`R1^cJ3H?66g8W?8A9H-)sgn)WJ0Q@3W}NnqRI9KWE3KP{LoV(Fz!r zq0n5NeK*=V9T%BrY=48@PLp2*lyGWMnm7$_{|JoXg`BVgfReZQ^?b5sJayRcRoOok zc)bX&uJye;P9|Fsf-37u#IJLB=$Bqo8}pxZR(6FM0E|qJQ}{Gg@Um_qPZKJVEiGeh8`N&vz2``%}SP}Er1L~9h74I6&u?Wr} z6nFUFrOKpLv`GG`9GmK(k%z}OWIFoXB|FR><+-o(x*>1<#mF6_X#HDZIM+ZLt6{@s zJ7}wvg;%AgQ%c!;TStu>pZRm5{@xV9S67GUIER6#mQ0%b!3J%s6B|Wf+9A0E z8_6XktFOwXDtxgvE6|~{7rWPQYP4f-d5*?EsX0Iuhp?T*7C+&*`UXT>eG4@8S+zOC_4?2hBJWxL3j1e{HIraXAPHwzHn{96?si={ZcGWVff|0jZRk89SZsQ?A?695CVm%KC64urJr#mx7u{j6c$8Qgma;3-_30X6DI?PFep8S7q)W2b@T?KN)UY@GRMavIE&J9* z8V^qCb7L%sYFfUm>w4V0w9|>b4*&9VVhuV_?|(ZQU?SdH2FPDoyeMVptDaI~G?JoGF@MVDAjb(DGeSe0Y*Mx1HF0 z5?q_&=&%VGa1duD4(RB@%Qx&KYLJVjV1<;bMXPo&i0v%9Cl}!O`Ba2za`J+fTV0Fz z(5iIy^azJRMmmu8ZDY(Rc-vhbUBBy2YVRNgo!>cK;miv2-uK zneg-BOl)&POZ3W9J0yiPTl6HvbeO5)x?|RiGu%Z2<3v<*bEd|UOa;0?4>DN|rgR8J z%Nsu?`qapICBOsG9C4!rYy?Wq4Gm`XSYMmOhLG9c*l#h%PNnogw%S(MQx1Q@V36e$ zp<}yMJL$|!fXFQOn1hbe#wek`@W8>aT~(x6RVx`LP48V@1cdynFyl6@$?4zd(`^x; zyRj8Yyv-{7L>G^kznAh<-Nn(bh5<}u>IdJQ;G?d6LV^2K|JZnMzo4Fnc7g>IUwF5AvFJgk zJ+jUTkYUIDWdvA;E zfm4RSnUAr~Z5VQ{^{=NSzetrsruqJ!$msiu(@~8j+iRj>&cii{45~7v%VWI?ZlbiW zBF-T&dcGDCr!-{-XJ}>TSL=aBIhV&<*2hOeCwgUwYWP3|QaMphm1Va7hi;w5)}aVo zwz_~tV(Y5e-pSAIe-yWCZeRZT96JD81hm#KJr@CGRm!$P1&d#?$`_h)5j0OL5HvH4 z8l3pkP2E4sm&Qe`ay4PBEe7mcTM-~bufHf-YmO`KKugzk9UIKn7WAO4Do(yK0?Tic);606RRyL;`< zJgo)(x5+Mk7<7p`Pf@&K*p)YVyNRHz4IQi$df*yW0$wn)*sm-PG$8yEnVufh4NRTL zkSy(hg#8?Dm6;i)-WmRb*-rA$=+`_xcHEw=wRlclWG>xX^nlH7i62+I2p8%8t+f|W zW17Yo*uU1%)^~6G12b`}>5t})5gDjZ-(cVwtrM$uJ!ZS>1y)QvIIc}sb;2x8m^(z5 zOUr+q!Cu!9rL1)LTXQ}N>~*M~fw`epvX2>od*%iAOM=lnuvcwV6X|)w`HRBax=OnP zk3MQ~A)?aS2e1(p)o5|mL7Fc^oQJr7*-#*C=;Dd(e#3)C>8;8i7bLL4a{bqR1s{Lr z})P+?-!!pyZT@k zyyKi>n*#?Y^r3-0XnA$;(uMGCDw6DN+7g{8JH*8b8eB%u;EH-$wG`d`w*vpErw>?E zSG~k2qsmGE!}MR$^`6JqTTQ z6ysBAKe!M(RLidGs-xyRLYVTrH1Hvmrr@z@sl|) zvJ9v=dBdqj(X7Q-(`82!FXri$B|fLyWEZe(E$!|{5H3!KL3gq53`1M>wR`TS{R<6B zR&a7&g9&7WC~jaJ^m_H(_dbh;OD=SQWIQdEG7!+4_!6_cE}i$aRJ$aXi}N$bius_y zmSJjSOD$!SWXy^*RbmrpQ%WtcxF|qrj`CwhFkG$?!S1BioPbd+1Wv<*qUqV3TtLF%|)(SQQP9+5E zYK4hvFL|He6LbBh2aI82h!r+zHlC?rS8DPeX68o=6k{$q*XxG<&rc^@7j~d%3B}c% zs7%scC7hl95z5zva!fux?ZS$LZy@_f*i-~mc1Id3=?7HZvwY8`6VL@xuuhfo8C6G0 zR%AUo+r3{QZ_aApkhJ-vcXCtM7Rc3KdHs**Lzexg?`qU25!N5&cha|9mmnyi)YO6A z;emtJ=iV5HPf;vY7jek+C+Xe)1JADOdiLYplTpYG-MKrAsOys6uK8YV?JY}K^zMm@ z^|@UDw%SWel`yAZ)L<67(Gnq~JKiQ4Gfr;tCF)%W`^TQUcyu|d0PPsT3D#FF{uvHB z1@r9|cd~!aH?h5EZek-iP9Gh@Aw?<@i}#`m6U@DOj8xud$e)_9gF_`D%@spK+~V3B%vWbd1X**TswvQ8^E*Hp@sVkRsnHu33P5wIC^0F>A`;?HGW(O^=&Mmhs#~fY47M`?_O%Ww zEIqEv;Y6;X7hJ=I*YK=7_3CV=x)oNmI*ZoTgD!{f_@B#Cq=%5%H;p%2MZ})Zj{F#O z(JE5dSYNJ^jp75FjFIGu;>fA`JtcQb`d4rt}^!7mc zW%)#*x?Pt@+=j(>_Bq#QALMm=R5~b<%uiJD?|QPdEU}un-3OXvQ#)f)`dZH^QqrT> zd|BaTSilNji)#X@k^C|vE}hgeZtuCf%VrXA#6UfEsu3&6^%JU3v;>j%+@{&L^N7C+ zedO27g6GP`6}p?uuE535*MwYCWXF~!VP*%2SwID}wk_EhZI4@T{2f%OPMvj4E{#q~ z<#)dnpBe8FA09A0TIwXpYUJww^T()G+ZgFNK6bGAHuD+8DHOW2L)pH*4v$tDCi)d1 zJ27E;cLx6{`3h#~xa~Smu&;jZ(B^SP9`Fd-z9_qTEqrNOHxacu#l4@*5OxJ5`^5O_ z8jcNaYtI?Ju$V^%J5y8srH2qqHH>+DsOuA|QuL zE;eE_zpn)de(NHc4uL0qTNBQ;H6;sMobbOR{nhLD>(v4Oj0>M$AsqZ7kD)oOnX1XV zoz<%ik84H*^|7}=zV+bjIJv;T3DLG0`JaVD@-%&?61*RVqwEB;@u9!B@V)+bUc%W(|p)w^u(fGsNrX;<=0~mRdp*#JGrKgc3@W#G||ReHV^gr?O_*e-8Ktqlypoh?0`6OPG4FUkX7VpJ&Wr`Nrfot_-U&N%S;(t`RmIh z`NP9iP*52|R3*2;=RHS{$Xp^tE8ce-5LL*Yq$eseB!+0aSretALQj<{{#h%*02xiE(8eek6zv2? z*jlea`1U+%NR=kDT}1XsT{{$7bK{cT9ZGb+yVc|m^r^5+A)gp`{z+95ySyWUBh*xW zThNIBFv?+r60tT`)s{P|PI&Gy3!Pi(y@vtBcp9ut!)~Hzi5y#pDQASC#47GI`5iKA z%Z5ADY=yU7^j&@4x}qS_&XnMymWfBdAPH!yO7^Au%8KKk>UwAtGR~EHC32G6b5!bR z7NZ!aCv+|uPhq}4T`27QUi2%{@~;Sqnszck;wXC&Nn5fJ7Y#4RG=qloLuo%%0uDe) zU3gRaySORR~Tw2=T$w);1R6$6k2poVNXFVfZ}aPK^evg>6OdZPvV4 zC|+vf$Db8j1WjHxL-p?qShu$6+(%E@`?MkC(9+P1t}Kbs>B$+$ZGA9dvweOws73PJ z{^o_KC9)%}0i9YUKFT;R;L4=t`pj1&oI=Xp)+nf`grH>Xz5+~rex+M-IqR2%z@dnA zT(Bhh??Gh@JxO!3`e>8haa5C1XQA#t96IYnT6I1u^)of;7DFPqQ1i9bxW!h8h|Fn; z(dEo{k3O#f3KueRG_k_)hRrx!pqEALs&X^VG!^<}bVHrq(KC(<2K_~F-f!9dN8^aZ z(F(5SH&MUn0SoEkI;7fx(SS5L8JA<~yc?JHid%25>OX9WjSPw>>iHP%Xm?#`x&I8_ z+w|B2mv*2q$0A?TwaS%3aAm;Eb$KiQt|;eL;VfAL`gbT3B9YE;Ry*8?)UNRJX4PdF z$NLlv+N-8?1Hh>O?mp<#?enw#lYT%-=w$cmbYM!4sHzEBWY5XHBZ5H#IB;TD%F7dB ztZ1^E2(fp19p<|?5pvwJFgF)l;P{TSU`{DGsE%eFQhQ$yHS%-N9QbEuNh=>%_&`%# zy*^VzPoeM;BB*FLtsAKYE27CdUc7$6pgMFSfC_6%Cmw zkR_lah~xD|2zXsqcB$8jGMECvK1m$bzzJ|sW|#?6?mI@yx7`#9 zbs(URjX>U;jJgS~s%V2go~1&TN||_IvwM;| z>l8mn#D4Lv(H*b8br(Smi%U=MqapL4bMSdsjfZsn7q&Lx-gL%aW&_8;8(TOlK{+pdzNZ7|TEraA@B|2nMh<2Qsx8m7Z#v`Y478Rh%0 z4A@4DTq$F&NYj>lMR4z_0d$S(GgMFkX=o2GF71nL{s$Z zGJjlUzt?XBC%UVBK$gnh1;YM=&o>T@<$$ZI^pv3FaQT_e^oKo;Nv5m}2)$l)HF^!>&8gtM zHB7sRpl%%R<(O_Ti0yTZRB*yEd-S6uBIwm|5u9_@u$*JDul7y|?JVZ77i@jyX>@A0 z9|EKHO)W>8DOEg;(YjbJU(HlT@2bVPI?cGU1UQBnRS5cOvsZ?QT*e00%r72PXQfv6 zDQDO-lq>B@UqSy@RdVeLl*`I3btEZri9dLu%|PMRMQ8n*!)K>!(>Y3WTkcr+p2s?D zXHW;NNw8Kb1#S4E0g9~xKd#hEf2k^M0 z-nfH`!7A#qz-j#F_bn25yY-(TyM3&D=fH7hO0NrO*0|&#RQ5Xv8eMcVf9*n44Hm|$ z`=`g>MYe%sZ=4_Mn%5`vS7}j?O^moB6(l6s#y{j32OFV&|K|uKbLypeAuk4fhiph` zm^OhT)P{A*_3LrHk#yn5{NMnNY!qCB?)vI|&{f#`q?8N2tk}Y#sYXd_z23up(hnGb zs6=?u-!x*m5f0eR7hJuop^KqCQ{~;B&&Xe8drrNVr93>5JKFYP_B*AT^ryt{J07)K zFK*;v>ZH1Vf?CRbgZ7X3AY5Bcvtm%G6RG^F;sO?v@wBCxk}-SUgMAaF*DEqO14iq$ zr)_F_ImnXK0~v`*eMu?TD;{6z_2wa`a*$%yQ#5NGz&%pepoSH0Uo39P=fL{a$ca~# z0)~y+ep+NzGq68|Daqoyv!8USiQc|QLjsS%?YDK(fcvl0VuQCLY`Q-y!+8aRb?+B7 zw(I#-zKjkhPS_~!$91D3D!-(XMYu@Rg~XL}32CKoYfLQI{m;^+f|n5S_j$$s5Meni zx&Uw}dJ#NU{hV)EG@1TTOdXAqta~+kBn_vswid;3ODjfj4Er9A9)>BGpOF3|VaeUwPh=CN5 z$w#lY_emr>#qVk)8ny zT9hTf>D#-*g~c7cl>5_)@?A4BnX${znG9Rb*yfr8L_GZ){Ace~x|&=cdWqn_{G$2_ zc=idZif@)TH>v6*;~l)x^Kzer=G9ZrHa~^_~CxC3g-YX~h(y4~!&!K9WNivOLy52qD$c+UUb#M7?a;JwP=a)l8_qaxTgCw1&Y z7H23@UI@?YGeac)G>#}b??MP}$b{37wU$9^?VJcEM%375C4^>p-hor@o!OB-MbV;i zaYtmBBr{os-_&R$K>kb)quh(KjmUI3Vpe2?p>H%}jIpm0&LX^spyk1#_E1CWa~nqQwK#2XFXu2^7)WX32)1KU(`$Xs+U+}Q zK|MW9%YqM5s;_&U6uP!SW+|F+gc(8cTWeLi(8={MBtiI)WKri7_30z5!4$~-^aB7&agc~;F_ZZ#^!qgt?lvpnL*kZJDED0HeR}Dhont~PF5hT5vQBJ ziQ(T`sYb;T_9Qlk@{*z=-iBDv_ofHQV<3O*t`{pzP_+4TH+H_c|L}WYRuH&!p{BD` z<#$3=#7tb?ey3WRMa`dx*e^nLCTJwStaF}T*$-*Y zMZ5PPOcq0shePds95?>)trans>2&+}Sb`K0R3wE#lx7kOE;WkhJqjPB!sFRkH5v)STt=W~iA1afXI7Rb`Yq%iXT1npU4RWAQc~IQSB2u`3dgwG z_yhXAl9?T~T zOb`36XEmTZKkU7oI7M2|%t&3emwvHA)D1qhR+)^@J8`Y)>`!8kz?YHF&IYx?(agU^ zz?w~ZtBT$^OJ^he?~p!9;)rf~eOsX}AVN`#1fM#~*r5?q;-iwBA|d|{+f}1bmCSw7 zW+JAWjczwD$`ryW%+-LSGTfr;+OSs2Tm{F*iIEyoLVjmzy-flhy*TNmBLZ z3L^bhnA`&3tc78&Ct@UE)P~r6Ip9?Ih7EbmNiggEy2krCzScMeQ*q-Vm+Z#%c-H?!nFh0HSv9vCBh-wgK^sk-7+;jhBqvV8N)`utd~FW_nfZzXC#SRNCq-ViAkEX& zDRB8G7^-FkTwZ6p{y&ZYu1~$ixC2O&Xx0D6C1?dUeR7JkxA5?T%nsTw#6%;6v>N=8 zz^nkZKv%pXgi(;M=Jss!?Lv}#3Q86;P!+&?+!NlLGklWsr-TvSrM8qZLyQkYnl{l) zk|j`*Pio#KEfD!h6+>I_Vz#h#BCylmb^*>x#!7#6WpIcNLziY0FS$ zg$>97zGPS8T<*5}ZK+V^BU6bQM~39G(JLR{!KR;$^+qP&>nA;?>KK=W=}-Fu)Nah) z;*@fAL6o@q#>x|%r@@1MT0}4eu&C~N;+8eb=r$K7ZXjp}$y^G6!@JroAzOCGns7z7 zY|lD+_*xwkZQWQKy8=QykTv z6J!EWpF=5Ff)X9+SIOj(CGc9!F#4a=-$({oQkRz>&U3)Jo$)&o8TdNp!M-3Xq8cN?Ba;=gWppb~~ABLaY{ zPa=ta%5Nu|eDH~@1EZR%F)VDv`Iu)}+-m{7X-*2lZV+)a9uJ1S)kUlV2#YZjzyTAW zB1^92hsI@ny@~lNaVd#G5|xu#3`$>{?-ze}3p26e-v%b4k)ILoeA^oc1tGMVe5}vp zDS^z{;{}=2ZOHB~?@K&ZxOU{yB{YmK;@8tiVL;+J^eO&7+&_mZ2H~R4+63)MEpzSB z@)iv7_z&^m8O&vtgBslu^6UwO?2$kRW~NG2^7-+gV%*DS)$s%4wW-Kep$B@8)xKe~ z+E>5)!$AyTPt-_ZZzv|{)2Wx-Psa|!N5sssQ*jC799Z`U=-7sX50hi?dqeNi{9p4e zb|yQ?#NlWK5vG)o%y5gyZu6GRiZi0GB^uLCcZEmoCM~k3A5D+FI1)+ihD*f8rJf$jH@l@sLC0x z=1M|#Sw^>+?N5pVlSX*k=t3Z9gu1ky2Vt&wE(>HaYOZ}GBr}PM%8#9mWDeDU?fhrm zu;B|-1SAlvT|;9D+zpfks*$Gyuu-!lEX)$bUycNvF9^g=#(7p))=^Ij`Kxbd=~Q?; zeorRbP=+@)ZNT14k^gppTVoRa{rdN9IFmRqUI1*J>*Rou%kL1-ZZ5cD4vi>YMc=Fh?fMZ@j^-2CFvg(3h z8BwPmlp?_Jvrr|#SU7~Y#DYo-5<3rpXQi)sdr}B_^I2%^BfM*1u0vSz(o(*g zQ!!NcHR(s{l>oYygMQ8jiF}3s+GrodePqh{Aimj(#t5nr z6RFjy0?>yFv&4sK)^XSp!F?(`-assLiBDy#1Fw zk(D1PLxP7O+JDN9y17?&|D!5?UxPBd=lgo#>l)@C|7WCoht%6@9?9T6xr!2P`$h}f z|6VU$g={}cHB=Ww45{=A5o(t0^k3Mm!R8!m2n#o zYoUgq_ASIz#kSrKcy(>)_g~TSYR+|JRHIb;fd55raZYR}Icks}{-!tr9Xpn73wp>b z)gjilM_tNP+AvVNjvp!?!!!CN50T!kJ!{643zCu2ijR=;z*>Iqo;fn5XKVg*P8$i4 z`njhr8%g86RAAcaWoGyE&hdx~m96(Q0=krR_!$U}UrWI}K!&Ah6y;)=t7OUXZ2qy) zz4uISf^=z1%WA$a1CwkHRZW#AzG>Ow6sCYfv5r&plXGe25Zn6!0-g~SGkvEs$A1Id=(K3dRWYtvVXxaQDX1aH)c`|+0WDrh|k3>!v zDu#zle|i3cnVv*_DN{?F@zkZqLI1b;bF0?s`$j93pGm-`X@SA5s3&9M0e44P7A&<*M!5G zGAmxm0T(`$CXed5|J$q$&jrD#$MYq08{bZ`@hnz}FKTE}-t{{5EB`jZA*0ujj|Y~@ zJ2ihtp%4~?GgTefs%WZ9-M(Jqu{jsISEpf7{Kz^Vjt4o}#0cv9AA1hu>d^dp6Kdv0 zyX?YZAr4ln>^=GvhFVrXzJ*OabT(14v4_8&2}C*I3F>^P?Uw>yxO)~BphtKeXZ2rgf?N;NN+$UbmDLTC<8W3fG?$Xl!2U2vQJhtf3{ ziDZK${txuTFAGuvAIh8CFr;G(DB79&65G?^K3dNz8ffj>epFA>rLGi+hs2NEbNqpjz#@fS7$ST9`6R> zj8D!b9y7o7K63vP4fjc+LD+utjvL)GMu0O`4O}b1z!!(ib!JR5Mt+X_Z72~x_t)OI zxv^5($ss&>n0Rzs@oEquPh0#Bx;mQJY!g-LnrrIZB$19`UxXf7=!bjuv1dmJcdw~9;P>YuD7usr(c9e%wJbO zZqag%`~^K z**J-E!M4@k8*=C7V>bTco^{<~Mk$W(gokAZjaZ3&5~kUaD2pc~9NlSpO;MTn=;vXH z0GhcA6~7kzWEP>BU{65CM-hhll4V6zBgnpscDP4%RvQvS8UMWZ#LG!c|9SJ>EIS0g z)6Y#(mNUUM=waGuzg2?}y~VT+ai`ti%;T^S#@}|Ej3|+!%oA}N3q9v-4%O6ap7|R7 zJeO>wN6bHSeKut77Qp3PIA#A8HjbDdy#L@HDD72IO{)J=ApT|?&~4sLcEAp5n;4;a zd8T$@>dAtjfoT>2Lcl{{NAT`BTkl;HV3g0Zmi$?aS4-@82Tm_hzbcF%25d+dGlra~ z0@-PJhP@-+EH&`Wx9J()rEo`UIjeK%&8aEqa@0Jo)oEZD1HVG`-)54tL8?6qPLSBU zJBI2E`fn&ItUVSx=;lG#Q9In6>u5vy@pfr zv5u?M*fpg1D5G^py~1^7sBb?}%HeF&mO zy_v@XwJJK^93Nk0q*9i%ljYuJ_2uJS%x#EEmO!QZm~b-3E`+T@&L}-REb~V$0^6Fd z$PU|ZP0O=%aoWG75C2rayFO5Ma=j_!d?8pPlwa%Mj>^gD*LaCSU(OLuCbd4(YfrUp#lm(I(OB?Y>h^N`1#nbB; z=eRZg@WHjC>vu}ldW5pDm|Sf6%NE%H*R2?C=j?b(2OAIUeUEFOLXh}8W-2ROlfCgi zi|1TIUTmd)Q0YdlqSa;xQM@G@mDdhH&z_0(d^xE15xGDuS$%c3Z`ZNKx19YC^;?u= zAhsjLedM80?b6oKsnp3DzFZj_WTBsqX|e7PQ+;l`b$#IY1cfjs3u&=+{2;lUzG5M$ zw@GinpqB3anT+Bq6LM(b3XEUbtzQUbxxMj{R~x?EL6L>3qIt7j@*B45gY&+b0~12# z{I_SG83;|BAQ^X})J80ACRV)|s~&*_VAwp?1VWS!lZqKZhy>#Lw@!jo-!oqxZ;K?s zLhG8otWk2$TjW0%-te%5FYv>E*zM?yC?W8#*@(*r5{s2s5N!kOVsHjEV>3jZI`u;7 zkFXHu?F<0Z*z&~_%Sut1>wSUDuyX2jI5r&NwUEuX zUF~6G!M0LV*9;iHADo5S*a zN2a_PS53l8*(O{Gxck=jA55KNblmZ~?PJ@vZQHhOtFdi6ZPGYtl8Gj^o5r@2#!h4B z%>SHw?!9kj%~~__YS!%D*f#klEF3w5#ATNS2BK11X+i4R24TRTz;EuuRU@k{Lq5>hn}td z9bS-~pa}l5otVElKA+&g4rh}hQJ{56V~9X64J8o@?M_I1XHI!tWtm6fZtBraRozyA zmQKa|&iHzMmXR<#Rhq0T^U41CT-Bl(S*ogd-o0QGI!^7p#N1-w&tO&UdC&Sfcto7M zDFjJ@h%881Jz>SOgDDVce!LofGD+2PcZ%2i^$nFGz#j<)p#}g5-HG^o+KiJBh_KWI1DC z&r1+htwF2-Fp%$|dQ_()C;WpF^jWlXw$!OHZ_`?&aEBKB$+370$vVVxu=MP{!mAvX zr3GjN_q#Qx0V+JXC*WsU5m?7S>IUBX0QZ-x|1Acg?%(iUMdhj#U;bhI7f|>`>ibBW zvRl>n3frFampk1i&uq5*XLDcKYIFQP#SvHTbvNLlg&}j$Dn*Ol5m8mEO46IoiL&?x zf_tig=*?${Yc^@3erIOfJkzSasB`L%n8O?QX3a*E*bN8H~&eLtr z%~#9*Rr7}5K-VC71_$H7nq`i88v_|zz9rV}u_ut=JF0yZg^}KaqrzQ_wVujnBNxe$ zhegN(n&cLVg!);+GZ$(Ul%lPmfAAAC-ple+T3$g+oJfkK7V?7`tNtX2`1;`GFcowE zAM+Pz9~p4y;T~`R8HxW}=L!dHBO#1>&Psoduag{a)9D&G>~;tV!KEv4|k{Sf$Es*s*WuztEAD$!BIbnrqA!GG^u;2?OZC zxvU`}hyNG^2J4|8?)}DW>_Bo~ON1)`z&*>Rrf#dIH{W_)R&P`3P3rIwv8-OQ?Cm); z*cU?))Xcsn(#&vgnR+>6QWf7*sj6$6yAdQvNBZbXik@Xd+PUGPT_<#QioFfLZ1^=e z<0P4JzD&(~3lfpA99BG)-<2rAZcBd$TG67ckP{#IDvj;$?Uh))syYQjSP zWqIkEWOsTJExO4fk>j9!&}7e~l63oz##LvXHD_b$2{~9UB+3%Hx`>-QXX;dHq@N}_ zqC601LKD;NO#;r#%fpWid};MB5v0%~{<4T7s)V0CkRcANT_Gw<a{d{_|@&DbMW5U!Piuq)Cy|R(-l` z@A1u#kZ*QuU;H>((HGt9^8{Th9(wyxcLRjEB=em~HhvGfy+Iu8%OK0)G3n7U%X*x^ zM<_i{-_qmrLc&L&D!vUt6kiIeF)}70iB8B=!JTBMuicqjOWsW;monjtw-6$SSP*il z>AUj|zFr)sNUxCPs&o*X$xF@z$bf!XOLQP*()csmh=tPsfGRwIRou=EGrQ0qrMelp zC;#SZW564NMk6`qWArD9G_Znn$pU`Cs6u8@WdwlG_c%lftpkh?Do?sQ# zxsbL?-P`UCBlXUxm@dgx87k_N>ASJU=ZS$_8)b+&&}xKM+6*GC5kV~j)NNyI2i+TJ zY>cz;A~ZG8O*6-1T_z+w%}0IBf=5%mGp%tNM0Zp~4CIspir7SwApDlrnOHSCPWR}c zT9kx|Q`Zgg%`_@CJ`eaK{RMX21=&AG!Rb5_YFcT0mBuwSO=*!10`%*OI*FwHtTgDX z;1B+hSw}YrPm261>#k`hR?F5|6A2CS$|>yz8xhI&UqufihB$&UaprLf_}XZfdY}CI z#EJjGG$~%F)-XpQ&x7ixDZ2ew-Y4edfCEe74>3N7z<}U(31X^WC4o@DAe-0;Drt27 zHS;bQosTN)^4F(p>33F(zg?oyUCc;+lB@t?W}x+5EQ#pEIIpED;ie1jq8`LmEg`;A z1xmgcbyn1Iys*<$sxUu9dw%M;b|!*!`+p3^u3HFQBXN`WLdk)5JK&9IHyvo}{E>^N z9%^t$-`0G>_R_5P1u|`L&ETKSi!8-fWR626fzpTQNn=D`?S4SyMVR&#E&wky1lS*CG|*9xdJ- zBfeg*>{iPwN>=nS>$X^Vuw~{<%AjoRNjO4$W~I{^|5};jRvyuZV2#JG#mPMFLFNEZ z?z3UV8^s$d{+fFMjg#zM2maN+GYYt@rnpnZ-y_oMVNZz_Vs&ge2O?w9+W3h}E_Y9? zgm*WW`PwaGl|=r57z1e_@awz=fn^Qpmmn8W#2;*Fd$=tDQ}EApgt`l)BPkum8WB+jEn{%x5)98)2Ob2^ zF)%PAcLh12o;MP5piR0_cTJbIo0}ie1WZ0qDH3-z94wTxzmZpKqxN2JM2VJ2W z9ibZKqaSsQJk>266_tPfs_R%kKBC;(0x2|Ev(lmXv>*DRF8BTvz137bAOvX)XnC?J zh=gTvMCe0=)sSgVw-FZU&Or(6qT1hR*{F>>XkQLQJthft+Vw>#hf1&1-d_8CjZ5oL z%-ZS#sENI93uhy2;xd0B#or-0YPYyR7eRvDW7BS|c}wEkFPa7#ck`_X8{kbq#-eon z%bAkLa6LWffPQv2+Y;QLxx zS!(bafAuY&?6_?1iAP-D(6A18n3^E0Ub!YaDD}<|r)Q-u6zlHSR%fN*I~gc#mh~zI zYKm~+$lF71rC8k_7UOQ{oE+zKVBR`cn><7_ERgjy&nEpY5B*Xye`*S?!<|K4xztRl|o9hNuN<3_er zQd^pY)qe|iJ?^A|#=?5fFPO0@Nt{KV#*OGLr`9Y1I#%$9r_xX>$Yf3Jp-L3-*?D#1 z+!@mEKZb5xHU?1v|1c|FI87DQjTo`aP@ebjH$xp*QWk%BAjKjd6Pr4xa>}{Q@?)h) zvf}|iLIR-@MBkvZ3j)IyPO=i=`by0h91R&6#;|TPIEh%SeapQG%D&SQg6CoXdPJMt zLvuCt3&ziuzz4|7gn_w0N|90HWp!aRQ=UUiM0;I4$s!sLkLhdS=#nkbIaMN1=S2M1*(*`bR|v@j%=wHg>mgU+Z~3>#>% zR4yL*sJ!7+3@zMal{5>LHi)Z_Z>}*uPdrFpcYTzt?GOQ~F>2!JTVPv+a#QPT@q(fs z>XU`|Ly%vG3rIVkrjOf@D(PL_cc0omy2o5w!u%uoQ+~Se@TsX{u~cY-c$iK|t0G7u z7fshD(|Z@V`3*tW_=y7ocNYD6t9W7P<7An7&FepHX^&3}rulVNf(njJmlinJwT-B* zHc=;SWttY2us^kpA3nYcc3i(e&gG!%5ZG*#!u~zh4@!;!Hbw>Pa8f}0blXm38n02r zsiZ9Xzpa=x)b#LjIwYlW+&z+0N%B0|Z+_Su)MqL8k~HV=w_M!#pok=nOhO{V%=4jI z615rOg}Aplepnrk)7wm6maRRmfs{3UWO@nc-ts-7n=kBVCqD+g9!vmOLgJumN-0wukEd)A zymGx@X#5hAAbqqm4@@8EmNdU$Hz_XCdVqQq$zhoDmP@Vx;GeqJzd1Y_kT|K>BhZ_^_vr zZ!3lytzP*{^t^BBp&}Q&Snou)i-4G+YaGKgdQJI$MqB+FQuRuLP?&Jh<90fac(Dc` zMBQ=j*NWSCfS)slq%MsMA1dq1oprEm1{q6ELj4MtJiw6J7@qnJG26R$PEa3S41>4y z4QLmBP45%*7qa~fleB+ze`a^2?}`6&bNjL3so06lY@_9^!S@~ubkT9)>v3t7BoBZ_ z@mzP?`STQc?^-j>1V54PUukdV%(zoOYy09+APC2oJ5_mvz;?X>b4^%3a8>=(fB3Nb z_vKq8Zgv`+^e#=IPHwF4nSNRFPYY4|xMX}rDQ@mo5&dCH5VXQR`qGM9ECX8R$2B$p zu&rDs?w9My0-vg28QzvkM*C)<``h;zjD62~0#h^^88X$3Gl>zILopXv#G`X6vPJgq z_upTt?;J>#e+PF0F&k$PBLMO6NRQ^&nC_0j>kdPfE$T@QTBQU_l``CCF8~1jYpf;u z>LfN7P~r5(2JxpiFA+~M3w5R3KNYG=s^N+_%_Hem3}Lp@woa&Hjt(q}IkL86#wB-T zCI)S5X7OGWr(5B|xylw$7nFfa=|FCL_*X^wwr45+}y*h5ePTPU2ES;)!@94MQ-!ITmYz`g(^NBL`1sT2zBE7 zn&t8*-4^HC@+U_I)1WX3ZpX?n&FCc@!hli#P34;3M~|EwMk%x;FjAfa+3u!}j zk#VvnIqiT8yfj8yxI3jX`n1`8jN+tCMXK%J*p6%6Q`fst5vg$h$0xCXo2K}Ct#ICq zi?h4MKX2A&*Fi^z<)=`xC*NfMcWu`C1MweXx-5vMx~QFPF0#JfFau)=-7GN5{Ev4` z4l7>VZAFg9Bus_E!)jUJiAnXD3YY87I9XZd)PPxQQKlTZ|0`3ct3PG^ z#vrArgu6NVRqYTk>9N%98_Cs`3KjjKK(6@24c(w6u38J;>|3u7dGHz2{4p)sY8PRY zUgE~rn9gqFh=Susn~%=`w@~QCg;1jhVvP|s^yTY{omosT1A-C?tot0F&DW)R;^wE# z?-|t+ytu}YvZlTq()%XN1v+(iA!9)n_OP37>6Io8{G&Ra?}F>k;(cuV6Kd(sl0pUC zDPqR-ITJ%Cp8bn!Fda?EG=+qqDNK2SxK?&VU}9o!qXG*9TPu$w$wgGv+QF2zoRRo zhi@b}5RNz%c*iRm`cJmt&)-tj0hv8x9>xIoYz%v{?BA#LI|*9lpvLeuTQvN<<#m^6MraADFw+{cjHi0>W8B2*^?SKb4? zvi;-ZoV4cm?L}(9wLt``F6^MTUJ?bK6uv0hx+6V#`J$EeWuyr;Rs;`4xH>5^Vv(e? zHFho#FJ@2Bb@*&pUnxKs)D|`5z*hA4X<&H{A;u~C@L|R6CKDsB#3CKt&UIk(Um;Mp z-gX1-mIQY5R47vk<_98X%`DdEAoll66f7IbcYga;{bCHFCPQ=)-sJHrM5Lc^fdnv} zb0KE9i(xKUK1tyfincjw1qH`kUm8LK<2I5ULwgz*&i3=6=wEFp7)xF|4$f0ZBE!eu zn4yhhQlP}EyaaY_RgG;V%Agj5c;PkF{exQ&FoV)geji7zoujMCt2bx6z>%tiTbEO$ zPA_YfoM-0e2t@JptHl{MH&v=`9_P$?W%amhty>iV!q}#+f3{|c1bAJ~`)mI#hp1rD zZFWMj;i#pzHcbM6e}iPSuV%qzWN*4tbRu@YD-4RJtqi``4M|CO5`pVjgPm|AMfrSX zB^PLly$*TyG3UjfTU>*PD3MU6SuxmQZMlBV4i$70lz3)!E`K3^JX9=sqi`fjYG}qRT;xIC=WMt~=$Rh>cSNmBKiO zXHdV5XqrGu`*rI=;sJAeQL9xTXx?wB|Go-V{ePEufO-y{an%X1a~Ie(d+<1P=_C>5 z!ctuQiG^(8(3=-HL`yU)mxZqygTdhsRYyEOVarytT+rX_?FSbsN0!~H zsO=?Obwe?6>@j+%DMw=&OIwOW{t%?S!4r|T5(Zgt0^VzbY&LrV6_uOeBAp}?^XsA| z9!TF5HPkA{&v4oc=sf%pPryafg8V^Pn*!LvQf%SY_WQ!+pf?fys8$>0?9Xy=C((8s zsc&OJ!$Cd|LIYlrN37&$;#f`fZ#ymJmKdUL|BVD$6u`n~IxT)I-b^`fxpjTKe_EH* zy*pq-DqmlKw=c?ewzpFsXgxoQYFGgB zZ`oa)9=C>Mti}I&bg7wEGPC{*5wUnx+l78|b|@)^iGo#zO+<=$3|B=yMp*wnrmqQB zc*BRhu{-t$rRe@Y%5#$Z`hL|ctZq-EE}6EWorQ$8ec9Cb8V;vm>51Sp>C-Red}F(v zZpZ}MWC~*VCS1@o8}`XG0u;;79+{5&rlIMb064gHYlfNacBCz-n5Mu*ibKK9L(X&Q zN-B0_Ko>vzi*-AIriAh)P^nM=XdDX5zTChcS5qSx*wo;NJ6ZEM37B9G6#mh19c*RE z-tLn)IKPlQ_#1*K|8g{nl8rjy1_{Od=2xgTE6pj@^w1LLFBH7I54A?<%#mN}1-Y0j9B08E>*Oi-oO)CNU>##gw+>L{ zKcp+yh%(hO&8x>w(N+YBXP0yotlmN-n_@B> zfpv}Psvy>U5{9A9ie}eEQya1R-O$yGbY922de@qlnqlqqy09Z|?oP7fdpz=ODZq7@ zx$w={DDWL$=Tc(iT;R!dI|39HyOIQ_JlYs z`?C4$1}>f?1uB%MmH_?)8eaa0K?$^91t^)cM{4D2Kqv6*CAe`E*y*hxR0-PYV#{;5 z*3Wt8SQ3Hg7g&;*^0A0k<{`S@7<5De(W~zm<9m2SAI89owdm|>AIpc0C-c({(a4^9 z#ISSJBBk0#E_-z4qITdUxG{C-RR#ebTD)1pj{#2e{*vLzZ2ZRpm1b`rj=LXzH}H>i zk7-kqx`MebUFbgoNfa88G+AOC_>!#{AgS{X{}ofsvspDdWeiX%AW~~2IqC>h>LbfL z7JedaaN)@hWr^uA{aHqlY0@V0sZ~tK3dSmtDippafcTX#VembZN+N94M;~KcPvGm> z1HiD@Rc6MVv-~HEWI0j**k=B>;z+Zqkk;P}9aPJ?Op^oO$xlR41V;gu7#>fx)f*m4 zA-)_K?2O<4isShq{P6K$;1#h{9VGQ6Ja&soalI>AbE^{YklxlA79Ya;nW2o2(d7-{FW2cu2j z9T*aqx%7&%wEo-1MBp}W4VX!}LvvQ0_7JFBikLtL%y9__VW$VaSTDPuy9I=(tX~;N z2wlvCdS8FvqSKBC1=1!XiC|A-3HidcUo23fERy>?0(|q==SLajDf?7Jqg(o^l+_KE zHjeJ+Kc}tO*o`FF^-K+w2taL2ZGD7-Cm#c@VFxj$Tastky$%` z*nilC00*V7Pk1Z4Md1W8!ZVg*YQRo5X|e0uB~3Je8isiF0ab7rWBp>x1+nm^^Zxac z8Yzu^>jd4)kgatG&qbEDhi{vS-dj9wyV*l~HVLqH#ab#AupmbKR7Li=7DIfX$OKrP z!N)=s9w{XXQfX*hPBTeP8$^+%!Km%a`jzYHUofVMjRY&9$&sH}#aA@wa#^uZ=j=D#LbhyHL0pLzSYnD|jjporNXs98S%A1wF3#7-L~uFRc%CIEW4;r9}XqBx<9X zQ-?N%yTgbTpkw;%CU4|XU2rQ*QQufO1{|vrWk)9jr?_b;JoUB+r$F1)Zc+8~AXhdE zg6fPeKm%J`-7mWBL-6UJUV(rgRFslI1YpMaF{>HEjLc-RiPnB%7Vb!uST?!{AP%LC zOdLq8QO(%hH@WUBxh0HDuUySTxc+o0bFhiWp{N)bL~c4fXXq-~QbUGgDDH2AvKEDn zl2s*+WL$OTR^)fiqcX<2@Bx^Lm!Jwid0|Ha1)Za>Gep}_qojxmf&}%c^^s}KTyBei zMBy{15e#_^fmc+U8@#25yC#z%U*bg?(hJK|a*0XgZH?e3E_4v`TsFDhPW#``L_Jh| zf$1yzcf=;neDDl8SR<-!2=4KFr*zL||1k-ET4R1<>w0$B@tpSwi~8DkvKid0^ZHXu*-Qi{ap`NM-NFMqwQqe_EgVBHFIsML$Aw?46N; z2(3T{_;!?2%yqJQQ{KcHehKTW@X^SatduHNw>bi%=p=?i9M5qYO_a-lWE zRx|rSyDNFz5-=;Y7&A;;Fnl2VG;jbEe+=N8O>W%@xD>&nu}SMd-Ha;>_+T0#qfZ9X&M;Y?s<;>YRddhrcaVH4zw1Hj@QrIo&vDiI0dPY)% zR_9G{uGJnbN-tg1@#Ixuq(-ZbO!4Vg99BrfIR6jyVjUuYu1s2Q26NQaih=sFxJoWx z`3#E%_nMZ1rh_|cI}obq4dxYznoQ6(mZq3QAyS%Dyzo5=v^?RyKVKTk z$jL))qxzGi4I@~mO%uY(jS*O2Il!b`;oOe<&MzG$dag5o(B&C)0qgQZn|YsF`Sv{1 z2jOT-=<=HIm3ZM0DbAC>G4eU0YhE7Lf+I?M*`&*b?r|u6)%SY+@KvL%mCmdxqit4X zp1}&tsjuqMPDJc%+YlPf;5uvo@rKKAC)m=RVS|Fz%y8E7W`ihS9yktkd`rR>UKpv( z;foxc-{0Hf+k@?cSBOjwJ-@YKM%l6R)r->T-nO5pEm?(Xpn(IrMBn6prxZ%x4A8y^ zQB9EcdMq;Yv$R#h=mmKJ{-yTnAOkyFQ9v)CH|t>459f33HoW}~K|QS`)#=&N6!T|Q z4?OuQOYgj1*0FUsSvT(^ailI&I(*J9$k7I7Y0NE$ry-?U(y4L9*($D9u~Kg7>pS%H z1*D$T|3X2Y9&S8^RNfQ``jI!qSdPf>+WypLrt~}R$_dms8^IxsaQ|i(oP_+aM)f-- zW5R%R7$6mkI$r&UP7*~O*y&dD%eoe1@?!d8R**vz zzE0S2QhH(z7@X(_>X9FyKGw^j9K#%l>SkdOIIQ)pZri-Q2R!<%;RGQCF@?7X+z4Co z4)bD9p+5)v&!3#_*+gvioxIL5J!3P$P4~NmCO^fkzJcIel5DBNVkq0KD4x#S zQ4#`ihY7Z36d_y+Y{Al$5?EDc&Md6aKBQ6{t?|PR9yJ=gxvbYq{^k7)`H%;kif;U~ zf}tG?vT3SRzaRRkET4D1h`3sWf>C}6cyTss&MEDAk??Nj$)^4MA?;w3d`vHQ+IiUO z!*(H8W+|tvLfHiTjZpjwpx175u{@-P4#B6>qsEc-bV8!M4urK@iXDp~l>j|aK0Dsu zH&wJS^+#QBHTE^_T+YqQ-``j5n@s|+iMELKp7(}84qUf;@22q9pDLoRa@Z}Oc|9i2 z-Y&8tcv24TGDbE9BN1Mf=z8V-eHz7JE5FP~dugyR;E{TcahN`KWn+m1AvOD9tMp7F zcxIZMV7NU=MQ0H;6+btX(RSq$|*Xx zE&fs1jzlqIOJ^y`rM*}XHnWe3jK@al>CMUsEbvJ!ijv7lm3oFb@Q*xGS zcW4)OJ8pU^g70fLBlc$}m}0eQ*$>HZiJOWh>{`QUzSyHzpKf@~7}dW6GoRQ$Szu9u zZ;V$zTJzXmCgFuXKqR}r?-Uo#%-v4(x?*>|&L^FhNu$!3-{1bn)-mU>e;>rZD}8HA z3pGmVt4AlsjyL!!7w0KsO?P{2uh^8S0yrC zhIC;sy--KzE-l+gg*@Z=?*wCR2DF(UDej0_196k3V0uAnn+r*Q2kSfJX3&GH1ZPz& zB6MZ5sG>ohC(lgbjFXSJj&vjb%g=VugF8c>al%wJACxo!zvLjkit5SIVhu}f$j^_yitUJTh1Xd^NQ;)pQtna=xb_R z?nkghA?3^kb(*NFh2@h5k)i}1pfKfk#a3Ls8kYS5&9sls)gJ@CeZ1|&y*pr`2H&QT z;VJ^3yDjE_Vi)F)9Cw=0)fC<@80MVhRt5Z=hl-Uq*}!E$1(Q?3MRGyiLCsW>Sv7cP z>$(`#ATyyDep~3@o@o5utR8txM=aZk($LvlA~tmhrc-#fOtGZczljXk6R>*)xPcS9 zE5c~eN3!Sk_rtm##{n8Ze}m8zcyGlRW$Bei=v@APly-o6Qm0c@E^x32oHIOc zIS1JXz8C#B6>$91&oiU84mRL*rYxNqs}V^--dF)#6H10zhuz%xE0ZinO-gWtE+n<|;a1{VuTqM@qX-q|A5f=oU$7jFl%}o;+XKfn4QW zlK~D-0mgo+q^NG|)1CUNih54LTOJbFftPA&n4d$86JyVx_^7!QL-^`_sGYC$e`B8!P(Q)hm$iw47Z=fGYD4ar4DbhDJnB{9vI@BPJx z@dl%a|tFpap*Yq(9Y;1tetGN;ub8U)F_#V`MRVF+bQb^Ds&2* zA7ZUJYmM%=CuU!Pdm_31xjn!OZ^Fz~c*OQ^=~Y8_o9zx11PLo!oAIZVF{`54k2z~D zk~?+PXok76ZVpI|!;e4j;xm6eih)fD`jB&ZgP*SXMFV7-64Uaw!yOvJt!TpUH{U&q z8QQ*Z&AxTbHChw4MKE0abChuL!v0rf?-cwL5E=+?`Lr{^aQiEwi!X_Q{uZf)QkW+$ zyDnJkR=;fFn`h6VO*EUwP8VujGK(IhNR3E9VpzwVKm1ZvD{3Y7;@Sq{iWqD9e#R&> zi-*~=;_d4aM7dntA;H$~xYMdQc~JQc8zirXaQ?c9T>0kQ<&LWI!J&4Ic#p*n|3%xZCa=dy@i{iO(dn zFs|$e2W%p$TJZmbn%+?`iOCTLN3Zk1J>@9+(_`V6*(z!rR5n}$WvaOQi{4bYXKio(yF zfCUbH?2by_+Lv1%c>?=t8`eg)TcwrLs$g{a1DUj#O5B6fXL=YSTnU9>eTuuWtmu@F zi>9o?ttZ$rJ#nJ6a5OUVz-uf$;b5f2nJ^+Q+>2@y*t&>;V>G|B!)s);Jv=`J_q_R2 z2@1{e6v0iSPyP6qYz|7%D;J|Ai|y`z$nR=2p^{aysw)bD8$;C2b$f5e0vR=g0iMLX z4#)h;xtg;D6V%iA{>XlHX8;`|i18&xTvjhtbyP!pBwWRFS|z*^xVJ@w1T0Lu3w6ySDD(3deR_9m$nuy#7V&1_J9p4TD^>J*qahh3gH`=xfv>9OOxb2${O0!rP@`pD#Q_LwlkpngCj*@= zhZ_cfpSRTT2@I_oyG2^s&D#rGnE4}IV+w@<+REYtDdM*Qpji{PZr>Fdj;;jX>j5Vb zp2G1@4Aonx)H2cx33!G9KZI-zFVF*8zmelHquD2_{V?AbQZTlTUa4p2 zK{^E)^L^#`3^{Q(rG|qG4ww%i`fzadJN(Ze6|}rNELLkl-OP7jX{<%Ui34;T$Tc2@ z%{1;9upRWkY2btPnZ3<@9!vI;!$80dmd2jYf_v7?25gs}OJA3st3=N#x;WaVs~*duUQj@;j4%L#2YONGkwF$UPD-OvQ~s# zv$J58K+&y4DAakhWj;(*8CgZtjuC+BJl#3bC;ySy6s{{I2q&uTXzcjdx#bHzj9Vkc zqLved;Ht?8F}39u@cvHI;gm~`BCgs<0nBx-(MyumO_LwN?-%%4ki(YD;}Sy^-ZDvLgfTvfNylacUxCNxzBpBp65BYcn!X?KeJo=J7|%Vs zoFsM();(3rmODvjr5PKAgKm;*Ev9Tz4JvB1>EBsSn%;A!!*>7f`v{LUPp@~8tlRDJ z;9L?k-)GHhv<+sXLMkcL%#{6gSC?B@9bVuZVD_z@E$9MY3xOY|6v{37(J12NmLfdE z@+Vs_i<#7&6t`f$-Bu4_)r%k1FIzsUBoYkS?HikD$T6o(XK;=t#B+lizc)lby?mEu zmo0F4o<>+IdYz^LvcC(OtL`JjYE9CKTTiZmLb-L@6OUlg;o*R>P>@G@-9IJ`1vZWG zcow8_ry9%-(by}H_!u*^n*ns{494f=^V-{U_*9}rfPJO@&ytkxDXbsFK}5r z*c>Mso}PwQiNt8|B)q+K===>KVo3!fmI_duK2P%bUcNq=89yDe!Tg`IbPlNPDC!qJ zNnH9^S!#>g@vvr&9v{q27fn zordIl1=&t2+7LDP;>Rx_AZcMDc^D^ywurE#&NjveF@`Y1jjVXh&g>!@x`;7a-qHcB zV?%67p^ZHyWP$HY=`pHi2d%soD};4}FJ0H-?~Bl@xgSVrN;2@}r_e&Ld0$!JyU3;= zLJB;HJl1!k%F}yq*Pl?{AL{|%ZZb#*kJ|d+MSIQ_^#r_OQ2J7aCT)5jTw{e9>kN$l z*9+hQk>9oz8x-xIoPC=&bL~@#XZv-TeWXXt~xWYx)rya2Wsuu z3nfqAwNw-01$UQfYlbm%b``g$o^;qgEF>PeZK9nM5{Ru6+>UqAm^1;g!X!tai#!C= z@C&2O9g?3EvkbQ7vsAK?WhfEWZDq}^vEicDwxg5nk3l;AZA8it_u|l7Ay&V=wDgbn zd0N{&ybJNyzgVQW(eYMeV)=MiCR%psvHfI8;0WU${ChY4sgwb5>n@E`>VQ!zcQ%$7 zJRqhMvlc)OEwa!!9K$F|!B{T~L8Gf}FmwFoZ7r{xt%_m3HuwrGt`HxS+-;cR?M0w- zJ&oThY*SPJpTdL}=_-82Mv^-PxD;i{$4|rcS_lFRqZWrSO;4N#>rfc^D$9t)g?j_@ z_v!6A7?m&F731jogVM8qi(0ks{>s$T(rlVv`A3|Fh`-mL@!ja5YY_hVYpm-?>mvA3 zEl3sIz~h|WpZ$UN4BwWSLS3c`j4wZa{-KcD*7+MvQ;!NyKOe9@siuf+HOS8QX83Ii zb~~&X1bnzVrv3Is`i`w}OtVWuJVEaANP9dZ;Ut0u- zhw*J`_IK!62`fg?I}M&MJA|o}23I{LkiN-l%}FVY8fnU99PILft23sv$b$=&$1&u;4 zOR#v-*>UvT2&6%@0%nIIZo@;~{wglHg!5Y1EOy&Lqt&^e7qrh{D_G`=pCXUf0 zz#wV|SF+mybaWn;u`vHm=k?pM6xw9ji{#i?yL}`z0vuYQmK=~}RvxRxE!3{u_{^L5 zO{uGqv;#!YO`4#R-(Go2TUzo+gFQNss@34XuRE*g=y7%viH3pj^zm5hrrt4+vu_;5 z3_T&_g&-+#JFJ#X-+7cuhdubrzQlU9^$QtEBgb~cSE8uA6t%+%VN5O-93);OG~uQh z86WKnw0nsLG~}*XNQiTEhadhxM2eQboXAG7PJ7?%vu5pP&e!|V5jr~0Bzp6`9_^k9 z8}TAdu<;J;x*l<)z+(0lAf^owUly%VeX`*fO3U^ug%r?oi2+Bt?ZG{Gw*WV#1dL(g zF+zo-O6O<_dNMiC9g>@xgv0(}Fg%LfcGHnM8I@)XPr)tBs4;#XQ3rD4=Qta--VHgh z=i30wC6{V_Hscf+lHy`WcH3M!y+tK;HH*g?{@z-|V)s@zX;yxxy5ID~L`b8PP$iYP zJHaVvhbI=KxsYTjeb?qD{e9FE@Y0P;Dmu;FNfSNF8r-chAs{~StJcumy9=$y4gAF} z(VT_8w90tt;>qGMtgwH6BTl*R9VPLr-nCRgff~;tZXR%iYez~DT3(7>Zim&eZ;R(L z->d(0uX3gr-bBL7bXl8fn5U1gYmnrYXU~r#8+8$NlD1_PzPSW_{)-&XSqIA&SN;3< zBPoYl$Ck^D0q3hSI%*K=01ci^tK=Jq#I_kemE)dAG9A4xkQ$#XmQYm-t)WUgO)QW+ zdcb6LODoJf&A`_|4F=iLnLeJ>ZHqrn{rs?q!01X4S(m)#9?mVHbU1m3KYPm0`PG4T*0xxg}RI@N-k`C)(EU+sk2Yl;Rx zT#1hS17Sc&Lq4zFj<#diA12|A9`gFa+dj99@d9pWeIFHf4y=Ma0uVVGsQ&cbBSW>h z${aJ-4`qwKaD_h!(>M`n^>;WTmMK8LyhuL=P{EZPB+wNKr9_U5Ez>?;mIALfP=*50 zhD&Mnne$Pl`JoF9wwX~F%cL;YH1IKZg3!wU;kVbVC$$>qp|AE}tE3R#+2CVR`xjb| z{=+g%QG3>7C%`NY;!=U}EY1p)fwAR!g*d12Mzu_1$BT) zi>%M6BHx_pLPzceB0_VRY(U|-c51NpP&+zwS4{4GkjwfvMqQD*ulyi{7Fc3~Uc0r+hV?Hl`6xDu)-pk)RTo1R$~ zHC(f0*-QQ@N?V#NM~bAN{FXp_==Jf|OB>b5e&fWyjLy;Y^>GoG9*>@Bypnn);|mC5 zzEY)A)k2i3u}HOkq`d}5jUg+Z&h~s|==LDHJ#~B=@pXwvWMOl8J~$O}CmTD-Z23A$ zkGEi76MQT(I?ORiQW1K7H;9>itq1_%v|Hi4$;9No`fHuj#GG_WWzZdB0GfNei-oAG z;Wdb=b7@%uiU8VJ8TNQ`A4G{{1}v6`H}auapQ8M~MP@y_rF1j0V?nO`c^2(l3Eh5m zP*dvnPIbtLPFwbpbp7wb*m zDf4YPdJqPR4BdcSEvU7j6D1CxEw4}O%1;LHgt3Z-qH^a#b|IjdtGNmG-k4*NS=d&`w!VH`9c;I+dFC9Wv9yw-QA2VnD)vPhApvuruC0P|oqmJ>nWCQ){bYG* z$T4Z(^M+eNaYBqJVPRiVNrstE<5Xi7yhdpqT*{wPZ@V@%O34EUcSV+sj5i=iFv8=nGvBQW-)edpz|+8Tjyc8)7?cgy#HJ zHp^XatO_qQ*GE{Z0|P9JE}t!QXBtOX{Hp-Rv*j>k7uwQBi1WDUSuE#`bWB^Ex>C~z z|G2dQ-A_KFg+SYAfR{Mer;8K5`8spi^{dn4$9A6)I`FrHd7qv}SGoa^k39lbLT)ChA?C-d-f@@3MF9I0YP|E53!CWf>cj#_w`YBuuz=9UMs{zf&Iv9@@p| z?3NGt-JJE+ijZf^8kI?lJJ=oQomS=V?Z+Zk5#)N^BrsmhJ9dR?XzQrK*Q#k5NYArv zUof1qs(TGPA4FGQ2c(wIQ!D$st|3s@ACI`-&Iq3@-n&psBx+}w!OQ+spo{V*Kb}7p z-)*_doS)YZ-fG4a%V7l6-E#lb%E5+SQov4TmPC4>ND&z(8{?jZd|O6uZr*}x+KQje zm_fjkt-WeY1TYP4FZ~&CgsKJU+_GdGr_V)MGlUT|fvSu#MVYy=*y9k9O5zM((avc~qgF8FWi1eX?279fB z>XA^IG>G*x3BD9@7+x9&w?ck0Xf<+dneU-v2t`KGYmQ-=tnBxH{|%67MU~mL;=~^f zRkf6Q$VS7o>uKxTl9FR((}=`imHzUrS+lgmB)vEOx>(3sBn+BK2h!m!pchplPS1Z0I50pO@ne|rly z26RntHS2gs_b#HSp36>f+2dfYmo)_^9auXYca`^De-p|+*O=~uKogGn)#eM`|3CbiT>n33c3GxgP+)#88 zMUR|Ed0BxiJc%SCfQO_I#`N7Fi}X1u2k#A4JM3=w!j}VADRTu{0GEt#-1VI>fzrS= zY7@nMy}8U5B$sLlY6HTVr3Y~%R)D9fwhj-R>AMAd-seyZTJR&3&gVlgxV8trxxKju zP~iK!#gaewy|qXJf!Y7(7ze29mfd^5a|?#G^fGCruQQ=M`nBliv*k^`i>Zc)n=~~# zVejeFFh&p-bF1lZjfNQw6V3mCVssrdoK|p)!1AqvdYjYO2(B`k9sK&e3|9_lc(iWn z6&N34RJWQEGpQ_Nb4KwTICYvIoFGyISZiTH!^opEXhlRw7Eq*-xpz=ud`ly8J-iI6 z(>+k6SBa_5T)SQ&JrQ#>6ctjgjg`Uq_WnNfPA16Lh&xrA4_7})mZi{th*DG<0QW;H zQ5deL*ZTm`Ua24mrr`!d=+nE|2W4>I(fp8l4PGk31N8l3t}Z|=z7lUS`gpw0_Sc%#7QV7w_C z->2*FAM4Z!4D)+z2Tq{m2YAh-a{u~T@~<>=Dq7mK`~vCoR$@6OR!R|m7O+$6MawKB zl-47hXI^I+p7zM!2UJKn6A7X)i?6C;;GsUgkwby=O--Y3* z5PE9icL{zB^AyF$Nbe4O@7w@Ee21KUcq7_?EvS_Ma_#mRD_~;&S}6Y#$<`i1zWmVILxP*|W}w@W zv)T|pecVQC2%S!m97ZCm91XCR7+SN*Q;Xnx4qRz9rBqHGXMn^}4B%|MOW=EX>0-a# zZnIdi6^ZYNDf~SzsR~48rngoWVU6z)`qTFk#25XB-th^hv2fRZm=F>!!51A9@|ME( zF`L16^CQLLTK3vX%jm(vc=t7Z6nq&1Dn3gQ(NN-oj)MD zd;N+5tAt)z-AP0Qr^^6C?kAk;;b(P}omx!?YG*6Dzel%%i(mNWC75>R5`m%Gzvof9 zxCB$K7Ad+b8QrZatg`A3ttDw5I+z$}Qq01P1MSJJz?PAZtZFB*DuPx+E2qo!tq5P- zUBCq@5S|E~4Hrz~86Fp|&b=rX27?;@7Xaa~e3JT%d2==t>%XWv$Kc2s@XH6CjybVy zdt%$R?TKyMww=yIlVswFZEGgBjm^8Y|J~XzxBBa?Tm967bABgGuT14{kMz5=@DxB7 z7J#;6#!;pxduK^xbn|2REe@x6)+<*5lBEdkfS5Y_SD{Oa5P6@8ch@9DqDPHgwJ!9+ zeU$C_dv!FNwq2r3qnZJvCvLOq{U2|J$|&^`o{jm>IMw^I?Bulh4>qq-Hti?Lm&VKG z?Sv0qgNV_AimRt#ftZyEzO_e(u&;qFq~HanU$x0|N3jQ?Q%7925C`}mkfv=e^T2@S zLx>d?2T{izWVEJemqsiiT_j)Yb$iXdLm~|eHz{lvzr61GVeSU;} zV#=Fn`Y0IhNglM35D-3Lf>QovGtYCcPz6(b$YG3eVp_veN8Av!)RVFWYi87wUF_{a z(qmGmtoW7|j2TIxPsuE&iQlsVYf4aU3)X=WWBL?w89r+=c+;~n?GEjGMmy%MsFecC zL@8GXu7UTTOXvS=Ak^u);tco#>|h*&l&libQjIJc^%l@`XrYC_*D@j z6KydevoGsZcF*sR@WJtJ zmsifqu^~NDWj1ZREWfRZ@R7LYvbYuaUQrr>CkK5v;4my z+vOlkC5bFO6$mr=-0Q)v$OCj#J{{KF6CYo-9p0I&u5K2S(llknHNcS1e?^P_PA{Ks zI%Mjzi|B+U<8A2wd*>C3X`waP*$9I<$8xz9fD&egR@7vvRVDM!>}ZV(0*KT2zvC#c z8-Hl*FAm6i2do_uf?4sphWO$?EV0Q4~tQxG5l- z)^v?*Y%!LVLI7bZw+yVY{O6!&NCeGPr%()C8%nCB44s%53Tl#TpV@LcVsyHF&ZQw2 zCDasai-a7K$LD}2q-=M`!7CpJ@p&mhM*mlVR8eDK4Z8c`*|8A^wpT;8H?PyW{IYSo zT7UlbCqS+YF8*V1ll!qQV4&~w?#G7HGLg}3l*`lVwtvdIZXF?)3?^IfSJ33lyyWbU zO@X_Q189^?gZ{CSuM9v7{D)cp@S*2@l-SZ4N|y2gVAEps@7c(wN5Wv0`raR~~T}6JptwNDRDKm|YHCHul zG*-D%JM(B@3Ndck-Qj~{1a5pEb{vZ@tO5(pY;3G<= zg&_uN7wS@NKc|$G8Q|1QAGWLOFG|f-Yuf17UJ#L>Kl6tMhK4X6Zq(xN(I}=ucz#tt zaj;}^;ygLRbflX~7d8>RZr@Ydb>4E4A81~63BK8eD&|@Cs6Tf=dR`j72^YSlG>7Nw4synJCrdixkQrg%;FAwv5X6`CEDnW<;2xXeKZ zG`NXTk8${&?t(S5Z%hI0JUZsB8=V%7OU3^DM|{l08y%E24Jncm|5 zd9t5Yl~DuKvj2Z_j290TZyta3Tl%`{Q^)90HZ{&{W7cdEycTjF`R_8@lRq)sV+iC4 z1cpz}W+F`{OhlSo5+_6Pg54=Qo)b!7%=PIGjB=YqMMHk4qh@BJwvGX?2>HFVc#*b(1z@)RUYbmRzXp{+6{uwgRiP*_B~bbv!aKX? zC`yYnv@xMQ@)PP^low}CTm=4#ox?@veeUclMZ(Z*zqY3guPzS~#LM@)?pO^y$_l2h z3^vmYp3cEqSGr6#fDL3#RKtN)F-`iL9kFR}s`omr^#eYUN#%2W{dH!u4QF>zd_p15 zSWr`Cq#IZKUm$Tk*G&9}d}kwH0BT=5td^ZZYK+&fcLwZ@pU5$)mZ&Y#nVtM5F*Jkn%=^yQK3*0skX9|OTXKdAs9JLHdB+9|hv)1KtFavU4KN?t6upi|aA6d*h<` zzQ6jAbn+vJq}j#4Yr>C@lOhb81XYc~pBfR#$;&fi$d2&6Be3?Vj}UU@YMz^~h>{5H zY1-Hz_0FszP^1fa3DbuxTDpxM0i477r-AJZy@Hy_W~iWv2C`G&xRGFuYJ1(<`OZB> zTGiR3@K3EGN;K*Oc`FiK@yf8|6~r(!^x#fFj`TfM4}x5w4=P%1d2jOp}Ek%MR;v;P>9 z0l{AL#n1Tv;c}Ns1kwLRR8(f#--D*KyJ@5_*-|{@V5xWU;lt=bvt`B<>j#OZ(QVxwP zsj17@sQ;v7KXNHe?g7wK;`$|2IBy!u3)yw3G-A;vYEs(?_zdX#T>bIO%241e*yz`} z`nEU0O>Mz;)qp1(tkE^7nUL~t$2GCj{bK3hNOX|n)sv)@6A%JY-INb>8JkG0;!-IY zbTl}!A{0`6w~J!9DwI?^-e00t74b9!JjJMVUvX73T-Tm)9{9S&K@R!OB$6BSfW za3f;vz(!g-3~sv`1B|M+z~$eDEz-vP*fMB+YV1|Td(qUT{UDC^#{G=#cm|K(7-=Hl zihdX4*a3fWuvN65>emxI{4dykT`i#UJ$wdW4XNOavVCLLW&kBpv98*n!?(N=vCxEO zKhpJ?@(9>)*4sB>7M5zWRd)CVt6&OK>>sE%6p6!q4XwEKnYTeT5Va-p_rTmZKQLDzItO8MR*^ba`wHv3VQjMHEHdLP z9&XK)Dh8l!ChO6Y=q!}zF;J#}tJ`X+ZiP&za$%nYiw{$(ROtq+03Q9=kRt!U^J z0W$%}Wg%*7T&{Ljose6cp8Ec~+cLEBF==VPUEg9$|5ipv2&t!WOI7GG!YmqB1)A~n z9}ikIVJJjAMu%CS3SPbFvNU@!9Z-H1Wj?z8rW5cYAUaO<1%IH) zm;U(6_e=gcrh*#cQy((^Pm;VfRHiEQXazfVfsz)-7LNFZSLM?k!SN8KMuZWnWHVZi zK78Z}3Ss*W(~JyNj_-k54ijA6o?()?TsBfsj=1x8KMJKGL*L>e;_8JE&#zb&dZ^DG z7}9^H)I%jsN*x|~xOJ@`(I7zRcP9My_e%jGp}pzni3AFN7!8C- zFij&LiWvYfJZU!|caIY5LgZb^{NNT9iD~(4Y_cT?*%~!N4 zRhSyVmE>p$Zc=?V$7g0rBIi%5^M^(-lEzmZyDP0(j~@OO@!L5IIsfQp2>wS4aAPDG zp@A_(S$F_Jqyz?5lgPiqc-m_S^86J0x#0(G^wZyUP+3U2+&;_?&j^GfBq5rtM??iuVW*esp^U zz5eS7ZQJ(4Dkt>ArRsi}j+|!d6JM{d%`injMxjx15Gs$ zx1)=w)CHF_?K(#bN!dg^{xT-El5Its^lv>>8i#A-eYj)*4xAmzfN9&@6z0m6s8#oF zuOoiFRU)@H=6}#jk#vZSzWU;91{O8)6}qyYmEk6dH|D@-r~>HZc_ecdz#w_dD-c5I zgOnEPhPp2LmL^3q9n4CS7h$v(tOh0Os=8DWtde6}z3bFmpU%T?_C07xMlsP)2fDRc zrKR;pw$+U43Rmga@)zi05I5AZRvJ0I1P@OqoZQ#=UYbzaC(k`Xg;bomE8=3Xnrz4I zw8U)&n_Wv5PCfgL8a)wyxTr&a#rc(CH`;b2tv3Dn?f{o63j zWhP}?(j;>w=MgQTw8>5!qR?AfYBf!! zwcK;g+U$G_4rL1Ls2V^rp8wA}8#f4^u`R(*MX|sO%|H|WlhJU5^cNqLp(?NMWL@N7 zaAqd=kU$$?pUbfalTZ=M~-U!kko5zu1QyzsDj2uHh%@qxH_i;g2wC zg+kc`WpSE@Bk5{@nn{T*uauVBNTtX(RV}a6v)1?e9jif-CE=p)+{)pyZ{e9tih>kD zUAphY@w~rxgi$VzK+?`ldj-u-ivhyaH9twEB~<~ok~T+~ai6965$FkVt`$drwJkQ4 zhjCbHjfk5vm$uNJN7ngkzdKQuZHA^?B{Dvt=yr!gDm)#P$1OQz{WtVu@6r;SDQ(0^ zyUU1VN$tulB0}E@GP5ahnbr3sF(Xg(nnMM$jMzRK55B`SlBJ$MMqdUkLjUcwf73VF zS$9e~SjreTVQw9$*qhNZ0uhTT!-Ic9?*|L;a;=!guk5ygCF^l#f6$}pgyjO>J6GO# zd!p-+H{(|wH^vh~)v6aB952tr(sZKLQTvl~vV^TUCdS#Gb5?8@*A@p4)s1a1+pBOC z79Jf4%%Kb|901q(P z82C5)br&5XM3gksy|V5E7JUiR_7lsGQ~^dLRubn!Me0Q-Az(;v`I^f)<9^;DTbH{ozPelLje`DPNEfS~A8b_3MhP-RR0uGT2#5B@z`dhc0 z5>s|I>-?!3))V$7&|X)nyEgfXwCo=mGZ^SG?YjSIXwWiEGu#FY2YBOO6A=Wj?S-EX z+3rkW?KnIPyd0d8y#BtTm^-qw4|n-KqDLh;dJX8Ksr*8u+wjCxPXfb4Hr@=R%HU|L z!AlB0IM7X5Cf?rLzMSO)*imG>Z4k1Gyy4q^Y<49fnS!or)NHWW8g$G`M_P=~G=!E+ z`l2lms!?kH0P&DuUYBcir1$yg!vI$r^5_RheNm}J>GMOt)5vfddLizaF7Nnh+D_WN zp*OX<9}WWZ>N&M}Q${|tS34qhMwXh_l;d%JrOy5gA5s*(^&|Vq8h;ARBPksiMB7gg za$z9T%Z40z(XTx0-}e${ANy^>t=TLOz5lqc69k3aO@IVkJxH&Dk2tk*Q+>iI9!2WD zmpva8dPsQLN55rjlthKM1cCWRPz!b%A>F6TE}P5nX==+a3Px##q+z>WdN6Mu*s9);p3npo6uEa zTYD`L0+ApEKtr?)YMKqsstC|p9ToN&7lvK~ZUm!gB<&}He9V4750k2f(vr?iT#Nf) zoOreBwYlfTirOika)849i5}I0>~MD)IqC#Ec2im%nb;b1YNeS_v{)cSdDn;!|*>6^1s3wjVio7cCGMNY9p)*XXo2N5h;h<)|u+^+v<{Sn)Q74K9x{OZuTY-jD zuUG_!wPE7tx2OuG5ld{!lxg1Nf!SL>c2_mTIW;ur4?G4;9M`6V1>4wZ_57|Z{@m^Nc4FL4|H=x;@M_r5ylkc z*`bhJVSDlB^$@|q^=xGAXq-m73PeA^RMOHBYboyKVI7IuSoFjnR061XVzh4ZD$7?S z^7{lWmI7}+$sHwdo6yn3$NV$Cm8XM2s!`xdKK~`J=>By4;?wce-~Ptjw0y}u#^?&M z0`yTvmv)G)CR1RIGANiFcBxS*Y{@Rk__S*;b6wW&Z~P{I?9TE2w@2ar_fMBDBdtb; zR5TPlSfl~ae5O2utzu$AciY24D6-gG1rt_0OA#J|8$0)V0RLyt=li)m0@UuWdoVU! zX|kW#F>EX1$0Op-XPW9(Rn7U~@_q>`Rd={qCf4GdinJ_{9yQJm_*VTX_~3tdT&8w@ zu=2Xx75dU z`xy#F4wqo~5f8;B?MPKw;^-P&iE;Hm0$6ckncZ5M6YFa0MV-F)f|whtmpL21^GvR_ z$P;^V>+pLx#H6zAJA!ELXi>c-}G0*<6yRaw^Hx(c7OI^5ENHMhj%ObqCdA&O!&UPB9P7pX}1?6c6HS{ znoTm@A#S-0*u>m7P;$(44Ws%3PwT2pL(4%Q%i<-*eVVI)+NSe{?-6 zTa;T%Lw8Aw1PLFFT}JvDG50yR^*a0j*+H}rfd9MGULXY2qtMMCJM}4X-uQ@r3EM2^ zGA5;HfGv?6a_{097Bl;}bL{|Dm0)3&rTnzHnP}WcCJ42#Q!6YRk0fl{_ zfAWNR(!({aMlPibYuP*e+64cgHxa3GoFK#04X2j{X}J!tBtsHESn2y=W$V5Wk86t^ zNG48_V*_gA6Heo5>a1Y^h1ZL#EP#m3psLkdyC-q;ZdAWE9>ducCAtX}T%W<>`iSMt zfJk#_N=ZZGc~05}y^)goM#xEquFO1K3BK;3j%H0(%Q1|sg!FewWfe2}ynrw_j?uv$ z(<|!Wdj>6o9P`K9i8FND1lqOzM&Vw@Nep>?QBXTyVkyFygg{!~*MA-c`66P~Lj3NG zhT!)`5A;Q=JIoho=f5>Zn$ZDW*`+G-Vx=IKdF3emTb;fZfgtkt9E8H6LgsreheGIGCxlUquh>2v;&*0+)fL5l4fy<~<&~~7I&5^^p4Cp(P+tuC^=B<3 zeF(U6da?>uL%vTUFW+>X-Oh+$%M9b@M-VoGW>*A8UpG0kK)O(7ZqcC(g5+_`)3B8;azJNrQ@$ zC&D$%hSL0RpgaYih|h{6%b0wjw_f9Wmlwk)#&Ap3fbO&5OFjuEC%TFxUucXfuXKH4 zFQ|0xBRdP4$hT)$AjnRGZXq~WMDklKBh?!}!AO@UE-(VdMVIZZvr}7D{mSQ#6-+8s z2Igtg2^y07b3(@C{`{ zfT=v+2g>yG3hFD`LfPX`m^1$N@_1mg=gFAwx~fO`=1DunOzeF&1Vpe3-DezuDO=p#h(w1qjQV_sW&DHJm{@|> zS`rUn5OQE0@7YB6!c*LF=}BhG8&Avauz)xX*9hS8KiPC@<}|uv5*VMR^j7$JC;HrC z#L)u18B+i1Z~uy9?6m#Pg&w{opf#o*7e@edQc167NPjVM=m>4^?wq2K7uoHOHX>Ta zZw1hN-bf8oH6-^S&kri9bd5ZF;gP`^Y4!w%1jH*;|roU|f`QCP3FL>nvV zxBDB)!r8@Osg|@?P37kZYKj_#gtY;*c$>9f8r^}4#@gL&E`y#qldAM!!$&Mv7SvDs zsjVte;vxuAJZl%3izyWYXmmqJcf*f>Fi~9+iZ5hD&FGj=r4`9B085rCF-h9(VqUwP z0;qa?Yn4Km{3m!4v2(JI-c&oS&8#=nzq2)US0_Vd zhoh)xsWu#ufAV2t)bhe+dy&r0*fwY;E;;Y;3tvFWnQ+{8UTZy9l6xjPeu*F9gJK>p zvQ|%IW;-(6i7O-Sjz_;3Pr#APIgA|>Q!=y2hCNf8varM)g;Ic>Sy>@OOn}L{^X*2VW`#TTx@|!ovN&Owh`}Xy09{g6;21n z&(whvip|Psu+xjak}F_#W5@S_vym3~0ffRVTDLy8hAO?DxV#YNb%I3d_W~8Mar4^P zT#5G`0T@g=jp;lSVA|^rO75gRwYcdDeis-=fhnfV=7k^i9xF=dPsWPO@qx{m=%W?w z&9ELgbPXiis@zgr*$Iu=Q%S33LUK&YByC-j@;W6PmxkqXUt;0+5j)Ys&VslEG`4@# zSRB~2;r0z4h;(%<=2>xO^af1${GEkntRsrkc4h0DZp2less$WAexR2SlIXSq6Rk-7jsp%T7=L=g7y(B-$c%_liGm24QU>Y-vYU`Tn$rs63 zL`RP*bEUwq#Rgr6omN|Zt9fr)uGkhAE01%>5v%>gm7#W|nlPMxLUqN=J#qrsnFbxu zmVghcrLQK|A#cKeb_x2JR@m(x z@%whB`J?x-6j*NOY+8ujjf3Mt7UYmb6oQL-z73fHWn4ojU=VUqAyPd&in!ZiJ9L4K ztejzg7a(E{kV8SpCnL>MDjvK~fu;AoVD3GS{(5h7rl1!-&_aY!o9<3EGMPkRKs!QG zAd7T(w$#A(DqQDsSeB)tGp|ln1GiXeCEs!EltP-idoGtZ{>)#RrN_xXsxaFfSe-=O z8OwNVmXavnc_AuPL)Q=cZrFw!Up6hVK^8{UPeaI?4V;$S6EpmEWAy4p*5X#?`l?yO z6-GPT7*W?Wbj)oWCd-`{!jEK+qHNgAukV&Wt_ynN|Bms9JQ51eng}1hx9uLiZig{_ z^c582YX`OBh+4a)aM(SAMLl@fF{`gRpEaL^(YfDz< z!YBLIu@rF`_L@$j_p(0SS81~`-9C{UMy__J&NTesH{5bD8WyiF>Bw!GhS}AwcY*uy zcW5(W{@AS0h-y{w4`ty>l4`$wjtFjZdo=aUf4%Y|)Z&1`&w^^OrLU)z-HfGWleU5H z#UK9P7(>)hEzm843gFR;aVUd}D^^^mgcBIocX`-&jxFDPs9r_wr~KV!o_y&hR__qD zt3oPINMnXzCRa7LAi=F1a-jWL0HRP&|31h5u&0q&ds#HiVX^4q_zswt1kvt{9pCS{ zGU@H+>%zVeOscaho}mR$3~dOfOlM8wSi1 z<#DJW;f3E118i5rX+5}*1p z>^X`Fr=#c>434d_PXL^sad&PxiH{sjAQ?^6B$f|QW$DS1w9J<%7U>on=nswBI%hT( zpnH0fg4W6gl{v?M>KKks`I0FU5NQew)ME1D*=5P4;|XMF6c{gF3+vQ(3qf{tJdkv^ z2S2yROsG&Ks;ZkSd^Xfv_U`Rj@3~lWQgk}oVbL9bp1&rDOqqk&y~DFgN=MgtU8#cI z>a=ung8Li>PQscdGF`p>5PbJXGb1_UL~!KuL{anwI1$;@^hU6z2qb?wBA*cwky7Pb zI!K*}p>62gp|0G7rT=c&J+Pp7R~Y%VpezKLoTzB+xaaD7 zEx&O6`D_y(9(LEA>@45KRBZz!z3t30kDO7ym_tf^)%0efC@&gw=PTEipQ>%+mxFWT zmY|0@oRL+0JAlDD1Hv9&G=&vJVhV<9&ms2K-`%rW-+ZN=4FmpT^(dcf{26{xk(zn zB{i)UNj38dT_AL~L0xS4OelvT84$CLs2ISNDwVn(Eu*iL1f^9u+j@QEEmwZIkrPGiKh_*d;LryC4>6W$Jl)D+9#YPQbsD#{S5e-L`~mp zIVC%i0(`uphE&_A79;`5oSqYC&%zN0FR-h zt3YJ3g2^P$;SWXXs>99{_jz*JwA#|-uOh@j@)%Ii z^_en|3_XdgT5fneDjo@%w<`R0-0Gg&Y{zjCm6kYBI&PV>w?7qPKPP)``qF357vkDw z1a$<{*Fs(>>Kf|PHcUEZF(kN@7Z+AXXRum%J($)7J*ZAYHa$Il$yXP2&A%6~QB~hJ zsy>3c9543%E5Sz!+cCy?s@4^k;Om(ZTx>S)yNd+@`_o*!TW~I%Tcq!Q>zE~fZ}BU6 z`*kFW(YG}YqF}VHl&FUn2la8xT5Zj-ze`^jQ~lFf|0mN*&t}yCCSOByv;G+^JS+3U z@0XMdK?~-7KaWpZcFb!W4n;T%-L?sj2VPt%Epx1!9h;jRR=S4+Q-)Y9;_XDC-;^Hc zC^J|dhh!aRF;Xi#T2v^FP?^kF(MN1&JvtZMrNx3ohLYSp-^D{N3H7@=UYo2*$5BJC zJ>5vcu^mvA7;fcJ((?~R4+;4be=~DJ+%(aRQL&dl)zhQBZZy_w{@W9@jRXs$VPT=4WhQU)J7R<^2% z?9L>7UWrMQSj03f3@O}%gd8bTgh<=_j^6;)f1?itkNs6-ehhDsAs8?w9A{SpRvs?e zA$L2F#55#~UAaM=?n!Y~a-2Tqj?(vqO>eq9554=aq#3dwzSmMrhxOt8-=9xETHM1w&uV^PLQQsdxYY6knb@18ccBDA%_Ff^~ z$~I)1#>j;u>IJ#%7Nxdr$Sh-ReuH1U9>U{?#E!N7OEUm@dZXQf4~%_}?TF3K=QifY zMJl7fD8xhOlyAAtwvP6@(_@N?qN}leOA7#9NjzS^LupBljF8d&CHdkx)-mz4thxgy z81oRYEQER(bodBkI4EO#yTA_A5I+9tQq?67PMD5kEO5c%yve%eIC*rM&4T$#C=0sJ zUjkl}(1%&0@e0}3R*j!eJKp}|$HO%ZLGsxwjBX`oC z=IE$^C(<`bq{4muM`GV)<66FZQVq!p<5r!O%$T_xhHPL;H7RFHV8GLn&nutBRBX}5mBAfRCt`%)N7Km1oTBmZs%oas1Aw#Q(5Qlt5(DJ? z7hz)hcj)~K%7)MD?8Z8*H7Eysdt(r`7KP2T9;``J>~CibebdZcul`JjuJIE4#QW)T zQb9bZ)5n-U{EhC=m>q^%rMmG8n^A-4Z$jTmzzp;u$&f{v_X0MfhXlq}i)0%HSCGWs ztKhiLBB_=;bDOaX%MZ_7H%ji>I}ROL_P|-XK*}JYiWrzUbrsqqYI1p!?^Wu%c%d{q zq+^&(8Hl)(fos}AY7hpXrdUd7HMD$nMX)c%${dN6iA7a}<$8qquMQ#Tn}4nYUT_g6 z5t$2PpHi5dUpkbeQ?QUPj1hH#75=I2CmchQhX2y<{TbA>R)JsVNh#ANvtX1MvI6Pi zJ?FyPJP+gL2qFoqO621aIEAqqRgYByf5uu&7? ziu~L1ug&X-Z0~vJ%2%9FpaNuT9y$G1^S|H!==#f!k(d?NGhu=LP5Kwox#%r4QUAv0 zBh(1IEHm^wpP(ARp6-43WVvVS;TMbKVN0brgN<^G&O$NfXJ4?;Jl>#;FP+$8Vsv+8 zopc~hqa&hvN*x14AX>=zx|bxK888 z>6W7_c7yW3?IdhoTm>~6&-!CwcM<%*3C=kbK@Fj|>qf0d#{Zz}lC? zYy}b7ZucpZcfsRZCiG6w#RTPka9nyn&v_pDz^ycdy3kzc#)qG{xN=1-o;5kex#e_vG_w_-i2wOWGa*hqbTm4_8=aXgW*d2=j@0@qO2Fp?=RLK|6`3*<-Mh`ad8 z2&-a@olLR3e&2pZ*T@$@@=zt83sU51X3r@sV*|N)6ke7j5Z^pIl5l*7mgNQ$o^4HgoMiAo)T;Zx zHLT?c8Gpa}^*ycXQInoWJ~&Fg1!kl9TZ|e=m_uWaXY9r8=&@A&q`7^k(Rs{83)Dz$)lvrUQneS`?OlcuXX93n68Yu#R+LPPTPTO&hVaF zv=Y9#*RIv2LArbyCzZk)%to<*su!%>0Zb)uS~Vd(Tp+SIfbZO6=UB?~pfrAd$z8qM+xPo-$7!bE{C{5PlGJT%-Q<~m@XZ(}W!uE0} z4<<~Pxs4B)GaRuGZ`rC$aVXp1;3 zYj^xWu}{DkJ(S#zS#99&D>QwWqY%>AIXeyejvk5|L*ikbt9l13M*fc)!YdAgjc(6H zY4n#2T|aJpglB2UrRHWVnTIhtumVQ7`R5yC7LIcV-#zkNqe`W-nDrxg;J%SHe~3k38sQzzD}^d(;PqWof1y45*lGf3(x-0svY5&N-ECM z0m#sjVCWn3A%*Yjw*oPl`KzM}{|E|9o~=*f4u{PMtk1W3&+E@;-dNvfmNNl&XxuF~ zuB~gyp25PixB215w}lw3f+(jKPzX7@1=bI1Z$hLD$ovOPEr->RFDM1_Zl4b~zwf^& ztR($)A&oE8;DNCcdS)%b7hP9?s^X`UE{-m)Hfg`q@zN;5UJGJAo}30ed2)!Zp6HNO z@6XBTkgxN~*XYgiogdlJg}*&m@(X9KHea+w2FHC0Hss<&#B63b}nPfVziAZ3%5VcjtFm%0Y%#+TT`eIV?Ph~HJKzv0}nl#YqAz>KGX7AIsAK_o#OQEB5 zk_q2yUYJL>fA!nX7_|Z)5GqaZ%rAT|yCdsRYIUq0@)DI*2(s1)ZyT?TFJJ44^9k{l zlMtTyZePf?Qg6IG{>@rN>|Sd?@Qtwl!GVcO=WFAE|O z$g*OJX1BvZ4Oy$THH}c+`Rlt8n#e?p~(2 zjcTc7=$Y2qm_|+7%Jel#aI_tf;HOoRq+LUlS^)YJ3;E^ZsOKS5DvrpiX_cInS|oh@ z4y-IaIMZ)bIA-iwwady5;Dg2e0rMQ5=&Ne@F{%R?CDnXD_w6X9N<^1&EaQ79lrC37 zXMrX}wZ(l%ISWV~-iKb3+Z#XB*R*CAOU7;(O}}p^Jg+PP4-`_@hyWyfp@F^usRTU} zCG{kiE6(QPB3on)%IUr{SK&M03d-;?lF5&Q+WKutxkb7bh*dKs2|ruG-+h#|k`gG} zddpem%MjILXlIN>xIB-<8C!o|-nc`G!fnk6R8M+F8T$o65q&Frd)#&sWEGbhU7Rb0 zGU_|_r@>m9340stJqOmOq0Qalf8Nmb7|uaq10BFJqp$0Hpu|q{Ku|uiV4$5D4q3o+ z!j)^Y=-G*hlX`ZZc?iW^PuVodxoXoivaTu_JtzF$Bz6<$q=BGa9AaQ`F{onU1W z&4tbxm|!W!0_7cp~l1Sw@VwCY6Ni9NWMh06Vf2Y5gt z=Hy4lYc!)dH=NyZsE^QMB=a}UjZ12-*03(F!iBgDqY9Yk8aA zp6BpbIzr>q(I2t0sg9Ct7f<(P;qU1Y{@e^Va-{OU>>()nnri2ddk^dY{}Kcfj!Xr` z;t_r$U5c(AO3Z(3dVV^7;C9~~2Ef*6hFs%KB({wc#;NSV#fBlJ4W%!jB_xD|6zSYO8I*z(Jz!SUEE&iyWx1Fbqx}wq+=# z%*+~Wt6lYfgqmlN+iZ2j%}l2vt!$~ZL?$Bww-jxwlR5U z&ROf6`2qE%R@MF7xc1(Vw#!iga-(DUib$7h_YrYM|E9!53A}LB^E9qeN~C}3iU@d# z;8d-u4g6;w{qNCqt7%QTx7NEXrm{kmC}4`{UrNEb@u?tC_pZ&OLAfnvwi%_Yc+?e> z4vjEvMTae6?R*RqEXLY&vg5TuXvMaXIpzn0AIez;!N;3s=T)?n!L88l_A41o|?hM1kB?zL6l;AYcBWt8JmeWRH9 zKO@^Gc6@ziRzs4yGIWL1Yr_pd8Qys2l=95!R;}%87nNm?K)i){>_Qcqi5YUmPRw+o zqix+|OjE)vP^LyiGEA5;7B&}Q8rJ^BCd@3aC=2WGYt=LKmvercmPM=BON2k6!O?x5 zJcuNzI{gn@-~_))&qBX&MAXRFtQnjU@Puf3B1_g`;iPG$frEmc8*W!G?!?wUiRpBC zr*TS4ZBDOI_2DgG|2uggN$W@wE7r2JID}10_(=cJv z)5ozehZq!h?N9{dckq+1J70B4NbWe>B8uQj5&CV;4v3UTP!-swij#|DnF(_;3D zoqeav2tKx91f+qJC@FQkMn=*1V25o%HODGnYFP|@&!tg@{(&s^iCffIK^ zR!)D0!WZ|`#|opt$+Iu$ro z)mUt_5bc3dvMH92UOKf)c6M7tj8%PMG1}TxIT@xiH!w)^pVgC=3H}<%wz>*6a-VdS zTN@6n9C@?xyXI4Dk!y0YdYxipdZ^-h92sF%O^bUp$ctxRu#B!?X4z$s9sR6lf}O(#G&8a|tFt@ALqG!Wg2y8*cS8o_N$K zxDqYNifY)<2TLUEBvs8QP+nHRq%s{szsY<*9f@OgJh4!kui)QdmGGP%pw3NjbDwn0 zwc=lsN4ib99mtlCoA|$Iqh%wFgz`A!r-iiQe%7NAJA>~x2fg0tiTywtePKheWr{7@ zhK}KLD;)VVj01a)clYl${p#CBm4QNPnKDvlCN~;>5V)v~-ZvzP55S6+MYx?{6~I;h zUD|%C94D8vhS!n4IsoDj2DecaSaMRE_M~#A92f#(CLG;r|N6kfESJ z#=j(F*E~dtso&Cp_y9_T?N`f#eyd-PG96JBk{4S{TT?`JrjXury}G$aXMv)aMhcK- zb8){FeXv6fpUF%pCrv=dH-0 z5fpU{ajfLz6p$x`?OD&}MOsXQ`?q>t&(wgiOIfuQ0d;gXj%QLVD=~&V@rv>RGdDxm z3$6=WflSxS!L4@8gl&M($sWB0uRB=9Jti`F5sjFz?r%n6dcO3|7Zkhzr0f9C6;<+o zv>b)Vkw9=T0GB#Ms5baA7qWe)~=i|U?bh~_zT&h$`A!d1nxof;WN6T z9PJL%`7~u;pf|41!f?SqaI>&2{e)JfT3wvKTq5NSTl3)hT=au9m^2Nvz6PV;(?+`n z(F%JX2Hg3*uKYqjN)q&s{f#t5(9{wbn^?d!Vc(q$=?^PG7}C%b9WmPtm$3B@7UsN4 z>-^l%k=uZ%d*28;_Kji<6d3K^qnJ@nP%rN1XIM{+#Jq!rMR5u=p*3-sFRGy=Tf)7a zC)@G|5~$#O4m0a?osMbY7|A%{>(X)HC+$}{ABK6y1l`nVvutrn_HZteYO*2sPwnZ5 zxf)T+)Lz9OW2&x%3;*Br5^CvL{ThPtlhs+0bW1PePVSy2ATG~4p*_#|gL|Zi`Oj;Y z={~P;rM@@3%9x`CuDc28uiFtve>xR@{l2>pnKkbxu)h>wNMRXLk{B7Icwfx}dZdWbL?yvd?C5JqrG4w@XZ6een%ZYHpG zu1$T#R%2r7KXu1ckOo#{4N*>s8=jB@v~BO-_^He2vgu3DCLnL>E7Eg(w>@2d!?H2>tD0^lQTg%B?B?D^^?4Z&oQ7_Z%?j z`kLYd`0SiDc5p@+AEwF-dvkaY_{70DO0ByVK^)wF-m4J!WJ@eclH~J)kx6RIzEZH> zZcs0F=D`2h1yQl{52dL*L~FAKVO_h=UOvIO5c<~{M=XHbfA%9Oc*;`fJG>W6R+Ig@ z{WkL7I&eKp+mmH1`jaFBNn#fUIzz9hR+~jKZL9_T^AIVK6`cb<-VljAw>>{onry^+ z987EfSKYERszddZ3K+570tr%7FN$#yrJmlgs_V0AVtE-SqGFb6ZJ`7yo6*R*I~7o; zM2BO77Ec84w>Mwxcx4{yZH+Sj#YDzcsB7R_z^pusrBz^Cj4qd)~faFxAc3 z)ByFh5T5minG-GY=uVVD2F7(OsvNzS>xG=86X-wz8{y<=(l{TnNN;Ch2CPv`*wb}@ z>Trs*o2fB3gI2D&i*v!XZJ?}S;INaSk2kQ=!Zg5l3ws;ve)L_WUP7t8$hgO?r2YVtEz2E;~LoGt?|00GUT4Br%Nu3=uX|(f-8*srp!wy_$F!H&;qbo!$_#!4dDkDB- zfqFnZbtDDP5Q3smk3=Yc26Gcrdi1U^vVzTPB$#LHn!_m`CW z_$NXAr@`x1A?w!05LLs6A&K(Bv7+%AIiWf<{X0v=yJ;jMM14X20kWaf)m$;TfU3go zjqyKvH#UF#;U3V~%>r?{_2jpY&lie<;5^~pi1FIzFgZDhM}PP(YcUA_{_aWF!;VnO z^HM#+&9~{OOQMuNy%PuzWUMD>O3CQe-tSVPae4b_Cs%IUL9v~PMdv5LvU%7-2d8Ou z{JfEW&micEr8bbv__meh1DQI5Yd;6BNmW!Gp07V(I7lbg?ia6zcM!W^cV9jQ4BJC1 zDE0bYj(dP5+&Gc*smrqD5pY4jvWcALgM2l!PYEH<$4s9 zz93hU%A-K#&Ri3xFJ@5cIn1`L>-h_fdCD&lHPYA3=>XUi{#r?&A|icxm09UI$wWal zC1p0>9n2atG(G~0j0b2kmj7k}@S>AR<$WY*1SL&1Y4Qbs=<%*%l}eCIMO|0}+>$$p zp_PU)`&V<3l$^>ei}~3LklJ!VUU1FDd>;Ipi=B|5uxC>HP2e`j4#RNDdR~s0`@C0} z1x!k!ah76h0y(#>K(DWJJ7Ys@oK8Xyq^EtQu7}-kV57dUrEw=oGL<^_ZMycpe<5dy zWZcpvHjqGe!t;}d^xc2yS6T}SVSjVn^+P^-$%tUh=w9C7Z3L;(#6%YwoVfXcTXDqw z^Si}PZ{SYPClo#LDFd|oRwP2it(r%Ddxc+aOtJMMC+W}@UZ?qHjxK&2_l*C`Eh_Ks zh_y3V@?ZWRGbJZ8l%kD8GqH7Tkd88z`~2e7q^A|R69ZK4l1j(JZZ{5~hUZ#^r@LAT zE_s3+TT3%!+)9)t$y3hLhn=gLV42O!PzGnu3P(x!vG-iZWY?O0u~miXS6p9lL(e`j zMZ>i9zZLrkTejDYbs#!gbAVSW)=*YG`cT8U#gp6L8C^t{O)ko^gj5wQZGzBox<1NK zhvIv^o#+Hr(a;BFPV;$`3$vTtCOh+$5iBZl3BQHOAG5iP5-SePHPPrR+Kg>c@knFa zN0eQ{?p31&l~;5*b1E-9;tQL$D0V%KzfS3z9Y9LXf=%22l05;KHF?3Uo!rf~EBQFS zL2LP}X@~7qYP5zMPu%%=4_Nh7Mnhwp)P6qceSx-XAucgQGmViwXm(@Y1Jm+i(hj-C ze1&>cvi*K@(;)B8`nDTEBBd?Sag z$~(b}NKHD=yGYwW%*_hBh!okrLl_gQ2a1@S;hgjPQL+t3n*bQMDS$Xn*H`XtH$3<3Fpb7d=jUpSB$4sTpJ=Koy~*+o9_ov;?#+T~Q5Pa|9H2x>5~PpH$Y@plbK;geGSNu6 zx6A4OW#z`0ANskLI7W+39`34yOP%ELv-!<_MlJX)bx+jaQ0l&JdO!K=~rCBb}!DcBIeF^j&1g;U}QqD zX%uEX*J>GB+e*|Y5=?z?m`1NTuN=o>CYgpXQ)C5_@EjpC@7J29@CVYnA~i`>T_9(4 zeth7JtEcIDBQz~CJQqyE&VqZwb*acVioiY@qA9zzDD;Ga+~aD(oNh%Zu*`=%N`*LR zkWW`K4Xpu7l-$U3Aj>OchG#hrs8y6F8&;rvE*>8&sepY)BE< zRXBk60NM`(CI`Mm5-k13`|EQTD(sscR3RrMVnRpIpQbsl%@2tF+7GGfM^gE7{KlTX z<_?`H@D)|i9~y};OqV=PV~elAZ?=j3UUumE%>C{r@a&=a+zlqFZ-!-Y{XUx&rcYsd zU#}goZWYcyRxr)B76|T0Py$u|{r`}Q|IC3qLqwrg((=M)KRtnA-a-d=N{{U6gP2+B zng4GGnR90^C~dg;$x_+sS}U>`xg7d8S98!F-9RAKMD@8ynjl<`q;P*yxU}U#FHoaA zPkfv(TEh5}hyMUF z^sH1erOLn>SbFA2xD`}?*IlYhQrl+PUN`sMLid|IG!gvQ%AEBpE-3!C!&{eX0FqLQ zfh&PJ3enS>H%_hvjq`C4vT)~L@KQO<0R(+!$eQ<00$NC*?jAM}71q(4(f&v0%*;g& zdQ>JzP%T9@HiQ_Yn04*kh(YsHefw()x>RBdc_V(iQD zxv9b1iTckGNm)3f6M>u`3H$Gsm^ermp%AXbHf^4XxxEP{e*pUOjfHx|9YNNSSpjg3 zeBhopj`9jLyh6gpBuZ=`c5Un0Tqi8mWp>G5Zum#9)`mxLX%T0Kk7ohc9g$#F%K{YZ2%z-aH|#AWJbZ!P zEU|9^LGezOWJe?WR#*Q0)`8jKtco^I?utunRHtxvziHvZe}vSH&G;>fe8tV^KWK$v zIg?-v0VQZ%{k*9&uOnf050Scpj_CS7Q8QnJ*F$i#<&00@wNGFRWdc*Nqj$PgvV&tx zMOkvq+69AF{q8L=grp^4pWI1s(u~9StMWnMAPZ7pGqgo&vrd$F<%#3hD1T9qU}z-N z@NO}Gq+j87to^UgD9fG|Kw?uvq!gvYa8DZAu5vDJaHL(-6w6=9M0P=SQ37p z#$$YMK&5)TA!AOI@%TC7#JR!U6~J|xhO}rzT6BOP?4K!hyy$C;zw6=D?H z&fsBK!(e+kz<)G?_4|fA`}2d-;PWcUeiOg^R|nxwdQsoiGeOYh4{XYkH99ivP&^xJ zkh3tkYCH!ALRZ3KJf;Nqf7?X)(TlTlTv z!bYo;2efV=p6>Kwj%E6@A+%w!ny|l848Mqk8pLRQp(FI`VU%9v&q(YR3m(n=i@{u4 zdRWRuIt`NS9!*;4AEo$$!v?DOrI2-?#?h#oE7zB2#6CY0!m{@)Fwn$xJQB*#`q!VY z!r2<;HiXa;8o@&&Fz~+N1gV31BJ`{&TH*7 zPc9cAI!mI{9jvh3bFua^*DSf>ezdkS|ZZ2mq#8q*0-}KJ1LoJ z^CB#LzA#U>AM0DsH9A*GM+{@y!6|pO@$ugB{GH9f8AX9-v9#?;2_SIp*#`7`TvW+J z<0;2Qm9On;Rv}2B;`=kVm4Yf?#Gsn<3i4=ic_x(vz?_M*7?GBTgmS1GzhrCbMv|=S zpXa(DpkaeL(96qrW==1hh$WaZd(`{KSP?>hMGgZq7cc@pP>d0UM(y5Hwfr9{>18t$ zLP;Xuia4k%Ibi!t$oUmTd)oPtU|7opuf7Bu3=(4AVe~URhdZX^zBV5U-X;ff|90iy z!YkpxDI)3I+|MZ0%Icr7zUWP4z_O{Q!eKO~d~wzeA4y|qc!kG$03S-IkH}&<9!cQr zN+`_R61<#3jRg%vmelc^sof~3LN~~IubG=0gc^AfyDKm^RrXoDR4u0Si51t*<^wKk zmmQu!+{hBcR0O-{4?o8>%LK(*7w`%vxkt#yl_`p`O7$fZ(6r5-A7Ht1svEmWT$Rz`&{ckT=3_Jrr^WjZgcUR9WvcE1nQ z?Qh2SW9>yl&&ve2toJ>1dbjNh0$jesHvt=hbJ6Ql&`EPT@hk%|D}T(%7+5N$d4VmN zK|Bl-tr!|QeByFwVq!3FE09WkaNBTngGg{c`M|;bz>(A7B~rj24k*ZMrgmMXXE$bf zX|3)N01AXOJR&%f+ggFyT?Yq4dtug;H6WS1PdNeGn=(JbG!iOW+S~%E&_d-UUXT^b zVCoGJm-?PC9*n|lyoimpO`?k96x_LhTph_B_0_feoT;p4d+Pkvla(%X6pFC$KGb82t46!r* zeANITY89}cqp@xIBE9<_mNE08_KWnsJ7oL3vYF*_BPgiwmG-{*$a)`D={$o?rGfhX z!1+`MK>G16Eq3jR!hWpK8~<@D&Y#Og(0XrQhU;Yu z^7_Jvcg8#>VN3QRLulEBw2^$~rB57o1?TF&Fl9B#dB5Gi)mr2(Mb>60*opst6@{A$ zeThn^EXav|2gQM0QEP|7LwD>^z^l(#j4!VWj{(`Ia3bEuddjxn}T*5ATm!1R%1uiThVJ#2Zfl+gJ*`AUKA z%z`D*!ZARzkz(Pk1}i(^iKcs&{;j_3kt1B4(`cQFfg$_nlt!ebtMjDgk6p5g3r0jG zO%U_gZDEb`qX~){J4ES%BvXIWZS{uAq%gMfLF*AjHDknIT|A<%mH(z3p$e#c+($5J zfIc{+!z)CTnJl78g*n0H4ISG8ubzn^Vyc7uaqL8`-){u)y5W%*0o&L>?l~?SK71tE zdj>+WUl^&Uk0K8}Oi8WykjpJ!js+?jRw{p=T=b}!XU*gV&6`x#iRlZ3>z+TZ6qVRO z%^x~g+cNy%U>XOcdVZ*~v0q^69B>4|25h9BUu3_l8*;5QIU$Olxw>7TTAqlK0K+36 zTw3o>g9c7UtSrD)qoZ$?>xWPmJw!u_d&@gQX_&7#Xfq>bTv?k$Hh)MPnTmq= z4@sgqes)0J_N^`~eJOd`f=X0HOy0=Hl#B(BL8Ei7-#Kg9I>7;3ZP3x=9MvMCzLv=A zC8p^Yt~q>K@Tu%`d2@OU7%F6>R9WE|O6MezRFLu|&N8Q7u|v(4 zwTP7K>Q9;zN3ilb#a&6&{`JHW>J4vqDI!|zr+Cfv3lfU5W9H|YvOUt6rC*5ks2_d% zpYCsQUzDl7H*~Ftz(G?8WZrWo!6{RPWYClPUkrP$f7`!5zJ(_b=iY976q7W=V;*1n z%6t(=dmq7AoMezLIb?lanX3i-V9cvAeiFr;uLwoA`-QmPJDDEly17)ThM{+D>y~CVs$7*s*RMm* zTm$Zis^1~^D)BlRs(QzvlC~lA-LhsnOyGA&K#RZ#q;+e&!_7$O4TF%altKWQ!Y!RK z>wRjLP*K|>*KW_Q1r|v8C?ab_eMd;hey4DtaoG*MH6D{7EpY!7=bag0H?bPtI@>;> zy6DDnmJ)-7r3I##08`l$^c=xI-Z=q&`M3eO2rt6G=|TJlZ15T5+;l$wpy~1m2S)~2 z4i4FWm?$vBEAf@%{(`tJ++2S`QcOzw15iZ6!&!lt>(8|Be(HZpjuVV2M2YKI+d=DN zQ+A*+LYkrZH0Wm6)8<|c>U5U7p4}(k6>fv;%aN~RFrZ^0C2GMC9R)G7doP5a;CL9B zq+2O1^uU>KPoSz*hwCe8fH*BB#R-{{_mVgu21tspBYnWmfFKH!R!D_s(!zJE#Q$P9 z%ZL5KsZw2DLyRh#9-Y{sxQH>ROU{1L$*;+gh$f8z(a`jk!IPe*Xvw;+$#Tg1wI+Ck z7YZt&7cY|;y~<5dnsc%LWJeAfIQ{xj*!Vg#4x@-Ym^chSzM zmeG8zMpZo|4g%J%mQ0n|Bs!UDT|uvzy6sv;|L$%kznQz}v|+w+<=V-&XiUiXPkl3W zG*LT>T)WUjrcly>QZR7MEgz=2HX|kFoge|(X(wu`5(G+_NbF}d_(z^5s=PX!P{8+N ztnItUixFSK-GUY3$_uSxv5d*<3`yf1;o&-9cQ<;`+!v^oGx#aDW=_WAWr=8nGPa>I z8ESTtP~Jv4rOt4WKUo@HSxu9=-_Hq9t|}ca>N&UEjLynhmLNMLq{b)Ez&dai!POGuE0v)In2K(O zc!_=NaH#!-?hbab+@!IqO=zdCpkGe$!`Ea)LQzl8s3A3ZU_T}cdA%Wu@Iq#Bu^a=| znp07hvHndh95|{rTkKoG4=C^k1tU)1zp4uVu!O7nRZ|;Wl16k*6xd5l*{F3Ayrv{Y zidDHySjo_2v3zFM!J{={vfeXgOtl_);!ZCRz<62e=yI13}r(ZAoeTG#sn{fDR_Jb~RoUJl4I_LR%7_sL@&0^AWXeMTF z>Nz*)$fc;J7xL=~1MK-y*nN|!#pWdF$w?rhfr4!rsM0!A{!nd)=>`O1J=G%pgTG7e zQqqosBT%DD`8z3^XH1m0C-XKzMoaKB7S{KEiOg zg=8f0vxJEnl`m4Q?jz~ls{CU38Be^-P&m92=R5rNeCheaxq|ZG(%d7oGq}zh>Ua9D>&D@WyU^S4H5y5%YLsf02Gpwy}Cm`T}^>xkIcBrEDc^^^urm;- z_HU5JZ6nN5*;@v0vsy7NG-S))(w=Vg^N_bjfy=7$<9I4M5?y)XGV^`Ms`6C$mlU9Z zKNM`gk()d=F7cf_8$OXlzZa#*GxLUrhp-XSNtO%9!Y!Vk4V+B;BjoRv$eVu;mmBbU zBy7$TZunmb3bd-Fl2fQ4%5@ufJ>fuX>0zQt^~e74n!B*vN4cq^9I!lJSI&&H;dRL6 zQ@u2csI~xy?X^A+tW*;E?SBE%BACKXcX;gJdBnaXoAVx^T3MdtiLiq$*)JPx;rGnI z#_96!BIG#3gnZZZ>|WyP3%t02S+;*tRGas)zCrk)jX_@&)s|I$}c$qBVF8J?M!A z;mF#H;en%6`B^jh_xT|SZvm7R=Y=2#f7IbA@{`fw=K`K$6-)i*kL3fcHRUW}Fj>XP zrXwTFIyt}=e#hchBCD~z$DqY_Th=9W>gWtfE0_6krZ$DDK9Jm?wqf#5{;~^Nvtz_@ zsKGN(;pVfwqPm$8nrForOsh0Q$i)^Jtt_Yr?mBCuw=Wv1IQ(GmgVGZR{%aWJeq?CD z%ZI;mkQ&tuM@=Qd`ejI&-5i4yrAwhDC5{wQ#n~{ji#Vdex3T?Yq$Sbt+oY5`-3Ax%S}PE=mAx z8+*8%P(F3=QL33}$FKb>>yTc0kmk-oih4QN5$|Xp)1)wk{fjX!mNJR_QB+y9^Fx~C zctTx5Pl2DM^_BMranpnI-kE`+fPjUfN+LIlU}WcJt8sM zsg91Mw`mJ7T+Noxel5b~$GiExL~!t@cY1t!fPunsq*{*f0$Su|G(-50^XKA zKsJ6uuQ=J!4%K@F7Yc`jqT(S}QbJSl#hiq6TqYSxW>}G1Fm$P)_{y3}?zHz3QZ$P2 z!Qx%5G0?Fl(yAspQR#27w}-1&u|%{|ekR*U21L7}BeMDQTeLED5?od;&!28}e3}zDhLs1RNL|eBSUq^~ z5)0cWWw|-?=rw_ik1;#mMNpeDvx9?(-vOb0h&RlQJ^!5C-3PhJ)mFSBedJ(R13C7I z2=7vixpm4)QA#O36Hlnk2kC2upx9_pQbAvsJk9JkFhbP%MNn^1R#4qSQc?B5BS$N7 z$Dw?iww97sEHSfhy3|0XJWU7m$sx)|chKB`+{L>z^v9nbf|Ew(?2jOU;W1f&QP^}+MhBL;jfPKBL1jjePI1HZ;(+zpXm!j9Bxh)#QynpD27d-+d0wz;#P=U@{PQ2(J+bhA(jEAcqZq;%NnskV|9VkcazSY~5_C(m=6K8BcLGMmObY2otLSDh z*4|Z|gP!KUsCHqC2@M)X+K^HSYvwCrFe<&6>SKs*Tws2`S+tq7WS3Q|hDS9@^60ID8 zex2p}sNcVUrt@*FA1cX#a8M&Rp!-TBAyoG<{I5k5Hu z&i`fs(htZ28zGXqZ8NM>csaOfCuCO=jmio<$wLw?6O>iO6rt-|vned&iPnb_3~G>S z9wIR@l_oG=ui4W=b(o`soBQ6;iTi6IkQ_ridO!P#+t3+5DiI@#3#`tvzXVdd#zf7t zY6n}g|2-JmyQ_89!aA)}58dBWor)DtPIlRx^{eYc@_=m1270OqWNs-jfR@A~g0qyW z7y}rFl`1jTMpLTc%8UI&z@fp!YSwhv+b9X55}0+x*>+#d!Kn_r<)vuQq8 zJa%njeYmFSDX!jumypakKs+iX288Vdx4xxxskYeaHGc8fWl!04$io%xjNW zB|4k^O{}f-@OT+wdSX9`Q))K*^KoIdKdK3T5(jYKuZ2o<`VOX~##R--^o_q|V10Bq z_wPfQcwEEzG}#}uB-N5+u8R1w_TpTP3?IOxGfb%-h^9?)#*3{~oEWt>!s^jFgG+{y zn_O%{HgV0C>8TYPBRmj-Pj|c#Wz|N0&SYaV3M{7-E6`J8a~xE90w|aY#CZUJfwjo7 zK75OvI`mg-ywimH@|38Lxm<;r0;IgKD(b+KQX3{3)01{OlQ_u86Jbj$m=v8*&_MB? z2YTy|lDK}9fZ^2{!ON>)N+kc{RYe9&B^k0c&XlDTk_5qPHMO&>0WD%l3+}KQ#4*Bz zqmEXhgWVk6+C;O1{*DC<5{cht+exdQPDXC@r|Qr4CGTJr*7Tm3m&#u94zq{cpS$V0 zL$9-b*p<6s*R#Wl6NmHlew+-x-{1(|8_!OJ1Bi~`Ti^AgbJdpaU$na;xi+{CSEp%2 z#f|CQKFAg3dZA=eH^|VISQa=Zp`F}t736_?f{0ald_LP2+bnP~v0`d38x(QIBAoH` zsRfvkco)VPlS~oL^k|03wB@Rmb>RkVvc6^Wj0u06Ra>Mir1q7aN#bl$@~5Jhn_dK; zxrYypXklUM3j4@Nq{k7L%PM~^yP_wF5*2zPQk?OOsRqTY>0E4~-n{+NTLV95&4d{G z+dv9$+crz&qE7g2H(L>sj1iIE4=1kgJ44YH8`0enVBTkeUhsOYkW9w?jPD0?oi}{H z&!61)TV3_7R90?Denj4Ve;Y#snK@#0n&071&w>@a&6SR{?qxMI=pZ_U;iOwGJwSzqP$1(l(YgWi%_j0>J_MpQ|QB?#iWrPXOtR!ZQP5GyP1X!B-kWpEY0 z1EqX~J`FOj#a~A^As<6l&kygoaWKza_{Y*>)a6d!kXHMha|x|YGdAmUSE&MKMm_b4 zmN3~EPP+kge>Pw9&yxsZPhE=M_sy^oXR>YnnPoI8_43=La(Bx5I-fiHEIea(h@W^@ zOW-PMY_x6L=9cYTCR+b0AMc=GiJ5_Q_=l zgu83~l&XY3#e2_SNRzYsMiA-4rqe)n|bu8uYrGV9NOR!M)QH`AbL4yFdYE76!U^Z2B1N>y6? z7;0^cAd)8J2FN4Mn5;AT1WN&wZGYHd5O#dfg9;pM6BIx0PJe&Sz?VBRqe;}Yo>L{X zNlTrs8;}8?!L_%s(ReNov?7UI_j<5(Z59!emrNx$9)mc0IG>;X|mP*VyXP+7O~;2|_J#TqQT+fP7+?Tx~wx`VQd@ zT@RSFN#Y~X9>4N6es3}b?jy*?^u{VP2VL#x#-m}%lVk-?PSK`N%_iE-CM1ixIjwFciUF6A&1rLyP6mBK?y7F+DmrkCm?0*%}deCz(w3D$gU z^DGi{Q$P__Wu-2oBiGw18Zj>0AucPmmv{Jt(Z-{tG=5aSAAu-HqoL&ZyX`&U{f1Hh z8}nnz+!vz^5nsZ}i~wKc)BTcGq0q%0XtIo<5J^AK0@#yf5Jp9F(LkLR&x%Z0vuzaI zuL;|?7V>Ka%A^;ua29m@GE_W3#daD&#>o;%6&+-qsqQnlFPOhd`}~=PL?Wc)o3TPi zu7RK&)w5X{TkVZNorcx&x9L5Vc>@)O3?Mho0i`!XdQkHCWu}y|B>zW)C1a{q(8~u? z!yTQiG}wZ;6?S`Hw07SQnJ!6yoi&7-_sQ1t`tBFK@AHe<&lk=qOo4P^Avi-L?zY8p zizume6aS|1n#m8nsE&G3hqzxua_P71L)kkfpBvlJ#pBz|^^xK)Xb;b;Id~{EUkTX0 zW*pTPumqx$=5yESY99ohwBy*&PiWmDV8V%x0O_7SW4A$b{!r=q@Nq_;s2UYA4ZhEB zo|JD+cVHachYu(E-Bs`T5yk=#m>pQUb9>m-9`K(~x&oIxy0_c}!|xRY@T z_aKp}1Q@NuC?agu!F`dXq^JEhRh@#VY^FgipynGMqIdtrf?6p0JMowb*;mvW#ZuZ& z!i4ZM7HT7OAz5;R!VZi-R!NRR&1I58?o^CM z9VVhO-LwULPBaERr&xYj6f-GGR1#ttNlT}u%db_oxF&76DHz9Exy(A1yFV|MQ%zR5 zNtB_gtmXItj`AB-3j49CU>sklvo=X3uA(|`;XA@eJ}n7AH&suQa$>sCOVK`e5P9Q4 zgi<-U8)K%C49&2iAqY>bKW#w5J~7&^0}$qEA3}_Gj>SO~(Ydlaqrw)W=pfDIa0Y)z zb`-1Ai8N$$fLJ`0`QUWUj^%mW27mMuV;s1)8A;uFuglIFUb}E0urpyqhIcirGlmp5 ziyJt$GiDsBKOK~9h$@VRcvLvfnYp(gb!GTgKu;VyK!pO=s!zun99ST~Si7T=PN8GS z_9B=L%3}WLLmkWh6|>%0D?G<$jkATQndor0rJ~cbyW1Mpv{o&j6B9#}k?SWCu4?>& z#PNJ7qQ+=gt@p+F6@KS;$4G8{wmF)|$LZ_uSF}_^wew&%?kHGm@2|SLm-FGz=W#`Z zN~WCiz#a`#W$HCPAehYTc*Q-|5Zcr4Q*BfU&AvpVMmHOqUu1`w$@88N8Dn@fpoCSt zprWfYK^X2zJU1WqgJOh)Xo?mFSzvD=u;YoldLWRK$bm4fEqzN> z;iuhWG2l{8!zw+3$uWGw>j zoCExf8?Ls)3SS$HdxYN)cDHlJh=!J~$grdG|6;?Q|CQ8!vO&>Q|K z@T~&C`+3%Yu6pbcdp<*I4Obzr#IPw+XZ1weszC1*dIRmU@x`9DsB&LNp4V{trw*8u zXhdKkiB#&)68a1L<#JJgrK3v4g9Mw;T)VFie~-2p6Qu}v040e<$htC-wG`O16uF*H zBWe`ZOA1YFtA=8Na(tgrDoT7y*@zZ z)tHErI`JV@BRx6=)kkoz;}34kA0|saEy|?{osW!gw5Kapkts2U+TZd8$<*nL z%zArY4MiTDe z5MPrhKI1~I`o+l?Y1JHkf9xBscnx9gdtzQ^f5A={gCBIFTwiaBsV$#P;FBw35%%_U zo2~?&Ahmw@aG@qrY_VH>wzbfkmoj6_I{Jcx?kD;x@QDxZU~|%*BvL|w$#~;bOG0bM zH#5dkpmlUpkz2r5o(h|u$78yALESQ2{U>c5v!(W#0WFeRRu2E?5Eb|oOaC+gPg$c- zs5ND{7%M^CrjyR)2PDpHsh`&{P;6D~#>%FT6cOPR{~IJsFT^WUiCHE*F56!fHGNC6 zq%>ZELHPD%uHliPGv*b~q&Dw3Zs3Eh@>F#jb@{3O!R?WCU;3SPW;S1k-T`ZQ{rd?# zdC}wIZAxOk_cv{^zzcoXN0?v4!#M1X_zz!7s+g|4jdGAms!_3&E#FA9X(g$=T?2jM zIs2C-PhOrYSg-^}6l`U=1|v)W8YxTI+s{dxMkh1!Oc^DFPE)Or|)3=9uzPh&Ao*3Z&Vz(7hX7L_MG^+r@TT*t$Xt4EzFwJDuVaBw!(f< z?-Mm1mphuSkU&SPU4Ntg7X`;wFQy7)91%M+Y@_1PKmjTj2Rr2Fn5OsV(siS*kOx0P z-Yjf^;?PIIzl+ZE(wlm3;KWhzVKt5Uq>0ptJ^C#7ruQw;?yK)^zEGUKe+d_EIQ%ic zgT0O5?^o`WyHOs&4SUqlu*Df>VNrteKB$XF%$VMD$~@@o#RR7T&-s;A{r_XxYOAz# zwo~dl-)XNVz+FJF#-@a24o;m=E{fcsrQ$e9+HsjD#z|roJea7H3Clh$UyLa#KVUGh zXjME?8w#tBQ7g21&RuIQ(5q~NGc{@ zss_?)Dap-avp5tT2s6a2!q$Dy)GM&W5${;0EMw2w!Us2iuv*VZS>xcjt_qs3$5*{^ z<4h2gxCZ)iM}8<0HXI!@ftphDP^@yL;sPs4LR1U33qK&GJO<1xXf|hN`hgbs!nQlC zTeo5s({a(==E~!WkRo|p22q}B`4K24rcz1xcN-$;d=6H|ujt_=vMP}(ad6#f+_}{b zaLnV_LedWG^#K$LOofKyiZ%+}pKW5!@wCn6JkFI^WwIzsXShWX5= z&nXW@2@U@2@agJhJ#7zr#fG3$9saNp#NzG!jeD2%@0+4AuOLa4G(^52uLP-SVt&7X zq|XRAGXbrlK*4XtXCz~CeX&GH zfe9TfSGQ3vwXwjYeOg#7vbbyQU)=)Mpo&!WMmaPA$()SycEGMEaqu-mYFC6^-LZ|1 zZFF>E+fK(gv2B|-|M%X#92rB0R^Jsg!}^x%FidF??PM@*v^Y0sYU&nm z!oSB(VolY0;DRdGxBFur(OOY`S@=-&#nu3ZIjAt#Jp7VtnCPVUdl_L4d7mPn#}JGN9ee z6yuQ59Zb*FiB|AVP3tnukkN0f=%Lcj`$ocv%rm$0%Kto%XgVR4GP%`0M-Co6lroXB zlz(2LR5DMDlu}tv9taK$s8Fall5JG2pv7=0$lnz#ZN)EL+1aYqye9uU=S>^QG|#6X zWg`6{XYwXGgN`Y*HS-=)3l=-uu6>7@Hc#1{y#S4i9=1L@-Ce&tcUmzkfR^B21IThM zj|d3FjN{(i0kGQB(}^I4)ocjQ3?O-q=JL8O3mZ@kJRPe>*iRx-9=@k(lUJzQawt}X(%nIosV0d_9~`T6YZ-0^5=+( za=BrF?{_=!(J9o7M?6-2fo0a{WNyj95};ukfW#L6h6v^ren;)Kgi7BNx3iCZv&JaI zDKjaqGxEyZb@J@k{CrW#6ByGiEv`(Of!n)!uAEfn_>W1ns_7D@QKaD4o6rwM2zk68`odZ z#&X=ScFgn)+4l(pAL>$17N3e+Y(z^v*aT*eYR0~qZj(=`JeZ6!AT_W)J=z|vLrP8C zyIhle@MvIaj|P^LERK@yS)$oC!7`3VdGS9a8wCiLymnHzdb${e3%48oRlv-!Cj-+z z%{5AJlFY0|9zD$x%z?p;SaFiXWfrqbV*S`mxy29i&bO!Cr>F2^as*9S*AXx&WIgEY zk6IpXLIM9Cz5THt$+K1`lx%TT!6f{!BYQN)35b`E8K|dt+ws~R+Cj2;8UcP|W0Wd& z7F1s`n*iDNbgSbP%(P;O$wt&vM)$p;rR>~6e4Ha%N&vszFfq( zC3||sN+y~LLHUAsYGJtoxoGlHptL1Oxn86roN4695wrIX9l;t>!MGNzhf?XyW4qvA@c9ZO1{A+TWZo=z zpgzqX8$EYo75ugwF6UxwQ^5(J_TsD<5ukRt%Gyi~EYW!A)ua1uy^Vym`!}a>#Hl$> z^mVrEk>dI?3pjAP|K2NvCInxqymr5^BSBjzk;$(~<%1mI0$;?&vkzQZV)w7Jty~;VJ_gaow7}Y;}D%M4vf5+73u20tF@`R z^xboCEWrYsVN`=8!G2X(Yin)Q)%M6EbIxn&f<|f>-@GN+4Wo0w3bu@s4Kud)$JQ;>Cod#9FX4+Sa~Lvj`z-DLYOuy;l#lmmDEA zrV_QuXLFE~Nugk-t|ZwJ&K0?LVTZ1o$(8HhJZahz zi^`3~{oh2Dib`8Or&ZDTl+nyg`OfsZ&tb)8qb92#D>-6TzMSh1JRjJhn(6ji7w_=4 zF&W-mLc8BRY15;ke^+k8xK+qN)H$y5?bG7A*7a#pVx28mqE1KrqMJ_?`zzmg%&uzJ zS8-{VWct#%S%mJ+(*w__VQPg(n$ncC-ug8XTR;cz2O`Tb5eh=x&FP)omcUhwgbx(>;@?RyShVW&@wknvUD@DKRb}iU) zHf-$Gt`Ocq3cl9u&RX0B5mSd1>j{gHM{YO`{kL+R0ffbJ+|IJ=H zV66A|+uD3$_}xXL8fw{YD0L~Eq>vkM62alvAh@_+i)>Fh2}1kU(tDKSYIx3w51a(F zZAbA3=V*`z3NuVn*i8(xIP8M#R_NR}Qy?!#bfFr)KrNJF2^wWYT^m2!f#eI~(Ir%k zF~`YjJz(6)hgOOoG}pQkKYF8ib+3eUYH-yR$2i_~>PM83HPE&w161#Om{#V$7^9JZ z1r`ovFZ|NRE14*>t-~AVo9*@nnviV&gZ~pTnTB?VmW$Jhb&fVHCq%(zK}~hr zg@Jmq-z+OrUO6Bwmcr1<^#YRDr#NM3YNHiH`ARvgkgBp&rLabG2JtY)T3jX?mh z)f_vPc8~>E0OgE!@8k8=4sUU)6GO-jL;g>fHAcZqLqaK%{m6cdl6jnWu&$6(GvLfd zi<#XCbII#lsi9hAtaK7Kfa89xuT8-BNKAfrW2y}$Pml*8iN44z=H}vj`OZNVikRp5 zw+bCJb!i1#sY;}I#BF||H!JPZw|~LBtMAm>ov1V67OAa0mfMdr)Ynf?Yy*+={#jFA zK8a2=)Y)HBKE5*&h3Ya2C7L{v5q{$3KjN~rQiVye0t*(Cq2pX)F}AM^2S%{@J>GSmM);4e;%*A z%j$SdUAOlU-I~W)iMk<`VwN^ZO`^qAI=lYa#!vHpp~E&|FitDZzi(*7-uf0t!2O1V>B%GnjhF_2`3FEY4xHG21|=+9xuphO-b4Tw2|p#XTr z!+xzm3LvTZgl93}>WQ;t)<<0Y;-4{+Od7GPNvqMrC71FQwgud2G(#GPJu3 zL6u6}8L3T*467+|@x9PObbbkyN9%D@yAT;pj+abQK8#xTA6bO&|Dk+o{#Dhr5_$#g z2-@0m&A*y6Le%!FO%IWFra*+c3ydd>FGQ>2;56cf*hR8ujr+k4j`wG25qJ{j*~2!v zoJr(m4z?UY+PCN&T5Q0}ed}hBmIPqnXz?NeJGr;yEmziunbX@9339yBz;mVfIsh4H zZd;|nMzIhyoAaUFTZ3H$c-4!U^-^Q zApu)E0RkA-Wc}14-Oblg6N*4jEV^M=oWIF%js{_k4@p5KcOiO90$ODzYfUual3$%gAKTiNNuS%P<31`h9?V_CfcRF49m(b0<%xM} zr8tiul-@2AIP#ni1X|@AIHcR$d+J(i}>=W{3`LtN~#K#v0jLMAGIn z>9Lgm{Y~^7eWF0Vnmakn^cYcTWTtT>!;`&atmh8qCF~fQ&0Wi0;-Dk-*DrlGp8((h zo9b#QfJgIUK--j{)g-UZf?OP+D^b+kZ}OxTUm6sz*gt>Ywz&`xcCbHBL^~20eLhz$O#VnA8${nlV|9p!O{(Wu~pD- zggkMQlZJ-xToCKjA)fa_zn@Tl$?JPPGsCn#=;zuIGydrc3JzwCHCGg!PjxFYIz3tn zzAy6WHv;6E^eGhc51aYbz_9(sz{35KsEP!xj#d!Ku!5d zEQjW`z77`xVr3Ysn<^w#VXb-xE8#_JV?+5t)%rcN1mf-n@B*&_?{>!TO?rckLmQ!I z0#D4Z(^T!R5;+nM)_CVdB#Ub?!%RxHX=?FSO}J2K;y;4VWB5acd_S5#N4351jd?$< zDEyUku4`N4-np*P?|?sYZ(xzmDZCQpfM{6OdI{8}vvm~Px(n|9x0YYIv%c}j#=-y2 z-1)f3l+VqNL}`B~Hn)OoB?Y|Jq%vXh%kzDMHzxv2e1O#q3Ro4$NLM&|%VAUCFOcXk z{}-m!94utK?PWqVyLXiI<8kmKER1}+QtiYfsmKI;yjuvB(TjPaThyqRKcZU*U0_K= zG1`a_(=G#2$+D@QlH6^wuHrP1L-*+m$$j4tomysELXN9Fy%ttls^#-LY#6T#?Hb2FK~Pc39nxFb^R z&F}B00U4&Tv0K+BCARJ3G0nrY(18Q1yh>w|3U?b8-MIF?&{5mrsL<`QfN)#tb9yUJ zmE?{;Y&r?UEGuMDG5lpP9rDqKdI|xl<&-~C-$SP0>NKkqT2^oyp+(?3wxSlNY9YyM zc2eb|x(huNS)}1wT5D)p5dqlpf{I?|h|b$%r;#Oxl#HBR@m~7Bb~K?~>o0=U?#PmJ zB=Wfp<7uo`sO!%Tz4~S%x(5C(?vw9(=Eg`tMr40#p(lV z;QF}0%92+B4e1@>Q!YB-#=jdCOymB#x_e>20&Q5OBy5y#R5mZ%E`28mTQj$1Q&H$C zJIXo9cj(K)9f!6{e?W`4V@xr54Itt^9ZwA;7mI!7_#<5FjYsO<9!3Iz8=HGEFq;6e z8jz{y48cI;qeB4--l^_;Zc89sNNY`EYS3_Y1yvD1KHpR&w*}JN7C)eXni?>3`Pe&L zgdLYjY!J_}T!Y(V|2<-WZGSMPx~ihQnPlXco!|mXU72d!vL^z$%vAWsBkur#>(SFU zV$~4B^Bs(V(|I8O`0*&P8T|2_BH8ZvX9RfNg(*#WE!jMla&sRDJ+dQyJO+pC^DZ+S zC12xu7@8C;R}Jj1LefMyg^wVBh9?hvidhtZYDEoGYHea+?-Y z({%jA^oC(9Rey#-trER2b<)ugwu@T!KZb@TX1raRj!IFHtyGQ~Nn9GLn^M(ancLqo zdU88mvhbEYzX~TjkUW3~GcL=Gk?0>wrn$O4dJm7zG8v7vIZLgT;cZ;_*)5z7wbAr?;m_@gz0A@jI!wW||8 zTKYQ;Xawh>Rc!5!IJQ)NrP{`J8fHCG-W_Hb1Q%cjwR+fK5kRS2NF>DQ81C6e&RZrd z&c!%>8P^PY5aI_#4v78PlTdGIRY;eRpZozjP3H4jowxZ2YV6$H^_4lOX=wN)P2O!Y zQ@wFzg5BLzh$B3R)_O>-BToB+2X^es#^IX#xPHD7(B+P}Z2xnTGzyfSxj1c(0kEJy z;dls(aB<)9))r!(pMSt(j%pAPy)kl}`4HfT5ch*pIwOu+ln?(P8)*&kkC_fKV+)Ma zE>>PLd!%zZJp1OQ54J4UjPiPI5MVQ5YBMRoVYxRWyPO4+Sv9lW;Ju*I)n))FOU2>6 zry0URJnS9re^dN$I<#0CE3h1|wZER3W&T5Zzj5WDYs}^KOsrVByEXH=8XBS~PQ4g) zet$;2ml8`&fo6ldf0HC9CxRwMZ)T(}FLwi>#Jn0+B#GkO0a2zJxPNVAaS!ohX8V9O4Cl;+7j-$J3n8Su z_pn`2kiJ(BI4}Fk1eTP_y&ieP{g9ST8gkLVAN0c z*dUVKn;=YJvb=R1I2?_bZNfj3D8{BZtVn^>NXxI3lPK=zD(H(*@s33vbvP|2*jf z#V5pwU-X6UTC}iB2Uv(8D~-M+2}MRD`4dj&zWO@pRq>{Q;3alnL##CL`blae8E{Sa zRY`V7vk~jdQ&-Wgm}(aGH=ZvtQ&5cVi~t$By>TS;)WCYxu+0W_d|k@r_0mi2*^#bH zRI69|WlNE|fBhO2>!Af+NYr1QTiVbR|0+-*C0ht%Q{3wmIyzWt)y8)p-NHA@>JMaT zY`y35lkC|_B6W?t6Rx_!@wyz*pB{Oo4oz$wnOVmG2dq5*io4|ZZ3M>cC4|8|>mR~I zPx1~eK*ji%Ws2ajcybfz`|j)s6RhQt5@dL%^`)H?zM@8ed87Y$6KmbSV#2`OZyiSJ z^?SWSaFgLz|1}c$l;{m;*?ZNjCCuTx<0^1svIMoNk&Hly_YgfRl6PH1=GrlRIuDnS z_lILvUVI8Uv89=k3rJ^esJEgHw$CKBg(mM8osERlKtwKwBV5&0{^}C|>MyzNvBkP} z!fRs_r3O_oD`#?He|hb6k0fuyHXaxKpKV`8sYPa0#s()y^<-}vz{`zjM0Ttgb?Gai zhNQudtL{{durK#@@$6~Y;#91otCYb8OMtDm#n3w?>vTFOX)V{bE#ya*>peU2y6PZU z--9~ylk@Jtk8`!nBlDi6Pvv4vDN0H-Pa%NhkRT-ZA+_{m2!^oCK+w_ZvJ@foyN0ax z+WC7O@;b{p5#7j-7Rh9XY^mN8 z;14J2f*(v<^2%w8EPD+GgCNQT5ly2zB#y+4l~pGV=QFn)y~!}3<(aV6d!$6k(ZZif zns-qRanPK8Z~BKO?SF}SI?0nW%= z6p@&L^(Z4x9zLx3)|jXYB8$^5#0Vb9um{=O@$TFkyOEx1FW#rFp0qAd8QkaF-KDHI zu$zV#Q)L3pDN*Pl8I8-4NML#o5&X-4yASSA=NBKSO2J|TIUYo97jN$M4c5I|2k+Q2 zX%^q=ZHMOP`MB_T0)kgnvQ!AW6`TR`6CFXu{2_nhHt!{ce-lapzlzHp!0uM8J>+SY zZO^Qppo#^1%gd?SK#17zEG66@KB7F`xZbXYRt{6q7f?BPTtnA~JXd=@vizAK>^U4G zZDwPF-2zi9{6b}(`VF8^>>GZJG`GML)H~2g)#9Gqa&ECCicE7)q=ha?eBNk{8$G_W zgiqh^o7twW1-Xlo2ZjZ`C{!A={CwknDT$Z9YwayfU{1pFp=VgS4)TZvxTto4GN*Hu1s zr}(Q%-^<2u>vPK@%89($3;2NFlTmKu{K0_gaQ(5DOml&^d6=et>4N>PG9F zcM0jq5b5Yoay8eo%8tpSp7C7`RQY2s{&zkH;ijb~EYn9fJH} zj#}@1?e1F|-li4mDhCjxWRHO(kTHj#gxW?mdcrOl^#)D_u?pQEHXqTQa^Gb}hgDd^ z)Qsrr={1mz@4l5eAG*%Oj#>>~T7_byh`w?!IEk#x z^K9ey%g^qUyyoR#yAW-x4Z6ANQ#eLMR)b{v5{7PPCo;?7{OECc{kaOq)@EODl5cLf zSl$R+E6aR(&+|uHa!matjW^mhQ~M%rS5?@@=Er~j}qXI z{Md1J-y3f6LMk6cynVwt*F+p~+Bv`ju@tQJ!ls{pdIua{ zFE>8)7Vq%8!q$HA24oR?!FArlA-_(4bYGu*-?Bgux^^eQlxe(fFkO2t9p^-}e0CsV zQ$5E+bWqiCKcv>Tb4N}4r^;VaCUdfT%)@t~YBbia5w>XKH~OjqO$97Vqc;Zjgy=ov z7|RW`bUoA3j9{WotJaH) zfxM3365t&y&|~rv0Bi7bte=AN`Gt}=l$sr)u-j4|ZBH{z`M&J8VZz8D_li{iK|Ya4 z^uN1tUW`EKI`xfEo#Ts}XNAgSMUcuOg5Tf~{^)tlv4AF1&-d$VP56Eo($!`d#yaNe za;*4z%jF2-NPG9GBIzoScvj+N+5{JA`0bl!(oLUEr7ZjLB3#$p+?9VL3{g` zciddUa8m8?eC=rlf{!ig(hIZRSYHWl3P=avKu2^QA^wJMM|^uNo%5&Y7`1_s8*E5= zv0p}@%?C|*n}lneR3;X z%8*>lH*BJcgM4c-WZ5|bpcb|23x7TTA*}v9zz24k5=37`Tg}f}42c819!HwN6^pyy zJJF4v_J;42^Z@KlrS`IgG46E%$wIkCK*q|w5lx++OwEphXE*-5UEeC~UcncgFf*!8YI8t;Va;p& z*92j()|GxuyvP!DZH$F-F0pMxc!%YP411Pd_x2|t!GV%r;f|B$^^Fy=m`htGx&GOy z2kDfjuCkY+cYz+#6zN>yiw9Nc!pA04tX7!O29wV>J}r*khtRITK;JiZS^g(BUPb^^ z7m8sG+@UcN$+e5E=_=cX#hAx3)|GiYRGCt6+=vkJ^XCq|GIY-uFMhsB=w~+qK`*s? zB3p%5{Ys>sKfL95-`#w5@ZRx}l~YL<_c9$1bqHcxCA2yG*p-OQ$sTy+>_kzH)A${e zUSpVJ-_Yq(br(G51G4~+)EjXxRCPyIjrU?xZ_*)IFHT&phF{4`yl}JHg*BfYdDlBW z1yG9~y|WZC;;lS*>c-kJ?5K=sSUB{^LeWSzz!_{EOPR>@{%PCz(~}S2XPf-<#WbC1 zp-f=D(f^+%Prb|O<*B|{i7hU{+>C*2T|kVVQy6(vKO zc{!atzO>TQzia0nDlEzo)wE8X^2GIp(TgeyG5GTHT_yM64U@H{peZ0@Bvz>g@1|2BSuCY^l5*aifHb z5rsE$E3~!MO6blF6RD1-uoE-F+LU5hn%yDdG6!^BTvT@!!-GhoF|WX#&LbH0-o^LJ z?C1eYHg_m2@jC%sA4=D?tM&JqvK!r77|u;_%fV-J*WI7u_^f-rvCYBbiX^@er(IKj z?^%8FXPqXU)67ToIczKg(~id37IvR6o^wKBI^@1~tMWI>d> zGqAm4D+Lp9Jgg5{F1Hlc$(G0K(dBBVyt`=~1omsSex0UukW8Re=lXbJB6qUDbM-w} zJ|s9D`1|qh#8qPg8U69J@imR0K9*P*7^(nTJ_gQeQql*NH5u?#DsoRcPpVH|sFqA( zkgc_)LdGkU9bY0p{JqKZWPW)qqmGglbOv$kcxMe~W!QAK<1X8agtJ}mo3!adW(i!8 zq;uZx%y4!h=Be!0IQ#`Ba_&5=HnCI9Cw^$vb|@H_Muc_R5kIdt5hpNx#`V;}=7o4E z9KKL2QCz;(Yj)T_?ax0v9b{#qESWtz9547e||zF_%&R;=idwE&FB6WkO0=~< z0R!ej8ZeHcV8#=Cx^l4exoJ@5^N{|JNhhPuF60E`gx5?N|Fa4_`REAEyPQ9^UvStC z1N>#0p_G{o5L{5P;>v-GBk#8xjq%P&6vmDUwaRx=TgQPHHcfvWqGo=!)H135yErL) zxS!ldC=~8mfQm{g(4B_ld}@mzqEfa*eP(~a~RO~VY*^j8bl zcXB3H+7qM46h}p1>o|h=_B7fU!aYU29&+^=Hh)X$bs7EZ+C?|#6;P56(S^QC@e!dY zY&VJw#dnq}o$0slnAi0tMB%6`x%++VA=J&M>=4?mfjS-1`&6TR%3A~iJNXwGL0CRt zJxZ`8!VPG)9R~|RtcoYxaeTqNFC`WZVK(4se$&=Q=(upffh28kV$vG{|6(bMkJytS zFIqM8HN#i%{uFL?3$+Yb*m^-*c0NXjU1sdAQ>Do5;{j9npaiP7MNDKgp4=9n2EMz4GV;5m$PR#{@3(tBkqxLhi@Y-PEj7G_c?4Sg`45BSO$&{Is_9wwC6Y zqgSbxortSW^&efiH8bovy01O^!@$YqJM+&wK~M_kJR9&43!BTLhD%V)fA0P1Y~~Pu zZ)$Y)7|lPTtUk+Y;Xf|6av#UGv;N-S&$SE9;zv}%Rd)*I+)j;A8731&Pw9jG9urF? zdO0V2pEYvWn(I=&aOciCwp6c|UKTO1E&cSicPzbCd;QXMveKgDqo>wUfu5D(JGgUq z`Ib;Q+t9Xo?I|QAcuh_M(+riPi|P2gg;sU<*G-##g#!+j>Z_UtpXGk@H-S-qb$8@$ zGO|QC*p!ulH%02@8!WX1o#}ZxZ*}~)Yg_+D38RE_{1X z?8pJDs+cB3Jb^t;w6k-fRjdva0BbQzJpX8^#kC0K-A(ePd_C$&%PTERz)Bi3Z_6zL zU6qNV`=}?5jb0V7hP^!!I8imAD>%0n&3A^fqy74uUJb)-^L^5g--pO7+7~vz)IjEj zvEFU@>bMuN9E$Q6xVjCxZH2f$?a@ko_*czYx26LAq1RL=h{<-&OU&PfaVhfb?7@(q zCw%Et462PR$IjIc4$I?;d(lT~F|LzEit;&*lE%ShnI2Fpn8xl5zTH6|jbIVWF z;E!=;L6%ZkkK2Af+a_G=!&}dZhf2VnWkUkuE%2kb_?!c(-}){>WoE0}afYmXUw+HJ z?I_D0(up3YNH>y=RrA#;Ht}1n_RXK**?3juJ=|d`P2EWy^e|hYil!w^IV!{XBSA{W zME6M-kPdIRiB#$g0Jlw3>lPyZ%-`_ruVmM$shMy5Jl<0JM7rrQI^T&t@v0iX2}ky|?zvC3`L9AX1Bbel z-h;{;nkpjQ!XfuKM%2%jGkS=T1t*i-Exnfe1|sz~56`xyEz?WwR!z@&s}0WCRP`8_ zat2@5!Jvk7rvZ-`8M6r=BmBzOCl@Qo`SNt0o4vh*9n%(HG^rBp3a`PPDAqTZv2Y}d}k2QDgdT`@T0sb@3Cfm@w))y z{7V~n{D;~4w+$BGOi!FBH8S-^&NHDV*Dn$nRr=hV$a;L{<%TL#XJ-Z*+keAF7FX*5 zEtcrT7*#A!-y^T_?>$ZM%}*5{mqcBlMw7T&UjrA>TJR-`bAq?xuiiu70e@uM10oNy z{Z|OL9kOVdjCfglE#+DV!@}0q9Z}>Ni28+n@Q4N;2H(p2yu{9KtPEDC8;R?VWKw0b zMY=H>KXG~EkNWC-d>}!F=cl7Ddp)OH)&nYG6p%+_tL1H(_~b3K!dIffJu%i9)N?4` zh{wfwgJ9W!pfb?s@>P_(DI{bH^Dw{wRfx>U;EDI!ZcWRZ?R_vmkEfqN*}qE8Tku^k z&vUfKFP!h!{@~(}3F%hNnm-F4H#y|*A5E?dEDk_}$F>;U^LBp&9BHBIIezL{b!o&3 z@G_nb8&wp`m7-3n`br_kG)_~cb_;8(MLLcSo8pd0iFUSV@TrskkhrNl*iTbrvfF%;J#-QE7CcswmP3nIt4Xe+EijFhjLr@zQ{Y zKNP*|^UrHG*>6-CFV0K%dj}#+Ds*^lYJwau-6?cKD&{#Ugl^=pmr5-Ca_UB2z~~oWqjzDcLZi}p-S6~tyAEi z7nUrCJnxKt_GgV~_S}xQfKP~PcSNWK$D~r+&Y0|}t~s_!IRhR!Rkxk7A-X6(%Y$1< z_DYhPs&_p-(A-N+Q6|e!fq~*Bc&S|lQn54ZdBePBC1E9s!|i|cf57SWhEf}*7t<^r zP}3{W^+d0mmBUl>5vE_zkekyW5m@-DdT=Ut&(g{dEG)Q{0mgm-!vjLYAkX`lFUc6? z>d8@aOd_{p&rL*R7GkaE4-7|4@#!FO zSGoWe0dYu3^VO-r#5V68wZ#Xu@DCEy&8x1ZM~} zyB^~v;c5*($wV5pIFG3zdvB3(7@T-w20PRqwM2{l7?;=PSkKO)5MzW+<9M3TpHefJ zu?UM$N>J3;isSLIAZ31UP3Ul_W_0ouUFe$xCK7XLFb5+hbUqluAG80qr9M2bQq~^G zqCd?aSEWRWRZK0ImLUY5{gX7?R==N5jzvbD`PbfReh-%mig6GNK>#J0_|snh6#3EIEk<{wdbo3>5)Z) z`jVoV2U=d-UsG10QCvGiWOSwq%NdoSW$3%N5(59(!(RRcQrUrvo$G$e`QmZI=z0pJ zgmyvvQ=Tb(yMCk(vB$p;B;iMbMTPOs&N^H_Lm7}!8k0YToI{jEplxqumffc5!z2#= zNx*=1c1OD4v4eC|6`Nf@(Swk)ylxN^?`zI=1qF3j+1RdlLK&7TBp(ivyTK3jWYJ}X z4y762q(bbDgsjwPS-~HvOBaS9X6wNp)~-$Zyllh5J=s<6xEM}-IN3)gL3HDEBPy9_ zg?I8Oq9X9hJutoee_)@}W|At&gMBE3uo(k5^eV_^M9U=PO+l)E9??d2T37vBDs{CV zA7vi-y$~7fhHBarGC9I?z&2mjC4 z+!?0Wizz;5VYm1LQ8~v|2RWRAf_g*}ACic%#PcRgs(~oPU%Fc?#-sxR88!H$Ia;E_ zQ-;`ZpfoPK<_gS3cItl;7&$jzdY0tWPllEQD`C{0u3tY;eHRB+@>+7yjI z5<^oLC7_MKkdU`#ueWbSZ-LBd|A?4T{`@mg(aIKb+WWei+1f7&jO%ds(d?Jc_7m`HAhf+dKFr&U{*e5!EYq5>^mU z9{h(1hm;~Q4WR*_~m{Z>V3-amYD}PmH zcLHJ6fjfoBO^NRdoG$log0mdoV9zr`YKNp^PC^8sB3@i!;0XD`@7>rV&vHU2!A;Uo zas{OytD$;=;7CsvheC{pNmoH;nN31fd#R|B3H=H>zpt-|Ht8qr9d(zYUp_A>F?rES IVf}#r0tS?Cu>b%7 literal 0 HcmV?d00001 diff --git a/docs/assets/banner.psd b/docs/assets/banner.psd new file mode 100644 index 0000000000000000000000000000000000000000..37f6af8e04f6e74a46d97eb0fe6dc55fc2380716 GIT binary patch literal 2906025 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±S4wR(Ythpc-8?570KV+(Ck71M8aV(#~y00 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 z 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%0AT6T6oV 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

8c5llXEzbbEGTn zKw^o)qM~$hm)L1!0M8Cd7gBmxCux!d*y(rQIzyxdq?;JxymRlnd9(v3y7{JD;mnT5 zPQJTy)B@g<9gSvQ;R()*xObn#1c5zv))h-bzED`;;>%W+`TTGkd*`lN67;~Ec`_4Z zH}2|-NiRksv3RU_6ar0PoIO1Zgzd)S>SE+fb_?^avJLm2V-FM`40aENUEHOcS0|i8 z7^i&G+D4`D9ZcVRSokuNJOCW-|F`uI=PRJxAYU^Eh4u^q;&kVc|sFnrmAE24IxFo|O= zWJ3&v1NP$UHlG^^9UhIsfFGmbb5EY(;b=4(vAj>7=<<`h?nDQp2Uc^RtMsB3lU#mC z$38)4$^T>TJ-h6@s%&AYN|GfR2i#3Va}Avc4cJnt&XaS_C+Ae>RL-SfTh2IvZ5n9k zhHg4QH}vh%AMSWR-4FNc`&)1T+t}cMZH1~+?_AF*$t7VKTUHfacf4cRrK%I2^PIi* zUVH7e=A7%E2kIgM2kANi6|cg?1LcsW+5x`WV2@gYef%E-Rv~gQD2AwIz!sYZ_UOvL zt!A#U#LLoQfos(mVpG5nqSW`9k8Fq`LQ7L6p3p2jig@bc*Qbyy)~*|&1+FQQYX6;S zr5~^s)D7b(^S61Hs_M1}AofxCT0%j6ZTjis7=B^smaq_Bl5XO;ZkfU8pF=Ilno@bH z<9+yLFiQB&b@@*zSF1Df%p>!*(SBsr9UrFCuM2qp#ewV^D0}@8))xLVOHgV49G-1L7>X$M;q*q%Q4xjV@$F9Co#rU2&OSc zrA1^i>;My+4qoF!|BZ5s)Z+sniJ$6LcJro$}q_0xG) zy7o995^bT>bgNBUzCQ~&Q7>ANTX*T4Lvdi>fWomS|1gx-k$4rGc=7F*~?oz)nw>*E3L<#GNz z?St^qs6oL;j|boWkMEgx@d|JrnzpqaZgGrRAuqFal=xe_K7d4@msMYu}vt-t3rU8X5_^(XpBG zAfFMGB=>_KDyaM$!mK7T^e&&48>h|RDA2qow zKpf+e8!GQ=pEq=oJNfTVnY-hAX~Q4%yOd*7-t7EM)U=2hwT;nvC@4;tbLd&&Sf z6XA^6(*(kG?2^k*tsr_UIaycr=|x9&ozR74_5@Uan-v~&^^35AenLC*lW*mY>BhQ# z)KrfZzWc9pB4eT&{V7$HyWej$Lf+y9j+Gg;+4nOD()Y87Yf>D|Kso{hd6Q$3o&X7z z12U6ua=U5^1Z2vsrIQ8O)XeEc+X~^F_LMCMHzR+)o>76DQ8@eQ|2)ZyAg~uuEx=+3ERR3)u>x#hAlT(ltzz=LMxjA zm}A$L1wk~B3N4>31A1dlF2x@9i9KQqc=NRADfWKys57nttMp00H2UBFQIF@0jI#QZ zZ^g&-3&s~rX*~O_e<};CQktHO6^63Dj98ltSx$y5%k;OOjK)c4jSRAmQnfS@kF%{3 zc8epN+B3ObHAkw+A{S59bO6tLr;5me03fg@{1lakfV$M!gIo z{A%Y1|1iOGfcSmU%qS22+anIAYZB)N?TMl?4iXE`x)UumgL3|N{^_3|lbJ1ZT$GNm z`jnlK`XPgT<1iDp1#vf52h2fy;o|9rZkgKjJ-)o%90W~vw^2}_RDEqa3*m`JL}eQ^ z*%~rjE<=-l=Tg^TvlvdwW_e#^GSJsV4k0$nK)M+qU`-mY|L`9gjI^EtlNDZm;9vgn zUzS;cHjl4BZHMHE_wpi(RI) zyoIlH2TnJZYN&-%Ez&HVUbaOX?=Nv$APw)u5MOtlp+bBVL74rZOTz4KD*TS0_%rf{ za`Pd{&5uHE-hIviIpR5I6w2%*L~rFT%gxi(w)Ez=U+vea;{4X--czrK{JT4poF87# zhvGcR#N&myOccKBY`CBGd_Ra(nXE?N zg*5C(pl^@w7n6v69MbKiBKE&=Mlg^UoKZ6yTd9=&);-dYKog%v%5jN)G8D6?fpkb0 zKUK3&CHhlUeNwZ33wnrmcurv{@e{vsb}EXp$#li`2JYKKaeIA4LjweTR0}Na1$|WY z(Evd|pxJ?@zo3s8XqZ6HIrN<7dMX}6TY;bJBOs4Gua9^xJ%V-#FXO>}<8!^x=f$qcA&guIA92;1FV!IX}JodA% z8-j=VlXF~jIN%KLB4{I@WaDRkdao@wj%`_R%vNL!^iBCrw>{O+k@%3c%50GVZA-HH zZAAh10ylnMKcY$XjwDn&vT1d#R1nzS`8ZcxT?g zPaFk{b5!*le0yreK)<`%i~0dQZN-4^6dLJ>rDLFZzWR!O@#?E$)ZRi=a))WS3(Jx1 z+ody8PLx=V1r*!cG+3IMvMW-*<9=91-jy!wDt5*1TSZh0WJ)!4$g`DuptvD z;1*3+$CK~=c$(uCFVx=A4@0IzJpI#e=o!-G*aU|TRAFgd{JfCS8odI~3S!2XXiC`Z zIlk5bLYCKs48*L&!#r|(4BIGX&WQ)d3l-J8qcU`ZGhXCPu^c1)OMCjY*#4JNd zo!E9>9{EV(C|}F zx+6u{((L9&wraAS59<(^us1E zZ0QZHZ%MAaC4EL6LC8MoKaSf0&JhpfO`6BTwm+gGqH92WRaZcItbb~lNZ?f@b8ffjfj{fI^^c_`I> zqxNgrS)8#=TQ8rk+7W%9J>!zzh6xZtpha{8|ML-NY^XX!?Gwlk{YLsUBbEAD zj?LH;6^^x(MuR(1n2!an6A|%HPui zR(?i*vFF$&b8W0XM7NG zWl6GCh8iC!TVB!<{gpI^qjS5Zk2CIUiNS=QP)^jaMUVA=_?;gl<04b8kBbw?#}4Zh zG8=dHbLi0bfnzTUxrLetQsj;DJ)6qyPEIy;XMV}mEVHs2?V&j6vRtlwQ9ZvUmiw}_ z$={Wq3NjgQs>X9{zOQ5&HEz7{ogX|qDG4IiD2!V@ov6N;@RG>Z_LrCs8g=k*xqUY@ z=#jjYJm}ii?4pkZUhENdagS6cAmbna@AEb`R&p@ElMPRpI#R zVib2JUQ{~XSV(?89cm2zNGIS(y8l|-Gl`z+R8A=ls4WiWf(4#DYiL*vwG_Ba&1^%qaAhB2H%+k{C8uN)1qh7 zwhU`(r5x<3$OTd*mxcLhGQUW>r8i$>;5mFI6HRK&L>{?Lk*U^Mi3z(XF=ttt${R@N zgKhVxvh)%6n`or{HOf@CztAWxRevK5q2$+_*ofXL?y2{cl6E zl98A~gHb1JW;nniSI;xMIKYNdnhA8r)F-FuM6stlGI*#+-C}^Bm%bpHO0j1jS36a9 z-0SK5WW=B>EOla55SsbpZV%mrF@X=_v96oy$?wVxRux0{=axO)Hp=(5k=5S21MFy- zU@CipYc$1ix338R21yd9O!!F1_xxj7l(;d#n@GVsZCM}@k)0o5gmG>GQX|&%iVqpE z;&Qx)!Z->lu9(7(E-`AiCY-2D$j7}YRh;xt6lATw!Er{<9IrMtj4(Pbv3VTVNvwb8 zNB9m!c2~;)=$TWiA;LD_-P3cJ=qEtwD`SX{$AU>!o3vP2Vvq^p*s#NkQ%NQrVS%e> z+1(mpRW6*YYBq*=EwH0KbppR?4u3I4YvObfPP)f}N$Uh=u{oiExtWQ&NO%~L zxFA9aUhcR&>3Hn?B)%2ZIXQo_VW9Xvv6^=WXnwI*9q|_M@6Q>lUmSD#-Z5`dbtV)f zm7os+%x0s&7h6bmV2BUOoY#?4wT_)1;}m%&<$$X(O}%@jvZs(|S54zBEZ?88YO67> z_rl{rUx_-RD2aTv%As#hQ7V=(siBy~=Dz>z$ z_xJ#xm+ll9yB9I7%2+rdS1PQ8u75p$TxnLvk&oDilGOnYL!Y)E*!dZZcvzoW@HJbD z*Ct7+ZO@*WpT~p*p!!|uvz*eYu$9KR*HLQ)MwD2!Z!3DGIF_{b^C(B5cU6M?GIbT$ z`2j{Gp=gsUF>oc}%4C3Mc6&UMzyQmLh#P#Nm2q1}Gr_T$vAXEx)Ao*6MxZ^g0l3uo zI8!M?@nJWHm_%!C)w`<&)z*TAC2(%`_%`=8p%L<3CEMo0w$Tg_II!N7b2s18nOj>4 zrR0U|By_o&A-LMRF~n)Crm59a6%858`P24Z!biPdtoB>!(=rZmR?rr_rrWeJrcAz* zZ8zJ}ZF0u}eA9XCdympd%+Pv_BFe2L0^LWnI=s8}uI6TJ7&d-GrJAFC&Uf`io;2`;zg^l#NtFJXm z*LqEON7z5SmZhcd&@AqG0gW=mH-$HFH8uSJ!=wjAhdz|Eb^e_28h+6%e)!V#R-pMO zd}>^8d2UPe>V8vW1WxEY`RzxlrQ1)KZHZx`Z+_$1+E~VI3fy_zn_~0N2_uf2eu8DB zUqQ3>rGLs2U3&N&2TbdW!U2KP&|@RLwe&77-`Oj|Mf#@0t8IOIoqJ0dh<8Y$*9YiQ zDXdjh-S)d7FAc=E={xh%%jSM3`nkD3a-KIwjlefvFb^0`XqYdUBUWh9gQ159M-4B) zKO?3S{@ff19pia()89vr7?Jamxo+;a-@A-Yml>tYyk@>j*Rj)!U%t-s=7=3xZ<=r5 zN-nN6>Lm_c%8Jq#;sei_uMI!)dAjg(bQg~CmiZ@$=bg!7GHDl@g$Y|nzWW=`eyd!$ zy~>v+bj>~ctp_JvRjIYqbNF7k)BTbCoH-JB_>lc>K=(VUhd%uk4!^Kxyl5VPRx5Dc z^!dXt?54MmZ}EzG;nH;+x{i-~7+9P3?f&XQ;Dv7U?1UR9zVF%t>uvKLbJKd+9`$0| zdEOq0J?8}*-#vKVK4AHgW#cb!7M`<5BHwz!9<_oH|A0slJ!hkDf^XqHVURwP4RD?H zOIHG;08ioN&*M$F&};U)Hd<8RO8X;!>oL5*jh#2`H|bIyE;Sky(oezba2ul*KJ%RY zstrm4-sZ+XPw(Ol`;Q&d=(Mu^DBG>{Y(0qYdG_nm&L6d_QWNJ>FKc)`-!R&B&2}!@ z`$0yqiQj-X11xXv52Af^zh;7Q!(;S?NAZQN7wygAC(%vO9Y%CZBlyCv*cYz4%v<)r zxx@9`aBVFcCPDq|WSk>D#=v>oe%s#X5^`SI&e-{&UN%63Unc*!TLAGZk@HvZh)gTR zkf*I|-o4bK27PhTjs$2-K$MxSUN&1-L+ye361d7`_Rnje0U={Pd?_9k(DmkZ@sA{) zD>S^i?bi!67NE|!*(~3oH!Y?WX2$ioUb)Qka?56@rOa0Inj!zj9^UV;c@20^O4@#a zJ`Sv>--W?%_1L)#gTL}xLm2!WGGr|6`FTgT)ZAK+sE6BO@CQWIl?c@>x>^eEw$PUX z=Skfar57ZShLkkMG}4!#F#{gMJAMujl&*T;tKn%E(hcjN}*TJ@Btv~@dJ<4Q0BXyIZj2TA~e(O z85ET)tGu#@i%RJnhlmI#R;$e*==SLJ!QE-~CzV3+p1*mznO8HMg{YXXU`M4f!pkFGpvXQ{R00eo_3*b&dJ3%!ENVrdDD#@Pj>EX1X-ysCVR> zt*9{3c99mkleK3XeDm>V|7NQ3a9acwS!ASEfa=pV$NZdhh%Mg#P?Hz0G0XY6XaDA; zaDB7<4xkMSC+k288Iva?JKlRpq4%o)>4?81-7MgM-7J-wU5ll}oWD{KRv(;QeC(O0 zkn+sccvf$locsafeNYs$c*#XzhN3m zyflT1wNXFQk@k896yppMQD-5ao9L)_LUJOLKV!QUW$o$Z)&#?gjf7#6x*+U)?vum} zaNPD*=8!Z}>Srr^39tNqq4o>XO{~?OD(CvGJHdMzY&hG93?!aoFxjZ^m>vPK4XP&sP%giRY)M z>ZcTDsi3U+3>&tjjMhoG9iF_XHerBI7Jwdf<`yFV4^wTr2%)5bGUDs%K-s*ZBP`(f zH~G1l`XbIAC``}gqA6B66&g!6!^I7PWvTpSa{f;F2M7@;wNuEn80IuY#r`01*+nSj z4U_|#bArl4Sz|7@G;_>3r3H&JLq~1C+!T3a zzlItJJ2uP^LQ=qYMa9XOKkfcOuq#jl0cr1uDrHaQkb+ch&^V)C4DVJ#1I+q;{Gaj7 z`TmNJGU{0L%_p90d@WiMa&salRPv&ZKn*QPc6g*wc+yO*cDklpy1TGsZ7)1sEe>K+ zlJmpoMAMgF&WTdK^f@@(t^DexCn+Pk4v`XSLM}c2-KYF?sEKQI9iG|U%A{`L0e&eR zWxU6~bH9c0m4!cN#&UD>E9h2mqWG=HA30OJyFAZUX9a{7MT04pIq?@CcCbNP78w3@ zN?sV-K9hQmQ5F~pa2j9B9^TfBbYRy#!@<6*9|x5{Q*ezZvtl`fK#`Q zf+q%EEd0p$VLwB2T)qIKb0Q&pu4DYKI%H$~$7|nz>Tf1afFL6NMP=6U=T;XTh7BHn z^5H^1Io6vw(V1cxsZ$yks(DuY<%cx@L6Oj_m;;~fdXjcXAer;i7D@rdQ!UjCQJdKH zIPWbWE?rZUsWocq(2uH0@OP!ZYq2O)4CH+X0uM-NZB2cpZj3E5(X-!sxLf4J@%&#r z`|U>+dG4MSgW|-8XSUQ3#`h*hM|43#Wdx1SRPK9@tb42=0RkJAh=tjWNfj zcsS|g)N(_(yZM*j`^L8?j)^l5tmw!5N1l9UDp=G{EY?oUb{H{ix#LR9=U)1-YXkPk z+5h+ zH^vG_agc|cCsS%>?7w>8>BVw6!*?E97QAmf^YlZl+=3)6$IN1tH}tl3!s?jp%OAlE zOz_mVzFEjzzZneG=&oh4R|G4|`tAln=tboU62xSn9Hi_Qr9o&_=$%tJ;3cEASz{M718*P_rCk6PIWM2bdVowF ziq~n&HuX?|CWYyiv6%*}o9cP$XD7MCTJ^`XM#@QMvYju<#|7x9HN>&(!)pSUF=y^= zH2Wv)6@y!@XIKyBa9bJ=F@+Bqt^( zvbEAd$wF(ME}|-DS-YrE@%C`;!&eO;T7!XB@;ysD4;KXorJ7C8lB z8u+=tUK>a0#o9)7v{S28HmaMok$SDRQNOuXF61KDOcxQd94I)$2vRz20+U6mth0=fZzMgn#)(`^Q_-*hUMb<59|DwRQPP~TU*saz^#lPC-Z z-tBpKIM0K?aGcE-$%Y%XTdS3F0rrBxGx}p#h#ROS(gqgh2G-P#FxZCl6^T<@c?Rn# z+fv5F*|YjMpIe!2F2r~D7fyIfP6qW`fh&}F01S5AUb^frrv?LO8_fmqeRoNxB-KDy zZUP(|p`ol^P(Cf2WHMQE<3gndUx)vTSwIp2?$l&BwEaFLV2((NZrEO!6v_jvx5K4u z0BgCnyiO{S${|q}DX6d&T$=1G2jjE7F=yFj*gUH3 zr2>zQXQ!=|)+Co_ZD=S}?~bYkc(c}w#)GVb+V zEp-m(Apk z&rlXIet&QDfYs&)F! zMm6VIx@JI27f2lw;Zfjx&In`E&)QBBSmm7M3Fg}G>nvfbbow(TT zHs~Ubt{WTXVLQm(AE<_*pQk(Zl;^emy8nju25!|#zmgql_;>3oDW0RA(_X`^+n$P- zZjAxGa#VF(Wkb8DeOVR#UM#9$nFKu3cw!=>PAyfJPRiO!VXU<3@lvJAE1j(P7CysB z-|5=v2wC1f`cttj+{V^(itDH^Y6p-Pr4Jl2(veltdrLp@6@22TYI^E(m)@azw(^!X z(C>h1fz~?H@I2dJTq#B-5PJjtZS5UxzpB6Djk}_1*!sopW{}yNF;hEM0 zr%Qh5#pU*3;=t5oEgug2eK;u}^}{I472~*4i0ncoN~&>G&IQGK7+11UshUIxCX3}L zTg`@rBtX;|(7D?8O7-SMZ(^cb%lbYZNzR^Hi#KY-WKFJ}M24=>HoacSd>aFijx4T$%fH}_U|>hKhAN+=pH2f$pB_0c4nKQ1@K=8J z!Qp4W>RqJUf^A;dcI7B^-tq?i9YKgz9uu=koQv`^6WK5V#ngY>d&k@FddQ4jD!2{R z>Ms!*oGS?pDRgH@Xpnw~&@ci*!%N^ZT)xz0Zp3hR{9_f>IwDqR2G%L!%~Cd&W$cI8 z6OURpT6h?G=&0@&L-e5V9p6!5BRe#)GXypoQFsB~XlZ`nIgV!NY1SP@5!KCaRF9Su z3xTcdb`6oL+#fQ$F}5=$_JcHosOY`2+=g^c`VuczD}dW7&4eG%J-jH3Gbi)2%c8jw z-5t-n44+3Su;H_BUvsO}pd_^)Z8Sb&x9rRN?qzO-p_couZkuL*0tex3CkNUox3{+- zdWm>IKzUw-)0c)jB^Btf1)1BL{akAO06Lzy|H@uJL-G!fE73mr6_^d9tK+cXm+G)w z!Pj)?b7JE|UQKaB%ZqHyw^ciYWg;8gDb4k@BrzfDWB8$uekb&}>iLErnP_{0&Xm{_ zJxi2SJB!mtt%44as>DbX6iH}?F)HX+^b&Guqd$OruOMCeP9wZyyeraXNrCL8UOgzQ z4!tm%im21jWpdK6IS}ABx*jerq_OFJbp#EUngc1c z`n2uk?n|rhL(+*ZRmX>PqH8U`P4y6Zm8fo^KB)bVqL0AE3MkuU`Jn|59fZCcMbvR< z#Eim0z&jz%g0;vP`cdS>JUb3yKD^TP;8f6}$bv;Jng)uMt-^@q5EOP=(3@$=q;kgRQzqkfnQ^>I=SN`JRI=Or(nz>N*&+CSKxuDmpxAzK`00 zYNMDFI*MD2aV|mb4eQV?3~Hm*tSPM{gGM~38)LyQ$*fu{f%eyY;+xCy{Jjl-YCbo= z!1$}~-SHAi2l*<8HOK(!va<(9RjHgRsz}Jpt)OYyu7W~0BuaRVs!?uPQTUzL=*#ri5v=C1Oermzc)k06j+cdllZP(yh zp;ez6Q47lCOT7!&;tv7}b0bXnCi)BiRk5j_sD9(|M@q@e%0zy0Hn%X(MJL_k!9tQ@ zz+sVLK_Gf|(t-p#l`E$zkeNb~M5bHN`U}+tXqlueQN(}O~2y!)C zSXP`OKBnkm>Kx)~rH&lT-6DT0QSeW2t%4d9EV$PGn5VWh@{1sFVzUa zH%b>tn>VjXr~mM4^4HQAdAVL-Pw0(Ssa%*)b<`>0y)gCh!Yb+BqWTE9#ONbry zt)N}PlbL{uHqoNjo?UT12%dZ6&KLsuR$1X0EI~yHQAw&s6hy+V8g@HcdAYJmJ~CZz zIL{B4WMt$Kz97+um*{%Mrvtt@v?P`!7AWjTaS_a}p{t~ywdex4obH=cYE*`^CYNr+ zXyJDwZ26k>1%b~u%oBREQfyQvds9oT!s4<-t5RR+aN}N6S+`u)W zi_%8dS1c3BEMR2w>3LDLaG*#7Q25F)8>DLscEEAaO#@R?3y)H!%^5n;fe*Yta=Q*W zR}Zc>{VRZTrQdL^e2fmSW_kfU>$y6uOC_kFf`wuZ%xXGYLh2vGlCMZ#M$5IbHJ+{J zCu+6+%u=PaxTeP|&T(nBCuPj0#nux}+(|o#Q%7Plpz<SWqZHQv>BszXD{E-el(J$WFI!CF%-_*EFm z$>(HpoMGx$-OF|?lD&pus#i8Cjf&h3JSQDk@E5E{zYPzaN;VIhLqXD~vn6GQEQdB? z*~r6^3D&0Nq8bUJ(8sgnONe=-QqvxDEBSUO+nZjk78aK5aM>G^CeTeqMM@lHwp5U4 zr;5j5*Qt8*WMQij>#hW@FQS$!!jMSc`UrH&h*&YE@aqni64?=T3N%K~q3O37Q1%-E zsYf*o+8#@xZU$*7!wo_k1!i7M7 zl4=$ic(`-hB~$=dNFUphB4mIXxr|oLHhOV$@}5R%cFhY`{1aSj)*TmX5tDB~Z4cR` z9pX`IkgT8{uIQ<&1K8!RK$*}6l_R8zh9PaJUp6A&h(g0gS`^t-FEXNX zXjn01-a^2nOz6}hn*)%>*9pkJH-*$!9#n zId#fGjy862{Pgs|A08~DLG3Uw$*?3$2@cK2HRYE@4am__Rp86n%2c*IdvCiky&C$< z;R&uXA0Fo`ImnEQd>oSBo|6~ zL`uff-^Q~M@Y|?tH^DTIciNCGd2WNdJ&&1TGm#r#w@nO>P`_E(C*LN>!hOC==w z+LBvWIZ}PtA!}>0vovk(ZX4TQNw>@BAd76X)UU}#gu}mQ!1+RPl=82L zZo(1_vz6Y93^$Eq6+7J2v2mi(1v~3eLgs@ID+Rrj6+*a$x)+Y42%c!9j@nhib^ETXD z0F_M5n2xU0ip{;Ap%| zXjdY-cGBeM&Tqr$UC6ahW(I(!0@6dv8zX<0oaSE<0h5I(99EE>RkIZ}od?J%QACBk z*u&#`Gd;-+EnN2KC}a$?gLF7bvw&o8`pu4wpcHtWS=otA9R)xqw$*?FZ9{X@9oZ>2 zyIK6ED4F^_0+bc6&*b1TiyZ6J8s%ESmPZv?6yD))6%ctVPN7mNIg-YPrIP9;a?=CfT1+5*>SZHOT9 zoNN@D#cDywK+@$MF#dV8lszG2#yB@uYL{FE&7mMk(un0^-0nox)6L5Aay#l*_;J18 zi!%_q)fyg;U1bN&ts0uWxZncLUb?q|M9t1G?^j8zfgOjHWxL(3xjWsvk-oqg z2#1|CMGX7eP9fOJ@X~P@(HJdmoMe%Y@*RZZurEL=ly`!%GwP-^}4TALsq2L zqC2w23AB<^(2IB>?L}N$+m&9#ui|Jm0JKQ5iXD*F(-jWz0>x!mdV0Enrz<>7UYQEj z=hFNJ42=z(%5W&FBGpfYJhZQl@HR`2=&i%dBewc(|mP0%N0UYzm0a(uSHaI{{a=Pg)F0?Te;<(&h^fO{5!G9dw%???ekS;4gy6E=Yq7MK` z;_rsC?`x^m52Gkss&wia7W#1+p@c`v7z^5gTZcu{-`srmJ)>itrUf9Z=K#qtlgx|- zT{2*FBZOIF7cp6yZpIaGqBeZH+4GfrQfhcZw@z*#jTC6d#}ps{6XFTiM*!(d6t9Dc zcU`gD>(Dt8oq8jujAOsvD#AlNHBA`g)A=}E(`ltIh$H;9m9}>27>;~2Tyu-Eo;YMvIRb48aq5aZq)OBjOM^%c z2W^-$`|I*u237BI zw$`u-58XLX6>3yPksfjTu(S))roSN*h6vw89FEW}$pT{InNi|tK0u33&Ux1k}!%9^mZ!N*8s1vvay3?MjjHUFltn^HC6Y;bvV6mEsHXU6STg^rjL# zafs)q^H{EsuKG0Hf($pE#Oa&{NF!EvTD`KWjvfKY;Ts~}XQR6b{_;ZE$$5e6>s~B( z7O*j-HAv)maC*n8$Mho8UzBf=Ob^WCVzrtB2oiBExQ5r|@86aVaYC-0;~C<$2FJbyh1(E1yUAd%xt0DDn+Gk3k04xySPwq&HHS|oIs0Gqwd&Mi%q47 zcWli=H#c0H0!d$KpDiHP+WDaV92nZ~Qe0K8RuklD)>Hkduc0`BVg_(J6y#BHk-T~? zi-kHYE8-N6)lBDfN(`fT9Mc)j0!tta6)o2)*ISTRc8w^~-K-NY6(wZe+{92?1vT`v z6h#2T<01$c;qFy1`!}Ue$UqCA5&{?%Vmw;+*K7NCrJLl8(W>f9s-l$|pH6Zt{>-Ea zIaV;T2ciJD9q1adTSW=+gA+sYhqF7qA zG6jO0-8mWThN|y*2#>7;gubra0uE21TFtAXYa^$zfj!`BC>CQ&_OT-mjZft;Gb#mG z;Dphl_zkI6yn?oRDn45X*|67xN+uQNdehUB?f!hEgb_LmnO>u)kjcSFDb)4$ZKVU_H>0Evb-EDAz`Ka%TS~P zvn|+-S{Xba*y#IJ<(zu69MvjiQ>Ju0bTu~QubQ6j1XO83UBpFq1teRYq@4bRU$-6{ zKJL4K3E@F7g8Xt2&M&lzzGu1hiG@kf_2R-*-XZ(qX}3C;%>nuzc;JAg?~3qFWPnj+ zfqcP+bjz0AWgtL{pq+yAb-jka00kIMEO&H<7VLJzL!OrXs*?p!SY^>ac3dk@FHDxg z+0*rGe{JRd#~<>>_}p|&9FI$Sz96KXICseGs@hpiQ0exT=Pl6O)!jf5U64M5%~WMG zlAJ-G8G>oT$pY5{5-hmn-myZRDN~%G{Qy(={ z1a{fTU7JAA7u#XZFiSIC7`8X*T3N&ZNaRF?xRld@AEUPcIOgGh#EB3)K**&~Fm7N` zf|;!&eV)+q?#=65^H9H&S*2YSIqDX^-Sp?ByEtC;tL4OGc$s6Y_R4a@>fck&&76Md z?4wg0!v#|^3=s@1jbyIo<>H~IPvM53e4=EBl`mPodQrL^V0ucX<32DWseC?=-+G@pK!E#8 zU;hfOC$Pr#W%~s@6UO$7&OY~m3*NK)JRbJxl~HKBFXAHk@Fi#686o=j@M0I7P50BDo6J4B zwtVuzDvINkiEaydIuD%ib!W^)y&U9jCnzRfRE~mD-p`doVrN&{aZoDw*>Z%x{9@s9w((D%oWDXaDC^As1J3VW}8oQT%LVbJg^1AufN5x}n&ZAc9L5djO<^OPI$r}e2W;4O8Tb!9 zYM)-N_s?_-vug{BD-$uQ7u~tCYPCzbX5O&f3%E**rjB@Pyx+z}581)ⅇ2};T*7X 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

x@)zHZM-gUt#k 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≩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

N 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 {-*G9s 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 sS^^TE_)Av+8p2mGgvTBU*Z-G;{{J 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%0D{pd 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

p?pqd740jvPV~?#z%)fiPjrI+ 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

~KP5UF@?5?Z*r< zT&`rarWHRbTKV)vhV-4E&#Ft1sdMhN72l-|i335%00_IY;SW1Kd0Br8!Jmng?rY*L z7(KgseMah}@)Rn9#q?=}%=@xpY;K6Vp?gF-byeYzoK^7{ChoZ%?MI}<9>Ti`If)}y z_eo7Py?|XDj!`}_uWj*n6UHz6t`k8Blji&QqB|JBr%#)U2goR@1L9{}--M-|a6y

st6@En_60rNtqBPt z%wS-28gsN`S@(lS56!7C$uz^9ba#!;PyCPmRy(&Uaq!H|Ru`S?sjJZ{a!K#9pP)S5_UB@ns$71nV z-QbF4b-k;WF78bxQpqG$1=b}~*&20i-Nm)YwP{LrKd|?P#zb{8j^n}czK*lQ*nE<7 z9!yIB4PXc+oY@!hl5W8pspRHlv@wMT-0}3sIk$Rrru|008$2&6TSq0Rbwy2eHQDM55q;_V!{yC~f9&yl;EzPOk-`}lGVqPdHqCWM8jMa$ zaM=n%#Wc}ub@<(_cRc;>N9iLKU;M1Cp}G0;AED+)(JwHsaFQx?91(o9&^Sk>2F4LU zo63djYI+B*y!j{TpPptcnSH9(48oLX^|F4f0F05x)Z0v-=8-XsYr^6MmmF&@qMy2xp;V3>`E%V@F9ILxv^DQI0{ehf-?TEd>i2`azfW}1)ibfsn9)|=nA{>djc+bAM8xGm6W=^LK zV4ziBXEI3vC+w46>!|DOX$grSGQlNWbM)6s8Y*hxmJ6ax5sZRikt1Ea42(G&m=;8d zQf*CbQ)@FKSu+kY4DU`vBR04rq3e`_D_G=rKFDRjvnFBUV>Bd{7Oq+D*AghG1up{= zYdXSx@RIUP1Kn2qTE@srR}BTwRwaY!l-}ImGdUa;R&pN{_qE*f4=D0{_0S`*Zt_9%x?4d|0&zvNUK(}mq1y|-v{uP;OQlh_YAwJjf# z;7;P7#=~40E1U5O?^jaBGV*6!o*x|NsCSgIOxc3GmQgO>jP4XSg_*tdsV5d|3|S75 zf6Tov^56Xa%h-4@1DuUMpZb?g{<>tu!f)GQdgMO%Vw|_L?VjlVPkz=?UmBKl8Xbc>QD*#5I2cdWRAbNMPy&21`!b+;Aj@5>*I0bv zgcnUH;5uZi7QF!t8q#PoJDwEglG$T$$xW+ruNqieT}homKS9$~BRU0T*=hN-9D@PQ zlr&Rn(0l9s2vtzr0UU}q$?YrrtdaQ=btYN%Vp%}h2)uey)zaU4mOWd`S%op~5&#oL zS~`tM)EUrf)W9)j=Ls64XtjI%E%&_g$)B+CpFP`%e0-0Tyrzo@Y-=&3%)HD9I`Mhj*3cq*r8M66r=u%y$@a?a#>Mrc6}ihn}(kF_y7&wx*q3} z?s%vrj^0~l`y(&-U*2YJS=iOyRA29Rz;HDQdd8K6?iZ91;N=WPr#IZzyyWcf<#)Q}Hv7=?6p_t(Wr2ZAXW`LnP6O+HK-ekyO!JCE+!}v!&%8lhp zI^fb$^v6WdIp$D15i%HcUg&~T0<9hThZaX=N6_o|)LCYCbuOFZwPhVsy?%Hu;O~>h z>^a9&2@J!I=}h+Nc84|C*XD6;-F4UPSx?SchHKEDj5Ft$VOLyduyGNI!9436H(ijJ z___ZH4xjUwJ>P}&6MX6R+P<_G*Kc`d0t=)2 zRCkWpRU1xCAR+sxdXMJ|d$Ek1@}u^&UG4OJX;*cQ7NC&3SG~Cv_oEwqXjcdG4N1`$ zl)9PP%WPg3-oV2O5zVRy9qdK8NVB0C;hL__ zriN4El3F)ZO*l%n{%zX z=5IB2FJHD|Zc|%ZYkPZZTWc%qllB%=)3s(>vdtw;jWAiiQ(x0Kux!P=`a6EK=lV!( zB8tLTm=pAeN@Pc4rEyfBRwvT&ZzO6{bqB6%`Tf3l12PE_N(zo2Ap_I zY4xM>eS$;K_u_M7k!StB5v1giI2hTdx?;?zp8xb|G-MuC{pbs1@0rDqjMVYV

    { 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 z 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­oHrd|^1~{Pm#y5|pj`DoW?_ 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�gHVqBjXdQDEDFFI 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 Ky4!DEzyAjftSsdK literal 0 HcmV?d00001 diff --git a/assets/boson_exchange_diagram_simplified.png b/docs/assets/exchange-diagram-simplified.png similarity index 100% rename from assets/boson_exchange_diagram_simplified.png rename to docs/assets/exchange-diagram-simplified.png diff --git a/docs/contracts/deployment.md b/docs/contracts/deployment.md new file mode 100644 index 00000000..cfa4cc7a --- /dev/null +++ b/docs/contracts/deployment.md @@ -0,0 +1,26 @@ +# Smart Contracts - Deployment + +## Initialization + +[Migrations script](./migrations/2_deploy_contracts.js) for Truffle also does +this initialization: + +- ERC1155ERC721.setApprovalForAll(contractVoucherKernel.address, 'true') +- ERC1155ERC721.setVoucherKernelAddress(contractVoucherKernel.address) +- VoucherKernel.setCashierAddress(contractCashier.address) + +## Deployment addresses + +Contracts are deployed on Kovan testnet at addresses: + +ERC1155ERC721: 0xF3aA8eB3812303F6c86c136557bC23E48d634B58 +VoucherKernel: 0x1806312211bd1521430C953683038d6263580feE +Cashier: 0xaaf749c8e6e37b51410F1810ADcAEED18d0C166F + +The frontend is currently pointing to Kovan deployment. + +Contract are also deployed on Ropsten testnet at addresses: + +ERC1155ERC721: 0xe7028d66222aD1AfEB0098956347A6284443bd16 +VoucherKernel: 0xa93f95bf0039CE30957b77A6638e2e273598D576 +Cashier: 0x014b8baF57bA77FaE23075aa93c2B768eeb440bD diff --git a/doc_contracts.md b/docs/contracts/overview.md similarity index 95% rename from doc_contracts.md rename to docs/contracts/overview.md index 3dacc014..6fa757e8 100644 --- a/doc_contracts.md +++ b/docs/contracts/overview.md @@ -1,4 +1,4 @@ -# Smart contracts description +# Smart Contracts - Overview This is a brief description of the smart contracts used in Boson Protocol. They are based on two NFT standards, @@ -22,7 +22,7 @@ currencies used in that particular function (e.g. The journey through the NFT lifecycle is presented on a simplified diagram below. -![Simplified exchange mechanism](assets/boson_exchange_diagram_simplified.png) +![Simplified exchange mechanism](docs/assets/exchange-diagram-simplified.png) Voucher's status is defined in 7 bits that are set depending on the path in its lifecycle (defined in diff --git a/docs/setup/linux.md b/docs/setup/linux.md new file mode 100644 index 00000000..53921b88 --- /dev/null +++ b/docs/setup/linux.md @@ -0,0 +1,83 @@ +# Machine Setup - Linux + +## Requirements + +In order for the build to run correctly, a few tools will need to be installed +on your development machine: + +* git +* direnv +* Node (10.23.0) +* NPM (> 6) +* Ruby (2.7.2) +* Bundler (> 2) + +## Installation + +Installing the required tools is dependent on your distribution. In this guide, +we assume a Debian based distribution. + +### git & direnv + +To install git: + +```shell script +apt-get install git +``` + +To install direnv: + +```shell script +apt-get install direnv +echo "$(direnv hook bash)" >> ~/.bashrc +exec $SHELL + +direnv allow +``` + +Note: if you use zsh instead of bash, change `~/.bashrc` above to `~/.zshrc` +and use `direnv hook zsh`. + +### Node & NPM + +To install Node & NPM: + +```shell script +apt-get update +apt-get install curl +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash +mkdir ~/.nvm +echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.bashrc +echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> ~/.bashrc +echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> ~/.bashrc +exec $SHELL +nvm install 10.23.0 +nvm use 10.23.0 +``` + +Note: if you use zsh instead of bash, change `~/.bashrc` above to `~/.zshrc`. + +### Ruby & Bundler + +To install Ruby and bundler: + +```shell script +apt-get update +apt-get install \ + git curl libssl-dev libreadline-dev zlib1g-dev \ + autoconf bison build-essential libyaml-dev \ + libreadline-dev libncurses5-dev libffi-dev libgdbm-dev +curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash +echo 'export PATH="$PATH:~/.rbenv/bin"' >> ~/.bashrc +echo 'eval "$(rbenv init - bash)"' >> ~/.bashrc +exec $SHELL +rbenv install 2.7.2 +rbenv rehash +rbenv local 2.7.2 +gem install bundler +``` + +Note: if you use zsh instead of bash, change `~/.bashrc` above to `~/.zshrc` +and use `rbenv init - zsh`. + + diff --git a/docs/setup/osx.md b/docs/setup/osx.md new file mode 100644 index 00000000..f2b4adbf --- /dev/null +++ b/docs/setup/osx.md @@ -0,0 +1,79 @@ +# Machine Setup - OS X + +## Requirements + +In order for the build to run correctly, a few tools will need to be installed +on your development machine: + +* git +* direnv +* Node (10.23.0) +* NPM (> 6) +* Ruby (2.7.2) +* Bundler (> 2) + +## Installation + +Installing the required tools is best managed by [homebrew](http://brew.sh). + +To install homebrew: + +``` +ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" +``` + +### git & direnv + +To install git: + +```shell script +brew install git +``` + +To install direnv: + +```shell script +brew install direnv +echo "$(direnv hook zsh)" >> ~/.zshrc +exec $SHELL + +direnv allow +``` + +Note: if you use bash instead of zsh, change `~/.zshrc` above to `~/.bashrc` +and use `direnv hook bash`. + +### Node & NPM + +To install Node & NPM: + +```shell script +brew install nvm +mkdir ~/.nvm +echo 'export NVM_DIR="$HOME/.nvm"' >> ~/.zshrc +echo '[ -s "/usr/local/opt/nvm/nvm.sh" ] && . "/usr/local/opt/nvm/nvm.sh"' >> ~/.zshrc +echo '[ -s "/usr/local/opt/nvm/etc/bash_completion.d/nvm" ] && . "/usr/local/opt/nvm/etc/bash_completion.d/nvm"' >> ~/.zshrc +exec $SHELL +nvm install 10.23.0 +nvm use 10.23.0 +``` + +Note: if you use bash instead of zsh, change `~/.zshrc` above to `~/.bashrc` + +### Ruby & Bundler + +To install Ruby and bundler: + +```shell script +brew install rbenv +brew install ruby-build +echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc +exec $SHELL +rbenv install 2.7.2 +rbenv rehash +rbenv local 2.7.2 +gem install bundler +``` + +Note: if you use bash instead of zsh, change `~/.zshrc` above to `~/.bashrc` +and use `rbenv init - bash`. diff --git a/package.json b/package.json index 89c6733c..c24a7db1 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "tests:lint-fix": "eslint --fix test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", "tests:format": "prettier --list-different test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", "tests:format-fix": "prettier --write test/**/*.js testHelpers/**/*.js testUserInteractions/**/*.js", - "tests:integration": "truffle test --network test", + "tests:unit": "truffle test --network test", "tests:coverage": "node --max-old-space-size=4096 ./node_modules/.bin/truffle run coverage --network coverage" }, "repository": { diff --git a/testHelpers/users.js b/testHelpers/users.js index c52b2357..1fcca59e 100644 --- a/testHelpers/users.js +++ b/testHelpers/users.js @@ -1,28 +1,5 @@ const fs = require('fs'); -const defaultPrivateKeys = { - '0xd9995bae12fee327256ffec1e3184d492bd94c31': - '0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8', - '0xd4fa489eacc52ba59438993f37be9fcc20090e39': - '0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f', - '0x760bf27cd45036a6c486802d30b5d90cffbe31fe': - '0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2', - '0x56a32fff5e5a8b40d6a21538579fb8922df5258c': - '0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a', - '0xfec44e15328b7d1d8885a8226b0858964358f1d6': - '0x823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2', - '0xda8a06f1c910cab18ad187be1faa2b8606c2ec86': - '0xd6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3', - '0x8199de05654e9afa5c081bce38f140082c9a7733': - '0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a', - '0x28bf45680ca598708e5cdacc1414fcac04a3f1ed': - '0xf41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25', - '0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a': - '0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543', - '0x87e0ED760fb316eeb94Bd9cF23D1d2BE87aCe3d8': - '0xfac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186', -}; - const userIndices = { deployer: 0, seller: 1, @@ -33,27 +10,23 @@ const userIndices = { }; const loadPrivateKeys = (accountKeysFile) => { - let privateKeys = defaultPrivateKeys; - - if (accountKeysFile) { - const accountKeysRaw = fs.readFileSync(accountKeysFile); - const accountKeysJs = JSON.parse(accountKeysRaw); - - privateKeys = Object.fromEntries( - Object.entries(accountKeysJs['private_keys']).map((entry) => [ - entry[0], - `0x${entry[1]}`, - ]) - ); - } - - return privateKeys; + const accountKeysRaw = fs.readFileSync(accountKeysFile); + const accountKeysJs = JSON.parse(accountKeysRaw); + + return Object.fromEntries( + Object.entries(accountKeysJs['private_keys']).map((entry) => [ + entry[0], + `0x${entry[1]}`, + ]) + ); }; class Users { constructor(addresses) { this.addresses = addresses; - this.privateKeys = loadPrivateKeys(process.env.ACCOUNT_KEYS_FILE); + this.privateKeys = loadPrivateKeys( + process.env.ACCOUNT_KEYS_FILE || 'config/accounts.json' + ); } getAccountAtIndex(index) { From f1c36e5c005c7f9dffca4503cfe09fd91bc8aa43 Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Thu, 21 Jan 2021 16:00:59 +0000 Subject: [PATCH 17/22] Fix coverage. --- .solcover.js | 2 +- Rakefile | 2 +- config/accounts.json | 20 ++++++++++---------- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.solcover.js b/.solcover.js index 2d6d03b3..2f0ab8f7 100644 --- a/.solcover.js +++ b/.solcover.js @@ -13,4 +13,4 @@ module.exports = { testCommand: 'mocha --timeout 5000', measureStatementCoverage: false, providerOptions: { accounts } -}; \ No newline at end of file +}; diff --git a/Rakefile b/Rakefile index 4ce82a1f..75bfe49e 100644 --- a/Rakefile +++ b/Rakefile @@ -122,6 +122,6 @@ namespace :tests do desc "Run test coverage for contract unit tests" task :coverage => [:'dependencies:install'] do puts "Running test coverage for contract unit tests..." - sh(['npm', 'run', 'tests:coverage']) + sh('npm', 'run', 'tests:coverage') end end diff --git a/config/accounts.json b/config/accounts.json index 5171c28c..8e9ca574 100644 --- a/config/accounts.json +++ b/config/accounts.json @@ -1,14 +1,14 @@ { "private_keys": { - "0xd9995bae12fee327256ffec1e3184d492bd94c31": "0x7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8", - "0xd4fa489eacc52ba59438993f37be9fcc20090e39": "0x2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f", - "0x760bf27cd45036a6c486802d30b5d90cffbe31fe": "0x62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2", - "0x56a32fff5e5a8b40d6a21538579fb8922df5258c": "0xf473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a", - "0xfec44e15328b7d1d8885a8226b0858964358f1d6": "0x823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2", - "0xda8a06f1c910cab18ad187be1faa2b8606c2ec86": "0xd6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3", - "0x8199de05654e9afa5c081bce38f140082c9a7733": "0x187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a", - "0x28bf45680ca598708e5cdacc1414fcac04a3f1ed": "0xf41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25", - "0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a": "0x6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543", - "0x87e0ED760fb316eeb94Bd9cF23D1d2BE87aCe3d8": "0xfac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186" + "0xd9995bae12fee327256ffec1e3184d492bd94c31": "7ab741b57e8d94dd7e1a29055646bafde7010f38a900f55bbd7647880faa6ee8", + "0xd4fa489eacc52ba59438993f37be9fcc20090e39": "2030b463177db2da82908ef90fa55ddfcef56e8183caf60db464bc398e736e6f", + "0x760bf27cd45036a6c486802d30b5d90cffbe31fe": "62ecd49c4ccb41a70ad46532aed63cf815de15864bc415c87d507afd6a5e8da2", + "0x56a32fff5e5a8b40d6a21538579fb8922df5258c": "f473040b1a83739a9c7cc1f5719fab0f5bf178f83314d98557c58aae1910e03a", + "0xfec44e15328b7d1d8885a8226b0858964358f1d6": "823d590ed2cb5e8493bb0efc834771c1cde36f9fc49b9fe3620ebd0754ad6ea2", + "0xda8a06f1c910cab18ad187be1faa2b8606c2ec86": "d6d710943471e4c37ceb787857e7a2b41ca57f9cb4307ee9a9b21436a8e709c3", + "0x8199de05654e9afa5c081bce38f140082c9a7733": "187bb12e927c1652377405f81d93ce948a593f7d66cfba383ee761858b05921a", + "0x28bf45680ca598708e5cdacc1414fcac04a3f1ed": "f41486fdb04505e7966c8720a353ed92ce0d6830f8a5e915fbde735106a06d25", + "0xf0508f89e26bd6b00f66a9d467678c7ed16a3c5a": "6ca40ba4cca775643398385022264c0c414da1abd21d08d9e7136796a520a543", + "0x87e0ED760fb316eeb94Bd9cF23D1d2BE87aCe3d8": "fac0bc9325ad342033afe956e83f0bf8f1e863c1c3e956bc75d66961fe4cd186" } } From a4bb97ec59c7e2e0090e12c7ca5181388aed8f12 Mon Sep 17 00:00:00 2001 From: thecryptofruit <45678461+thecryptofruit@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:43:21 +0100 Subject: [PATCH 18/22] added the new BosonRouter contract references --- docs/contracts/overview.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/contracts/overview.md b/docs/contracts/overview.md index 6fa757e8..38e94c18 100644 --- a/docs/contracts/overview.md +++ b/docs/contracts/overview.md @@ -6,8 +6,9 @@ are based on two NFT standards, [ERC-721](https://eips.ethereum.org/EIPS/eip-721). Main contracts: +* BosonRouter: creation of VoucherSets and Vouchers * BosonToken: ERC-20 contract for the native Boson Protocol token -* Cashier: funds-related functions +* Cashier: escrow management * ERC1155ERC721: token factory * VoucherKernel: main business logic * UsingHelpers: common utils as structures @@ -39,12 +40,12 @@ lifecycle (defined in ### Happy path The process starts with Seller making an offer - minting a VoucherSet, which is -represented as ERC-1155 token: `Cashier.requestCreateOrder()`. The Seller sets +represented as ERC-1155 token: `BosonRouter.requestCreateOrder()`. The Seller sets the expiration period of the whole VoucherSet. Then the Buyer purchases the Voucher, i.e. is committing to redeem it at some point later - this means an ERC-721 token is extracted from a VoucherSet: -`Cashier.requestVoucher()`. +`BosonRouter.requestVoucher()`. The Buyer redeems the voucher, thus releasing the payment amount to the Seller: `VoucherKernel.redeem()`. From f752c517895b3c2217b5fc7639c42faf5dd39b15 Mon Sep 17 00:00:00 2001 From: thecryptofruit <45678461+thecryptofruit@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:49:44 +0100 Subject: [PATCH 19/22] Just had to add Fedora :p --- docs/setup/linux.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/setup/linux.md b/docs/setup/linux.md index 53921b88..3724e342 100644 --- a/docs/setup/linux.md +++ b/docs/setup/linux.md @@ -81,3 +81,4 @@ Note: if you use zsh instead of bash, change `~/.bashrc` above to `~/.zshrc` and use `rbenv init - zsh`. +Note: if you use Fedora, see installation instructions at [Installing Ruby and Rails with rbenv](https://developer.fedoraproject.org/start/sw/web-app/rails.html). From 26cbb2df7ac9ed9a124df834ea1b6e95f3e622c4 Mon Sep 17 00:00:00 2001 From: thecryptofruit <45678461+thecryptofruit@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:57:34 +0100 Subject: [PATCH 20/22] removed "not audited" comment --- contracts/BosonRouter.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/BosonRouter.sol b/contracts/BosonRouter.sol index 792c3bf8..236e610a 100644 --- a/contracts/BosonRouter.sol +++ b/contracts/BosonRouter.sol @@ -16,7 +16,6 @@ import "./ICashier.sol"; /** * @title Contract for managing funds - * @dev Warning: the contract hasn't been audited yet! * Roughly following OpenZeppelin's Escrow at https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/payment/ */ contract BosonRouter is From 962bb1acb1ee17f3b5fc9db3b70fbc86e3c34032 Mon Sep 17 00:00:00 2001 From: thecryptofruit <45678461+thecryptofruit@users.noreply.github.com> Date: Sun, 24 Jan 2021 17:58:04 +0100 Subject: [PATCH 21/22] removed "not audited" comment --- contracts/Cashier.sol | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/Cashier.sol b/contracts/Cashier.sol index 80e1a87f..5f9f79f4 100644 --- a/contracts/Cashier.sol +++ b/contracts/Cashier.sol @@ -13,7 +13,6 @@ import "./ICashier.sol"; /** * @title Contract for managing funds - * @dev Warning: the contract hasn't been audited yet! * Roughly following OpenZeppelin's Escrow at https://github.com/OpenZeppelin/openzeppelin-solidity/contracts/payment/ */ contract Cashier is ICashier, UsingHelpers, ReentrancyGuard, Ownable, Pausable { From f4ab2182f2ab92bda6605868645a51c7fee07ecb Mon Sep 17 00:00:00 2001 From: Toby Clemson Date: Sun, 24 Jan 2021 17:04:42 +0000 Subject: [PATCH 22/22] Rename `helpers` to `constants` in `utils.js`. --- testHelpers/utils.js | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/testHelpers/utils.js b/testHelpers/utils.js index d603d2e9..f0dec7c0 100644 --- a/testHelpers/utils.js +++ b/testHelpers/utils.js @@ -1,4 +1,4 @@ -const helpers = require('./constants'); +const constants = require('./constants'); const BN = web3.utils.BN; const truffleAssert = require('truffle-assertions'); @@ -44,9 +44,9 @@ class Utils { [ from, to, - helpers.product_price, + constants.product_price, sellerDeposit, - helpers.buyer_deposit, + constants.buyer_deposit, qty, ], { @@ -94,9 +94,9 @@ class Utils { [ from, to, - helpers.product_price, + constants.product_price, sellerDeposit, - helpers.buyer_deposit, + constants.buyer_deposit, qty, ], { @@ -143,9 +143,9 @@ class Utils { [ from, to, - helpers.product_price, + constants.product_price, sellerDeposit, - helpers.buyer_deposit, + constants.buyer_deposit, qty, ], { @@ -191,9 +191,9 @@ class Utils { [ from, to, - helpers.product_price, + constants.product_price, sellerDeposit, - helpers.buyer_deposit, + constants.buyer_deposit, qty, ], { @@ -212,9 +212,9 @@ class Utils { [ from, to, - helpers.product_price, + constants.product_price, sellerDeposit, - helpers.buyer_deposit, + constants.buyer_deposit, qty, ], { @@ -227,8 +227,8 @@ class Utils { } async commitToBuyTKNTKNWithPermit(buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit).add( - new BN(helpers.product_price) + const txValue = new BN(constants.buyer_deposit).add( + new BN(constants.product_price) ); const nonce1 = await this.contractBSNTokenDeposit.nonces(buyer.address); @@ -236,7 +236,7 @@ class Utils { this.contractBSNTokenDeposit, buyer.address, this.contractBSNRouter.address, - helpers.buyer_deposit, + constants.buyer_deposit, nonce1, this.deadline ); @@ -256,7 +256,7 @@ class Utils { this.contractBSNTokenPrice, buyer.address, this.contractBSNRouter.address, - helpers.product_price, + constants.product_price, nonce2, this.deadline ); @@ -299,8 +299,8 @@ class Utils { } async commitToBuyTKNTKNSameWithPermit(buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit).add( - new BN(helpers.product_price) + const txValue = new BN(constants.buyer_deposit).add( + new BN(constants.product_price) ); const nonce = await this.contractBSNTokenSame.nonces(buyer.address); @@ -354,7 +354,7 @@ class Utils { this.contractBSNTokenDeposit, buyer.address, this.contractBSNRouter.address, - helpers.buyer_deposit, + constants.buyer_deposit, nonce1, this.deadline ); @@ -367,12 +367,12 @@ class Utils { let txOrder = await this.contractBSNRouter.requestVoucherETHTKNWithPermit( tokenSupplyId, seller.address, - helpers.buyer_deposit, + constants.buyer_deposit, this.deadline, v, r, s, - {from: buyer.address, value: helpers.product_price.toString()} + {from: buyer.address, value: constants.product_price.toString()} ); let nestedValue = ( @@ -390,8 +390,8 @@ class Utils { } async commitToBuyETHETH(buyer, seller, tokenSupplyId) { - const txValue = new BN(helpers.buyer_deposit).add( - new BN(helpers.product_price) + const txValue = new BN(constants.buyer_deposit).add( + new BN(constants.product_price) ); let CommitTx = await this.contractBSNRouter.requestVoucherETHETH( @@ -424,7 +424,7 @@ class Utils { this.contractBSNTokenPrice, buyer.address, this.contractBSNRouter.address, - helpers.product_price, + constants.product_price, nonce1, this.deadline ); @@ -437,12 +437,12 @@ class Utils { let txOrder = await this.contractBSNRouter.requestVoucherTKNETHWithPermit( tokenSupplyId, seller.address, - helpers.product_price, + constants.product_price, this.deadline, v, r, s, - {from: buyer.address, value: helpers.buyer_deposit} + {from: buyer.address, value: constants.buyer_deposit} ); let nestedValue = (

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

|b}PJjUD_8ulZ0Rh+s6YA#yG~WZU$5i5~ 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