From 8345d3654fb8e716367c8b7e545996a3be8047a3 Mon Sep 17 00:00:00 2001 From: bin Date: Fri, 10 Feb 2023 23:30:39 +0800 Subject: [PATCH] initial version, but it is not done 1. replace Niflot to TradableStream 2. rename IncDec to CFALib 3. implement payOwner function 4. add refund logic in burn function 5. limit TradableStream only transfer one time 6. add onlyOwner access control for payOwner and burn implement a new version 1. remove unused IReceivableAsset interface 2. convert Super token amount to underlying token amount fix a permission issue of TradableStream burn add view functions add positive tests of Superfluid pool replace require messages to errors goerli deployment scripts fixing forking error remove forking for the whole hardhat network updated workflow file adding testing log add deployment validation script added env for testing added env for testing reverting debugging log add error code Borrow in one send (#298) * code and one test * 1. add the limit to call fixed function mintToWithAuthorization 2. add msg.sender check 3. update tests * 1. add Multisend contract and tests 2. add permit function in TestToken 3. use block.chainid * remove owner and nonce parameter * deploy and verify new contracts about Superfluid * 1. update superfluid pool tests on mumbai 2. fix bugs of goerli superfluid pool scripts 3. create mumbai superfluid pool scripts 4. deploy, verify and validate superfluid pool contracts on mumbai * 1. refactor drawdownWithAuthorization function 2. remove drawdownWithReceivable function * update tests to borrow the same amount as NFT locked value * update based on review comments * remove Superfluid v1 contracts add more tests conflict in yarn.lock Refactor ReceivableFactoringPool (#299) * 1. involve SuperApp framework 2. split SuperfluidPool to ReceivableFactoringPool and SuperfluidProcessor 3. implement drawdown function of SuperfluidProcessor * implement payoff function of SuperfluidPoolProcessor * add flow change logic * fix approveCredit and mintAndDrawdown tests * fix Superfluid tests 1. add logic to handle flow termination 2. add related tests 1. refactor SuperfluidPoolProcessor and TradableStream for adding logic in _handleFlowChange 2. add comments to describe options in _handleFlowChange 1. rename payoff to settlement 2. remove decreasing/increasing flow logic 3. revert transaction when decreasing/increasing flow 4. add tryTransferAllowance function 5. make settlement to be able called repeatedly 1. add new errors 2. add a new command 'gen-code-ids' 3. clean code add negative tests for mintToAndDrawdown 1. fix a bug of settlement 2. add negative tests for settlement 3. add more comments 1. update deployment scripts 2. deploy new contracts on mumbai 1. add comments to describe one limitation of flow terminatation 2. use current flow rate instead of the initial flow rate when burn NFT 1. add new logic to handle multiple borrowers of one flow termination 2. revert increasing/decreasing flows 3. revert creating new flow to processor 4. fix tests and add new tests add comments deploy new contracts about Superfluid deploy new contracts about Superfluid fix some small bugs superfluid processor event update (#306) * superfluid processor event update * update deployed contracts on mumbai for superfluid * add unit test for settlement success event * update receivableCleared and settlementMade events * update deploy contract addresses --------- Co-authored-by: shan Superfluid pool event update (#311) update receivableCleared and settlementMade events to include flowKey Co-authored-by: shan update receivableCleared and settlementMade events to include flowKey (#314) Co-authored-by: shan 03 fine tune to Superfluid changes (#315) * Polish TradableStream.sol * comment out one skipped test * comment out logs in SuperfluidFactoringTest.sol * 1. update burn function permission 2. change require to revert errors in TradableStream contract * Added some comments --------- Co-authored-by: bin New tests (#316) * add new tests --- .github/workflows/linter_ci_js_test.yml | 3 + .vscode/settings.json | 14 +- abi/ERC20Permit.json | 347 ++ abi/ERC20WithTokenInfo.json | 224 + abi/Errors.json | 90 + abi/IConstantFlowAgreementV1.json | 958 ++++ abi/IERC777.json | 393 ++ abi/IReceivablePool.json | 242 + abi/ISuperAgreement.json | 54 + abi/ISuperApp.json | 251 + abi/ISuperToken.json | 1753 +++++++ abi/ISuperTokenFactory.json | 252 + abi/ISuperfluid.json | 1122 ++++ abi/ISuperfluidGovernance.json | 236 + abi/ISuperfluidToken.json | 673 +++ abi/MockSuperAppRegister.json | 39 + abi/Multisend.json | 26 + abi/ReceivableFactoringPoolProcessor.json | 71 + ...ceivableFactoringPoolProcessorStorage.json | 15 + abi/ReceivableFactoringPoolStorageV2.json | 44 + abi/ReceivableFactoringPoolV2.json | 1505 ++++++ abi/SuperAppBase.json | 251 + abi/SuperfluidFeeManager.json | 513 ++ abi/SuperfluidPoolProcessor.json | 796 +++ abi/SuperfluidPoolProcessorStorage.json | 41 + abi/TestToken.json | 75 + abi/TokenInfo.json | 41 + abi/TradableStream.json | 895 ++++ contracts/BaseCreditPool.sol | 2 - contracts/BaseFeeManager.sol | 11 +- contracts/BasePool.sol | 6 +- contracts/BasePoolConfig.sol | 2 +- contracts/Errors.sol | 24 +- .../ReceivableFactoringPoolProcessor.sol | 31 + ...eceivableFactoringPoolProcessorStorage.sol | 10 + .../ReceivableFactoringPoolStorageV2.sol | 13 + contracts/ReceivableFactoringPoolV2.sol | 235 + contracts/interfaces/IReceivablePool.sol | 46 + contracts/mock/MockSuperAppRegister.sol | 22 + contracts/mock/TestToken.sol | 7 +- contracts/superfluid/CFALib.sol | 97 + contracts/superfluid/SuperfluidFeeManager.sol | 75 + .../superfluid/SuperfluidPoolProcessor.sol | 538 ++ .../SuperfluidPoolProcessorStorage.sol | 32 + contracts/superfluid/TradableStream.sol | 405 ++ contracts/utils/Multisend.sol | 30 + deployment/goerli-deployed-contracts.json | 12 +- deployment/goerli-initialized-contracts.json | 26 +- deployment/goerli-verified-contracts.json | 12 +- ...deploy-goerli-superfluid-factoring-pool.js | 75 + .../init-goerli-superfluid-factoring-pool.js | 424 ++ ...fication-test-superfluid-factoring-pool.js | 279 + ...verify-goerli-superfluid-factoring-pool.js | 167 + .../goerli/verify_args/HumaConfigTimelock.js | 3 + .../verify_args/SuperfluidFactoringPool.js | 3 + ...perfluidFactoringPoolProxyAdminTimelock.js | 3 + .../SuperfluidFactoringPoolTimelock.js | 3 + .../goerli/verify_args/SuperfluidPoolHDT.js | 3 + .../verify_args/SuperfluidTradableStream.js | 3 + deployment/maticmum-deployed-contracts.json | 18 + .../maticmum-initialized-contracts.json | 6 + deployment/maticmum-verified-contracts.json | 17 + .../deploy-superfluid-factoring-pool.js | 82 + ...ploy-superfluid-mock-super-app-register.js | 28 + .../mumbai/init-superfluid-factoring-pool.js | 457 ++ ...fication-test-superfluid-factoring-pool.js | 371 ++ .../verify-superfluid-factoring-pool.js | 170 + ...rify-superfluid-mock-super-app-register.js | 99 + .../mumbai/verify_args/HumaConfigTimelock.js | 3 + .../verify_args/MockSuperAppRegister.js | 3 + .../verify_args/SuperfluidFactoringPool.js | 5 + ...perfluidFactoringPoolProxyAdminTimelock.js | 3 + .../SuperfluidFactoringPoolTimelock.js | 3 + .../mumbai/verify_args/SuperfluidPoolHDT.js | 5 + .../verify_args/SuperfluidTradableStream.js | 3 + deployment/utils.js | 8 +- hardhat.config.js | 69 +- package.json | 9 +- scripts/error-functions.json | 22 +- test/BasePoolConfigTest.js | 3 - test/BaseTest.js | 36 +- test/SuperfluidFactoringTest.js | 4498 +++++++++++++++++ yarn.lock | 3004 ++++++++++- 83 files changed, 22308 insertions(+), 137 deletions(-) create mode 100644 abi/ERC20Permit.json create mode 100644 abi/ERC20WithTokenInfo.json create mode 100644 abi/IConstantFlowAgreementV1.json create mode 100644 abi/IERC777.json create mode 100644 abi/IReceivablePool.json create mode 100644 abi/ISuperAgreement.json create mode 100644 abi/ISuperApp.json create mode 100644 abi/ISuperToken.json create mode 100644 abi/ISuperTokenFactory.json create mode 100644 abi/ISuperfluid.json create mode 100644 abi/ISuperfluidGovernance.json create mode 100644 abi/ISuperfluidToken.json create mode 100644 abi/MockSuperAppRegister.json create mode 100644 abi/Multisend.json create mode 100644 abi/ReceivableFactoringPoolProcessor.json create mode 100644 abi/ReceivableFactoringPoolProcessorStorage.json create mode 100644 abi/ReceivableFactoringPoolStorageV2.json create mode 100644 abi/ReceivableFactoringPoolV2.json create mode 100644 abi/SuperAppBase.json create mode 100644 abi/SuperfluidFeeManager.json create mode 100644 abi/SuperfluidPoolProcessor.json create mode 100644 abi/SuperfluidPoolProcessorStorage.json create mode 100644 abi/TokenInfo.json create mode 100644 abi/TradableStream.json create mode 100644 contracts/ReceivableFactoringPoolProcessor.sol create mode 100644 contracts/ReceivableFactoringPoolProcessorStorage.sol create mode 100644 contracts/ReceivableFactoringPoolStorageV2.sol create mode 100644 contracts/ReceivableFactoringPoolV2.sol create mode 100644 contracts/interfaces/IReceivablePool.sol create mode 100644 contracts/mock/MockSuperAppRegister.sol create mode 100644 contracts/superfluid/CFALib.sol create mode 100644 contracts/superfluid/SuperfluidFeeManager.sol create mode 100644 contracts/superfluid/SuperfluidPoolProcessor.sol create mode 100644 contracts/superfluid/SuperfluidPoolProcessorStorage.sol create mode 100644 contracts/superfluid/TradableStream.sol create mode 100644 contracts/utils/Multisend.sol create mode 100644 deployment/goerli/deploy-goerli-superfluid-factoring-pool.js create mode 100644 deployment/goerli/init-goerli-superfluid-factoring-pool.js create mode 100644 deployment/goerli/verification-test-superfluid-factoring-pool.js create mode 100644 deployment/goerli/verify-goerli-superfluid-factoring-pool.js create mode 100644 deployment/goerli/verify_args/HumaConfigTimelock.js create mode 100644 deployment/goerli/verify_args/SuperfluidFactoringPool.js create mode 100644 deployment/goerli/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js create mode 100644 deployment/goerli/verify_args/SuperfluidFactoringPoolTimelock.js create mode 100644 deployment/goerli/verify_args/SuperfluidPoolHDT.js create mode 100644 deployment/goerli/verify_args/SuperfluidTradableStream.js create mode 100644 deployment/maticmum-deployed-contracts.json create mode 100644 deployment/maticmum-initialized-contracts.json create mode 100644 deployment/maticmum-verified-contracts.json create mode 100644 deployment/mumbai/deploy-superfluid-factoring-pool.js create mode 100644 deployment/mumbai/deploy-superfluid-mock-super-app-register.js create mode 100644 deployment/mumbai/init-superfluid-factoring-pool.js create mode 100644 deployment/mumbai/verification-test-superfluid-factoring-pool.js create mode 100644 deployment/mumbai/verify-superfluid-factoring-pool.js create mode 100644 deployment/mumbai/verify-superfluid-mock-super-app-register.js create mode 100644 deployment/mumbai/verify_args/HumaConfigTimelock.js create mode 100644 deployment/mumbai/verify_args/MockSuperAppRegister.js create mode 100644 deployment/mumbai/verify_args/SuperfluidFactoringPool.js create mode 100644 deployment/mumbai/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js create mode 100644 deployment/mumbai/verify_args/SuperfluidFactoringPoolTimelock.js create mode 100644 deployment/mumbai/verify_args/SuperfluidPoolHDT.js create mode 100644 deployment/mumbai/verify_args/SuperfluidTradableStream.js create mode 100644 test/SuperfluidFactoringTest.js diff --git a/.github/workflows/linter_ci_js_test.yml b/.github/workflows/linter_ci_js_test.yml index a5f12997..d8e8ba81 100644 --- a/.github/workflows/linter_ci_js_test.yml +++ b/.github/workflows/linter_ci_js_test.yml @@ -17,4 +17,7 @@ jobs: - name: Check coding styles run: yarn lint-solidity - name: run tests + env: + GOERLI_URL: ${{ secrets.GOERLI_URL }} + MUMBAI_URL: ${{ secrets.MUMBAI_URL }} run: yarn test diff --git a/.vscode/settings.json b/.vscode/settings.json index 530019b2..d95a1181 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,8 @@ { - "editor.formatOnSave": true, - "[solidity]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" - }, - "solidity.defaultCompiler": "remote", - "solidity.compileUsingRemoteVersion": "v0.8.4+commit.c7e474f2" -} \ No newline at end of file + "editor.formatOnSave": true, + "[solidity]": { + "editor.defaultFormatter": "esbenp.prettier-vscode" + }, + "editor.defaultFormatter": "esbenp.prettier-vscode", + "solidity.compileUsingRemoteVersion": "v0.8.11+commit.d7f03943" +} diff --git a/abi/ERC20Permit.json b/abi/ERC20Permit.json new file mode 100644 index 00000000..1e5f78ed --- /dev/null +++ b/abi/ERC20Permit.json @@ -0,0 +1,347 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ERC20WithTokenInfo.json b/abi/ERC20WithTokenInfo.json new file mode 100644 index 00000000..177ac839 --- /dev/null +++ b/abi/ERC20WithTokenInfo.json @@ -0,0 +1,224 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/Errors.json b/abi/Errors.json index d8c88de4..e770fe6c 100644 --- a/abi/Errors.json +++ b/abi/Errors.json @@ -1,4 +1,19 @@ [ + { + "inputs": [], + "name": "AuthorizationExpired", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAuthorization", + "type": "error" + }, + { + "inputs": [], + "name": "allowanceTooLow", + "type": "error" + }, { "inputs": [], "name": "alreadyAPauser", @@ -19,6 +34,11 @@ "name": "amountTooLow", "type": "error" }, + { + "inputs": [], + "name": "borrowerMismatch", + "type": "error" + }, { "inputs": [], "name": "borrowingAmountLessThanPlatformFees", @@ -99,6 +119,11 @@ "name": "drawdownFunctionUsedInsteadofDrawdownWithReceivable", "type": "error" }, + { + "inputs": [], + "name": "durationTooLong", + "type": "error" + }, { "inputs": [], "name": "evaluationAgentNotEnoughLiquidity", @@ -114,6 +139,16 @@ "name": "exceededPoolLiquidityCap", "type": "error" }, + { + "inputs": [], + "name": "flowIsNotTerminated", + "type": "error" + }, + { + "inputs": [], + "name": "flowKeyMismatch", + "type": "error" + }, { "inputs": [], "name": "greaterThanMaxCreditLine", @@ -129,11 +164,36 @@ "name": "invalidBasisPointHigherThan10000", "type": "error" }, + { + "inputs": [], + "name": "invalidFlowrate", + "type": "error" + }, + { + "inputs": [], + "name": "invalidSuperfluidAction", + "type": "error" + }, + { + "inputs": [], + "name": "invalidSuperfluidCallback", + "type": "error" + }, { "inputs": [], "name": "minPrincipalPaymentRateSettingTooHigh", "type": "error" }, + { + "inputs": [], + "name": "newReceiverSameToOrigin", + "type": "error" + }, + { + "inputs": [], + "name": "notEnoughAvailableFlowrate", + "type": "error" + }, { "inputs": [], "name": "notEvaluationAgent", @@ -179,11 +239,21 @@ "name": "notPoolOwnerTreasuryOrEA", "type": "error" }, + { + "inputs": [], + "name": "notProcessor", + "type": "error" + }, { "inputs": [], "name": "notProtocolOwner", "type": "error" }, + { + "inputs": [], + "name": "notTradableStreamOwner", + "type": "error" + }, { "inputs": [], "name": "onlyBorrowerOrEACanReduceCreditLine", @@ -249,6 +319,11 @@ "name": "receivableAssetParamMismatch", "type": "error" }, + { + "inputs": [], + "name": "receivableIdMismatch", + "type": "error" + }, { "inputs": [], "name": "requestedCreditWithZeroDuration", @@ -259,6 +334,21 @@ "name": "sameValue", "type": "error" }, + { + "inputs": [], + "name": "settlementTooSoon", + "type": "error" + }, + { + "inputs": [], + "name": "tradableStreamNotExisting", + "type": "error" + }, + { + "inputs": [], + "name": "tradableStreamNotMatured", + "type": "error" + }, { "inputs": [], "name": "treasuryFeeHighThanUpperLimit", diff --git a/abi/IConstantFlowAgreementV1.json b/abi/IConstantFlowAgreementV1.json new file mode 100644 index 00000000..5e875ffe --- /dev/null +++ b/abi/IConstantFlowAgreementV1.json @@ -0,0 +1,958 @@ +[ + { + "inputs": [], + "name": "CFA_ACL_FLOW_RATE_ALLOWANCE_EXCEEDED", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_NO_NEGATIVE_ALLOWANCE", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_NO_SENDER_CREATE", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_NO_SENDER_FLOW_OPERATOR", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_NO_SENDER_UPDATE", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_OPERATOR_NO_CREATE_PERMISSIONS", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_OPERATOR_NO_DELETE_PERMISSIONS", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_OPERATOR_NO_UPDATE_PERMISSIONS", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ACL_UNCLEAN_PERMISSIONS", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_DEPOSIT_TOO_BIG", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_FLOW_ALREADY_EXISTS", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_FLOW_DOES_NOT_EXIST", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_FLOW_RATE_TOO_BIG", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_HOOK_OUT_OF_GAS", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_INSUFFICIENT_BALANCE", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_INVALID_FLOW_RATE", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_NON_CRITICAL_SENDER", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_NO_SELF_FLOW", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ZERO_ADDRESS_RECEIVER", + "type": "error" + }, + { + "inputs": [], + "name": "CFA_ZERO_ADDRESS_SENDER", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "flowOperator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint8", + "name": "permissions", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "int96", + "name": "flowRateAllowance", + "type": "int96" + } + ], + "name": "FlowOperatorUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "indexed": false, + "internalType": "int256", + "name": "totalSenderFlowRate", + "type": "int256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "totalReceiverFlowRate", + "type": "int256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "name": "FlowUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "flowOperator", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + } + ], + "name": "FlowUpdatedExtension", + "type": "event" + }, + { + "inputs": [], + "name": "agreementType", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "flowOperator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "authorizeFlowOperatorWithFullControl", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "createFlow", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "createFlowByOperator", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "flowOperator", + "type": "address" + }, + { + "internalType": "int96", + "name": "subtractedFlowRateAllowance", + "type": "int96" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "decreaseFlowRateAllowance", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "deleteFlow", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "deleteFlowByOperator", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountFlowInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + } + ], + "name": "getDepositRequiredForFlowRate", + "outputs": [ + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "getFlow", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "agreementId", + "type": "bytes32" + } + ], + "name": "getFlowByID", + "outputs": [ + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "flowOperator", + "type": "address" + } + ], + "name": "getFlowOperatorData", + "outputs": [ + { + "internalType": "bytes32", + "name": "flowOperatorId", + "type": "bytes32" + }, + { + "internalType": "uint8", + "name": "permissions", + "type": "uint8" + }, + { + "internalType": "int96", + "name": "flowRateAllowance", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "flowOperatorId", + "type": "bytes32" + } + ], + "name": "getFlowOperatorDataByID", + "outputs": [ + { + "internalType": "uint8", + "name": "permissions", + "type": "uint8" + }, + { + "internalType": "int96", + "name": "flowRateAllowance", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + } + ], + "name": "getMaximumFlowRateFromDeposit", + "outputs": [ + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getNetFlow", + "outputs": [ + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "flowOperator", + "type": "address" + }, + { + "internalType": "int96", + "name": "addedFlowRateAllowance", + "type": "int96" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "increaseFlowRateAllowance", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "isPatricianPeriod", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isPatricianPeriodNow", + "outputs": [ + { + "internalType": "bool", + "name": "isCurrentlyPatricianPeriod", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "realtimeBalanceOf", + "outputs": [ + { + "internalType": "int256", + "name": "dynamicBalance", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "flowOperator", + "type": "address" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "revokeFlowOperatorWithFullControl", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "updateFlow", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowRate", + "type": "int96" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "updateFlowByOperator", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "flowOperator", + "type": "address" + }, + { + "internalType": "uint8", + "name": "permissions", + "type": "uint8" + }, + { + "internalType": "int96", + "name": "flowRateAllowance", + "type": "int96" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "updateFlowOperatorPermissions", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/IERC777.json b/abi/IERC777.json new file mode 100644 index 00000000..c713a87c --- /dev/null +++ b/abi/IERC777.json @@ -0,0 +1,393 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "AuthorizedOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Burned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Minted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "RevokedOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Sent", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "authorizeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultOperators", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "granularity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "isOperatorFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "operatorBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "operatorSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "revokeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/IReceivablePool.json b/abi/IReceivablePool.json new file mode 100644 index 00000000..2c13a52e --- /dev/null +++ b/abi/IReceivablePool.json @@ -0,0 +1,242 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "creditRecordMapping", + "outputs": [ + { + "components": [ + { + "internalType": "uint96", + "name": "unbilledPrincipal", + "type": "uint96" + }, + { + "internalType": "uint64", + "name": "dueDate", + "type": "uint64" + }, + { + "internalType": "int96", + "name": "correction", + "type": "int96" + }, + { + "internalType": "uint96", + "name": "totalDue", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "feesAndInterestDue", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "missedPeriods", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "remainingPeriods", + "type": "uint16" + }, + { + "internalType": "enum BaseStructs.CreditState", + "name": "state", + "type": "uint8" + } + ], + "internalType": "struct BaseStructs.CreditRecord", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "creditRecordStaticMapping", + "outputs": [ + { + "components": [ + { + "internalType": "uint96", + "name": "creditLimit", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "aprInBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "intervalInDays", + "type": "uint16" + }, + { + "internalType": "uint96", + "name": "defaultAmount", + "type": "uint96" + } + ], + "internalType": "struct BaseStructs.CreditRecordStatic", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "drawdown4Processor", + "outputs": [ + { + "internalType": "uint256", + "name": "netAmountToBorrower", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCoreData", + "outputs": [ + { + "internalType": "address", + "name": "underlyingToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "poolToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "humaConfig_", + "type": "address" + }, + { + "internalType": "address", + "name": "feeManager_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "makePayment4Processor", + "outputs": [ + { + "internalType": "uint256", + "name": "amountPaid", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "paidoff", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "settlement4Processor", + "outputs": [ + { + "internalType": "uint256", + "name": "amountPaid", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "paidoff", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receivableParam", + "type": "uint256" + } + ], + "name": "validateReceivableAsset", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ISuperAgreement.json b/abi/ISuperAgreement.json new file mode 100644 index 00000000..820affaa --- /dev/null +++ b/abi/ISuperAgreement.json @@ -0,0 +1,54 @@ +[ + { + "inputs": [], + "name": "agreementType", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "realtimeBalanceOf", + "outputs": [ + { + "internalType": "int256", + "name": "dynamicBalance", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/ISuperApp.json b/abi/ISuperApp.json new file mode 100644 index 00000000..23d97108 --- /dev/null +++ b/abi/ISuperApp.json @@ -0,0 +1,251 @@ +[ + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "agreementData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "cbdata", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "afterAgreementCreated", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "agreementData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "cbdata", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "afterAgreementTerminated", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "agreementData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "cbdata", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "afterAgreementUpdated", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "agreementData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "beforeAgreementCreated", + "outputs": [ + { + "internalType": "bytes", + "name": "cbdata", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "agreementData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "beforeAgreementTerminated", + "outputs": [ + { + "internalType": "bytes", + "name": "cbdata", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "agreementData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "beforeAgreementUpdated", + "outputs": [ + { + "internalType": "bytes", + "name": "cbdata", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/ISuperToken.json b/abi/ISuperToken.json new file mode 100644 index 00000000..ffd956ef --- /dev/null +++ b/abi/ISuperToken.json @@ -0,0 +1,1753 @@ +[ + { + "inputs": [], + "name": "SF_TOKEN_AGREEMENT_ALREADY_EXISTS", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_AGREEMENT_DOES_NOT_EXIST", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_BURN_INSUFFICIENT_BALANCE", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_MOVE_INSUFFICIENT_BALANCE", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_ONLY_HOST", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_ONLY_LISTED_AGREEMENT", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_MINT_TO_ZERO_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_NO_UNDERLYING_TOKEN", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_ONLY_HOST", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_ONLY_SELF", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "AgreementCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "penaltyAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + } + ], + "name": "AgreementLiquidated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidatorAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "penaltyAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bondAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bailoutAmount", + "type": "uint256" + } + ], + "name": "AgreementLiquidatedBy", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidatorAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "targetAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "rewardAmountReceiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "targetAccountBalanceDelta", + "type": "int256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "liquidationTypeData", + "type": "bytes" + } + ], + "name": "AgreementLiquidatedV2", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "slotId", + "type": "uint256" + } + ], + "name": "AgreementStateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "AgreementTerminated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "AgreementUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "AuthorizedOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bailoutAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bailoutAmount", + "type": "uint256" + } + ], + "name": "Bailout", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Burned", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Minted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "RevokedOperator", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "Sent", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenDowngraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenUpgraded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "authorizeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "balance", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "createAgreement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "defaultOperators", + "outputs": [ + { + "internalType": "address[]", + "name": "", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "downgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "downgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountActiveAgreements", + "outputs": [ + { + "internalType": "contract ISuperAgreement[]", + "name": "activeAgreements", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "dataLength", + "type": "uint256" + } + ], + "name": "getAgreementData", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "slotId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dataLength", + "type": "uint256" + } + ], + "name": "getAgreementStateSlot", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "slotData", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getHost", + "outputs": [ + { + "internalType": "address", + "name": "host", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getUnderlyingToken", + "outputs": [ + { + "internalType": "address", + "name": "tokenAddr", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "granularity", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "uint8", + "name": "underlyingDecimals", + "type": "uint8" + }, + { + "internalType": "string", + "name": "n", + "type": "string" + }, + { + "internalType": "string", + "name": "s", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "isAccountCritical", + "outputs": [ + { + "internalType": "bool", + "name": "isCritical", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isAccountCriticalNow", + "outputs": [ + { + "internalType": "bool", + "name": "isCritical", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "isAccountSolvent", + "outputs": [ + { + "internalType": "bool", + "name": "isSolvent", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isAccountSolventNow", + "outputs": [ + { + "internalType": "bool", + "name": "isSolvent", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "address", + "name": "tokenHolder", + "type": "address" + } + ], + "name": "isOperatorFor", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "liquidationTypeData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "liquidatorAccount", + "type": "address" + }, + { + "internalType": "bool", + "name": "useDefaultRewardAccount", + "type": "bool" + }, + { + "internalType": "address", + "name": "targetAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "targetAccountBalanceDelta", + "type": "int256" + } + ], + "name": "makeLiquidationPayoutsV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "operationApprove", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "operationDecreaseAllowance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "operationDowngrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "operationIncreaseAllowance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "operationSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "operationTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "operationUpgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "operatorBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "operatorData", + "type": "bytes" + } + ], + "name": "operatorSend", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "realtimeBalanceOf", + "outputs": [ + { + "internalType": "int256", + "name": "availableBalance", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "realtimeBalanceOfNow", + "outputs": [ + { + "internalType": "int256", + "name": "availableBalance", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "revokeOperator", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "selfApproveFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "name": "selfBurn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "name": "selfMint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "selfTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "send", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "int256", + "name": "delta", + "type": "int256" + } + ], + "name": "settleBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "dataLength", + "type": "uint256" + } + ], + "name": "terminateAgreement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "recipient", + "type": "address" + } + ], + "name": "transferAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "updateAgreementData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "slotId", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "slotData", + "type": "bytes32[]" + } + ], + "name": "updateAgreementStateSlot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "upgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "upgradeTo", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ISuperTokenFactory.json b/abi/ISuperTokenFactory.json new file mode 100644 index 00000000..5608a2c5 --- /dev/null +++ b/abi/ISuperTokenFactory.json @@ -0,0 +1,252 @@ +[ + { + "inputs": [], + "name": "SUPER_TOKEN_FACTORY_ALREADY_EXISTS", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_FACTORY_DOES_NOT_EXIST", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_FACTORY_NON_UPGRADEABLE_IS_DEPRECATED", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_FACTORY_ONLY_HOST", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_FACTORY_UNINITIALIZED", + "type": "error" + }, + { + "inputs": [], + "name": "SUPER_TOKEN_FACTORY_ZERO_ADDRESS", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + } + ], + "name": "CustomSuperTokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + } + ], + "name": "SuperTokenCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperToken", + "name": "tokenLogic", + "type": "address" + } + ], + "name": "SuperTokenLogicCreated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlyingToken", + "type": "address" + } + ], + "name": "computeCanonicalERC20WrapperAddress", + "outputs": [ + { + "internalType": "address", + "name": "superTokenAddress", + "type": "address" + }, + { + "internalType": "bool", + "name": "isDeployed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20WithTokenInfo", + "name": "_underlyingToken", + "type": "address" + } + ], + "name": "createCanonicalERC20Wrapper", + "outputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ERC20WithTokenInfo", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "enum ISuperTokenFactory.Upgradability", + "name": "upgradability", + "type": "uint8" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "name": "createERC20Wrapper", + "outputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "underlyingToken", + "type": "address" + }, + { + "internalType": "uint8", + "name": "underlyingDecimals", + "type": "uint8" + }, + { + "internalType": "enum ISuperTokenFactory.Upgradability", + "name": "upgradability", + "type": "uint8" + }, + { + "internalType": "string", + "name": "name", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol", + "type": "string" + } + ], + "name": "createERC20Wrapper", + "outputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_underlyingTokenAddress", + "type": "address" + } + ], + "name": "getCanonicalERC20Wrapper", + "outputs": [ + { + "internalType": "address", + "name": "superTokenAddress", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getHost", + "outputs": [ + { + "internalType": "address", + "name": "host", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSuperTokenLogic", + "outputs": [ + { + "internalType": "contract ISuperToken", + "name": "superToken", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "customSuperTokenProxy", + "type": "address" + } + ], + "name": "initializeCustomSuperToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ISuperfluid.json b/abi/ISuperfluid.json new file mode 100644 index 00000000..03d23faa --- /dev/null +++ b/abi/ISuperfluid.json @@ -0,0 +1,1122 @@ +[ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_code", + "type": "uint256" + } + ], + "name": "APP_RULE", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_AGREEMENT_ALREADY_REGISTERED", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_AGREEMENT_IS_NOT_REGISTERED", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_CANNOT_DOWNGRADE_TO_NON_UPGRADEABLE", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_INVALID_CONFIG_WORD", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_INVALID_OR_EXPIRED_SUPER_APP_REGISTRATION_KEY", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_MAX_256_AGREEMENTS", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_MUST_BE_CONTRACT", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_NON_UPGRADEABLE", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_NON_ZERO_LENGTH_PLACEHOLDER_CTX", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_NOT_A_SUPER_APP", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_NO_APP_REGISTRATION_PERMISSIONS", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_ONLY_GOVERNANCE", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_ONLY_LISTED_AGREEMENT", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_RECEIVER_IS_NOT_SUPER_APP", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_SENDER_IS_NOT_SUPER_APP", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_SUPER_APP_ALREADY_REGISTERED", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_SUPER_APP_IS_JAILED", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_UNAUTHORIZED_SUPER_APP_FACTORY", + "type": "error" + }, + { + "inputs": [], + "name": "HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "agreementType", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "code", + "type": "address" + } + ], + "name": "AgreementClassRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "agreementType", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "code", + "type": "address" + } + ], + "name": "AgreementClassUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + } + ], + "name": "AppRegistered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ISuperfluidGovernance", + "name": "oldGov", + "type": "address" + }, + { + "indexed": false, + "internalType": "contract ISuperfluidGovernance", + "name": "newGov", + "type": "address" + } + ], + "name": "GovernanceReplaced", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "reason", + "type": "uint256" + } + ], + "name": "Jail", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "contract ISuperTokenFactory", + "name": "newFactory", + "type": "address" + } + ], + "name": "SuperTokenFactoryUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "code", + "type": "address" + } + ], + "name": "SuperTokenLogicUpdated", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "bitmap", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "agreementType", + "type": "bytes32" + } + ], + "name": "addToAgreementClassesBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "newBitmap", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "targetApp", + "type": "address" + } + ], + "name": "allowCompositeApp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + }, + { + "internalType": "int256", + "name": "appCreditUsedDelta", + "type": "int256" + } + ], + "name": "appCallbackPop", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + }, + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "uint256", + "name": "appCreditGranted", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "appCreditUsed", + "type": "int256" + }, + { + "internalType": "contract ISuperfluidToken", + "name": "appCreditToken", + "type": "address" + } + ], + "name": "appCallbackPush", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "operationType", + "type": "uint32" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct ISuperfluid.Operation[]", + "name": "operations", + "type": "tuple[]" + } + ], + "name": "batchCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperAgreement", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + } + ], + "name": "callAgreement", + "outputs": [ + { + "internalType": "bytes", + "name": "returnedData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperAgreement", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "callAgreementWithContext", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "returnedData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + } + ], + "name": "callAppAction", + "outputs": [ + { + "internalType": "bytes", + "name": "returnedData", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "callAppActionWithContext", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "isTermination", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "callAppAfterCallback", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "bytes", + "name": "callData", + "type": "bytes" + }, + { + "internalType": "bool", + "name": "isTermination", + "type": "bool" + }, + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "callAppBeforeCallback", + "outputs": [ + { + "internalType": "bytes", + "name": "cbdata", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + }, + { + "internalType": "int256", + "name": "appCreditUsedMore", + "type": "int256" + } + ], + "name": "ctxUseCredit", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "decodeCtx", + "outputs": [ + { + "components": [ + { + "internalType": "uint8", + "name": "appCallbackLevel", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "callType", + "type": "uint8" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + }, + { + "internalType": "address", + "name": "msgSender", + "type": "address" + }, + { + "internalType": "bytes4", + "name": "agreementSelector", + "type": "bytes4" + }, + { + "internalType": "bytes", + "name": "userData", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "appCreditGranted", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "appCreditWantedDeprecated", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "appCreditUsed", + "type": "int256" + }, + { + "internalType": "address", + "name": "appAddress", + "type": "address" + }, + { + "internalType": "contract ISuperfluidToken", + "name": "appCreditToken", + "type": "address" + } + ], + "internalType": "struct ISuperfluid.Context", + "name": "context", + "type": "tuple" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "operationType", + "type": "uint32" + }, + { + "internalType": "address", + "name": "target", + "type": "address" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "internalType": "struct ISuperfluid.Operation[]", + "name": "operations", + "type": "tuple[]" + } + ], + "name": "forwardBatchCall", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "agreementType", + "type": "bytes32" + } + ], + "name": "getAgreementClass", + "outputs": [ + { + "internalType": "contract ISuperAgreement", + "name": "agreementClass", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + } + ], + "name": "getAppCallbackLevel", + "outputs": [ + { + "internalType": "uint8", + "name": "appCallbackLevel", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + } + ], + "name": "getAppManifest", + "outputs": [ + { + "internalType": "bool", + "name": "isSuperApp", + "type": "bool" + }, + { + "internalType": "bool", + "name": "isJailed", + "type": "bool" + }, + { + "internalType": "uint256", + "name": "noopMask", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getGovernance", + "outputs": [ + { + "internalType": "contract ISuperfluidGovernance", + "name": "governance", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNow", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSuperTokenFactory", + "outputs": [ + { + "internalType": "contract ISuperTokenFactory", + "name": "factory", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getSuperTokenFactoryLogic", + "outputs": [ + { + "internalType": "address", + "name": "logic", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperAgreement", + "name": "agreementClass", + "type": "address" + } + ], + "name": "isAgreementClassListed", + "outputs": [ + { + "internalType": "bool", + "name": "yes", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "agreementType", + "type": "bytes32" + } + ], + "name": "isAgreementTypeListed", + "outputs": [ + { + "internalType": "bool", + "name": "yes", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + } + ], + "name": "isApp", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + } + ], + "name": "isAppJailed", + "outputs": [ + { + "internalType": "bool", + "name": "isJail", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "contract ISuperApp", + "name": "targetApp", + "type": "address" + } + ], + "name": "isCompositeAppAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "isAppAllowed", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + } + ], + "name": "isCtxValid", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "ctx", + "type": "bytes" + }, + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "uint256", + "name": "reason", + "type": "uint256" + } + ], + "name": "jailApp", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "bitmap", + "type": "uint256" + } + ], + "name": "mapAgreementClasses", + "outputs": [ + { + "internalType": "contract ISuperAgreement[]", + "name": "agreementClasses", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperAgreement", + "name": "agreementClassLogic", + "type": "address" + } + ], + "name": "registerAgreementClass", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "configWord", + "type": "uint256" + } + ], + "name": "registerApp", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + }, + { + "internalType": "uint256", + "name": "configWord", + "type": "uint256" + } + ], + "name": "registerAppByFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "configWord", + "type": "uint256" + }, + { + "internalType": "string", + "name": "registrationKey", + "type": "string" + } + ], + "name": "registerAppWithKey", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "bitmap", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "agreementType", + "type": "bytes32" + } + ], + "name": "removeFromAgreementClassesBitmap", + "outputs": [ + { + "internalType": "uint256", + "name": "newBitmap", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluidGovernance", + "name": "newGov", + "type": "address" + } + ], + "name": "replaceGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperAgreement", + "name": "agreementClassLogic", + "type": "address" + } + ], + "name": "updateAgreementClass", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperTokenFactory", + "name": "newFactory", + "type": "address" + } + ], + "name": "updateSuperTokenFactory", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + } + ], + "name": "updateSuperTokenLogic", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ISuperfluidGovernance.json b/abi/ISuperfluidGovernance.json new file mode 100644 index 00000000..e1a165dd --- /dev/null +++ b/abi/ISuperfluidGovernance.json @@ -0,0 +1,236 @@ +[ + { + "inputs": [], + "name": "SF_GOV_ARRAYS_NOT_SAME_LENGTH", + "type": "error" + }, + { + "inputs": [], + "name": "SF_GOV_INVALID_LIQUIDATION_OR_PATRICIAN_PERIOD", + "type": "error" + }, + { + "inputs": [], + "name": "SF_GOV_MUST_BE_CONTRACT", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "contract ISuperToken[]", + "name": "tokens", + "type": "address[]" + } + ], + "name": "batchUpdateSuperTokenLogic", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "contract ISuperfluidToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "clearConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "contract ISuperfluidToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "getConfigAsAddress", + "outputs": [ + { + "internalType": "address", + "name": "value", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "contract ISuperfluidToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + } + ], + "name": "getConfigAsUint256", + "outputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + } + ], + "name": "registerAgreementClass", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "address", + "name": "newGov", + "type": "address" + } + ], + "name": "replaceGovernance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "contract ISuperfluidToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "value", + "type": "address" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "contract ISuperfluidToken", + "name": "superToken", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "key", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "setConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "address", + "name": "hostNewLogic", + "type": "address" + }, + { + "internalType": "address[]", + "name": "agreementClassNewLogics", + "type": "address[]" + }, + { + "internalType": "address", + "name": "superTokenFactoryNewLogic", + "type": "address" + } + ], + "name": "updateContracts", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ISuperfluidToken.json b/abi/ISuperfluidToken.json new file mode 100644 index 00000000..e4a5e0dc --- /dev/null +++ b/abi/ISuperfluidToken.json @@ -0,0 +1,673 @@ +[ + { + "inputs": [], + "name": "SF_TOKEN_AGREEMENT_ALREADY_EXISTS", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_AGREEMENT_DOES_NOT_EXIST", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_BURN_INSUFFICIENT_BALANCE", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_MOVE_INSUFFICIENT_BALANCE", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_ONLY_HOST", + "type": "error" + }, + { + "inputs": [], + "name": "SF_TOKEN_ONLY_LISTED_AGREEMENT", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "AgreementCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "penaltyAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "rewardAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + } + ], + "name": "AgreementLiquidated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "liquidatorAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "penaltyAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "bondAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bailoutAmount", + "type": "uint256" + } + ], + "name": "AgreementLiquidatedBy", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "liquidatorAccount", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "targetAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "rewardAmountReceiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "int256", + "name": "targetAccountBalanceDelta", + "type": "int256" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "liquidationTypeData", + "type": "bytes" + } + ], + "name": "AgreementLiquidatedV2", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "slotId", + "type": "uint256" + } + ], + "name": "AgreementStateUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + } + ], + "name": "AgreementTerminated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "AgreementUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "bailoutAccount", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "bailoutAmount", + "type": "uint256" + } + ], + "name": "Bailout", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "createAgreement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getAccountActiveAgreements", + "outputs": [ + { + "internalType": "contract ISuperAgreement[]", + "name": "activeAgreements", + "type": "address[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "dataLength", + "type": "uint256" + } + ], + "name": "getAgreementData", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "agreementClass", + "type": "address" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "slotId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "dataLength", + "type": "uint256" + } + ], + "name": "getAgreementStateSlot", + "outputs": [ + { + "internalType": "bytes32[]", + "name": "slotData", + "type": "bytes32[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getHost", + "outputs": [ + { + "internalType": "address", + "name": "host", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "isAccountCritical", + "outputs": [ + { + "internalType": "bool", + "name": "isCritical", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isAccountCriticalNow", + "outputs": [ + { + "internalType": "bool", + "name": "isCritical", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "isAccountSolvent", + "outputs": [ + { + "internalType": "bool", + "name": "isSolvent", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isAccountSolventNow", + "outputs": [ + { + "internalType": "bool", + "name": "isSolvent", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "liquidationTypeData", + "type": "bytes" + }, + { + "internalType": "address", + "name": "liquidatorAccount", + "type": "address" + }, + { + "internalType": "bool", + "name": "useDefaultRewardAccount", + "type": "bool" + }, + { + "internalType": "address", + "name": "targetAccount", + "type": "address" + }, + { + "internalType": "uint256", + "name": "rewardAmount", + "type": "uint256" + }, + { + "internalType": "int256", + "name": "targetAccountBalanceDelta", + "type": "int256" + } + ], + "name": "makeLiquidationPayoutsV2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "name": "realtimeBalanceOf", + "outputs": [ + { + "internalType": "int256", + "name": "availableBalance", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "realtimeBalanceOfNow", + "outputs": [ + { + "internalType": "int256", + "name": "availableBalance", + "type": "int256" + }, + { + "internalType": "uint256", + "name": "deposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "owedDeposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "timestamp", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "int256", + "name": "delta", + "type": "int256" + } + ], + "name": "settleBalance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "dataLength", + "type": "uint256" + } + ], + "name": "terminateAgreement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "id", + "type": "bytes32" + }, + { + "internalType": "bytes32[]", + "name": "data", + "type": "bytes32[]" + } + ], + "name": "updateAgreementData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "slotId", + "type": "uint256" + }, + { + "internalType": "bytes32[]", + "name": "slotData", + "type": "bytes32[]" + } + ], + "name": "updateAgreementStateSlot", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/MockSuperAppRegister.json b/abi/MockSuperAppRegister.json new file mode 100644 index 00000000..65586d78 --- /dev/null +++ b/abi/MockSuperAppRegister.json @@ -0,0 +1,39 @@ +[ + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "_host", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "host", + "outputs": [ + { + "internalType": "contract ISuperfluid", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperApp", + "name": "app", + "type": "address" + } + ], + "name": "register", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/Multisend.json b/abi/Multisend.json new file mode 100644 index 00000000..a26e6f26 --- /dev/null +++ b/abi/Multisend.json @@ -0,0 +1,26 @@ +[ + { + "inputs": [ + { + "internalType": "address[]", + "name": "tos", + "type": "address[]" + }, + { + "internalType": "bytes[]", + "name": "datas", + "type": "bytes[]" + } + ], + "name": "multisend", + "outputs": [ + { + "internalType": "bytes[]", + "name": "results", + "type": "bytes[]" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/ReceivableFactoringPoolProcessor.json b/abi/ReceivableFactoringPoolProcessor.json new file mode 100644 index 00000000..edc22cc4 --- /dev/null +++ b/abi/ReceivableFactoringPoolProcessor.json @@ -0,0 +1,71 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "netAmountToBorrower", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "receivableTokenId", + "type": "uint256" + } + ], + "name": "DrawdownMadeWithReceivable", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "contract IReceivablePool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/ReceivableFactoringPoolProcessorStorage.json b/abi/ReceivableFactoringPoolProcessorStorage.json new file mode 100644 index 00000000..f88dcc3d --- /dev/null +++ b/abi/ReceivableFactoringPoolProcessorStorage.json @@ -0,0 +1,15 @@ +[ + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "contract IReceivablePool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/ReceivableFactoringPoolStorageV2.json b/abi/ReceivableFactoringPoolStorageV2.json new file mode 100644 index 00000000..507923f0 --- /dev/null +++ b/abi/ReceivableFactoringPoolStorageV2.json @@ -0,0 +1,44 @@ +[ + { + "inputs": [], + "name": "processor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "receivableInfoMapping", + "outputs": [ + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "uint96", + "name": "receivableAmount", + "type": "uint96" + }, + { + "internalType": "uint256", + "name": "receivableParam", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/ReceivableFactoringPoolV2.json b/abi/ReceivableFactoringPoolV2.json new file mode 100644 index 00000000..512fd91c --- /dev/null +++ b/abi/ReceivableFactoringPoolV2.json @@ -0,0 +1,1505 @@ +[ + { + "inputs": [], + "name": "creditExpiredDueToFirstDrawdownTooLate", + "type": "error" + }, + { + "inputs": [], + "name": "creditExpiredDueToMaturity", + "type": "error" + }, + { + "inputs": [], + "name": "creditLineAlreadyExists", + "type": "error" + }, + { + "inputs": [], + "name": "creditLineExceeded", + "type": "error" + }, + { + "inputs": [], + "name": "creditLineNotInGoodStandingState", + "type": "error" + }, + { + "inputs": [], + "name": "creditLineNotInStateForDrawdown", + "type": "error" + }, + { + "inputs": [], + "name": "creditLineNotInStateForMakingPayment", + "type": "error" + }, + { + "inputs": [], + "name": "creditLineOutstanding", + "type": "error" + }, + { + "inputs": [], + "name": "defaultHasAlreadyBeenTriggered", + "type": "error" + }, + { + "inputs": [], + "name": "defaultTriggeredTooEarly", + "type": "error" + }, + { + "inputs": [], + "name": "drawdownFunctionUsedInsteadofDrawdownWithReceivable", + "type": "error" + }, + { + "inputs": [], + "name": "evaluationAgentServiceAccountRequired", + "type": "error" + }, + { + "inputs": [], + "name": "exceededPoolLiquidityCap", + "type": "error" + }, + { + "inputs": [], + "name": "greaterThanMaxCreditLine", + "type": "error" + }, + { + "inputs": [], + "name": "insufficientReceivableAmount", + "type": "error" + }, + { + "inputs": [], + "name": "notProcessor", + "type": "error" + }, + { + "inputs": [], + "name": "onlyBorrowerOrEACanReduceCreditLine", + "type": "error" + }, + { + "inputs": [], + "name": "paymentDetectionServiceAccountRequired", + "type": "error" + }, + { + "inputs": [], + "name": "permissionDeniedNotLender", + "type": "error" + }, + { + "inputs": [], + "name": "poolIsNotOn", + "type": "error" + }, + { + "inputs": [], + "name": "poolOperatorRequired", + "type": "error" + }, + { + "inputs": [], + "name": "protocolIsPaused", + "type": "error" + }, + { + "inputs": [], + "name": "receivableAssetMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "receivableAssetParamMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "requestedCreditWithZeroDuration", + "type": "error" + }, + { + "inputs": [], + "name": "sameValue", + "type": "error" + }, + { + "inputs": [], + "name": "settlementTooSoon", + "type": "error" + }, + { + "inputs": [], + "name": "unsupportedReceivableAsset", + "type": "error" + }, + { + "inputs": [], + "name": "withdrawTooSoon", + "type": "error" + }, + { + "inputs": [], + "name": "withdrawnAmountHigherThanBalance", + "type": "error" + }, + { + "inputs": [], + "name": "zeroAddressProvided", + "type": "error" + }, + { + "inputs": [], + "name": "zeroAmountProvided", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "AddApprovedLender", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newDueDate", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "BillRefreshed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "creditLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "intervalInDays", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingPeriods", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aprInBps", + "type": "uint256" + } + ], + "name": "CreditApproved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "creditLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "aprInBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "payPeriodInDays", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingPeriods", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "CreditInitiated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "oldCreditLimit", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newCreditLimit", + "type": "uint256" + } + ], + "name": "CreditLineChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "by", + "type": "address" + }, + { + "indexed": false, + "internalType": "enum BaseCreditPool.CreditLineClosureReason", + "name": "reasonCode", + "type": "uint8" + } + ], + "name": "CreditLineClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "numOfPeriods", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "remainingPeriods", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "CreditLineExtended", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "losses", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "DefaultTriggered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "netAmountToBorrower", + "type": "uint256" + } + ], + "name": "DrawdownMade", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "ExtraFundsDispersed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "LiquidityDeposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "assetAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "shareAmount", + "type": "uint256" + } + ], + "name": "LiquidityWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "lossesDistributed", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "updatedPoolValue", + "type": "uint256" + } + ], + "name": "LossesDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalDue", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "unbilledPrincipal", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "PaymentMade", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newPoolConfig", + "type": "address" + } + ], + "name": "PoolConfigChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "underlyingToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "poolToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "humaConfig", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "feeManager", + "type": "address" + } + ], + "name": "PoolCoreDataChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "PoolDisabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "PoolEnabled", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "lender", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "by", + "type": "address" + } + ], + "name": "RemoveApprovedLender", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "lender", + "type": "address" + } + ], + "name": "addApprovedLender", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "intervalInDays", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "remainingPeriods", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "aprInBps", + "type": "uint256" + } + ], + "name": "approveCredit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "creditLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "intervalInDays", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "remainingPeriods", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "aprInBps", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receivableParam", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "receivableAmount", + "type": "uint256" + } + ], + "name": "approveCredit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "newCreditLimit", + "type": "uint256" + } + ], + "name": "changeCreditLine", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "creditRecordMapping", + "outputs": [ + { + "components": [ + { + "internalType": "uint96", + "name": "unbilledPrincipal", + "type": "uint96" + }, + { + "internalType": "uint64", + "name": "dueDate", + "type": "uint64" + }, + { + "internalType": "int96", + "name": "correction", + "type": "int96" + }, + { + "internalType": "uint96", + "name": "totalDue", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "feesAndInterestDue", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "missedPeriods", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "remainingPeriods", + "type": "uint16" + }, + { + "internalType": "enum BaseStructs.CreditState", + "name": "state", + "type": "uint8" + } + ], + "internalType": "struct BaseStructs.CreditRecord", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "creditRecordStaticMapping", + "outputs": [ + { + "components": [ + { + "internalType": "uint96", + "name": "creditLimit", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "aprInBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "intervalInDays", + "type": "uint16" + }, + { + "internalType": "uint96", + "name": "defaultAmount", + "type": "uint96" + } + ], + "internalType": "struct BaseStructs.CreditRecordStatic", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "disablePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "drawdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "drawdown4Processor", + "outputs": [ + { + "internalType": "uint256", + "name": "netAmountToBorrower", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "enablePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "numOfPeriods", + "type": "uint256" + } + ], + "name": "extendCreditLineDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getCoreData", + "outputs": [ + { + "internalType": "address", + "name": "underlyingToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "poolToken_", + "type": "address" + }, + { + "internalType": "address", + "name": "humaConfig_", + "type": "address" + }, + { + "internalType": "address", + "name": "feeManager_", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolConfigAddr", + "type": "address" + }, + { + "internalType": "address", + "name": "processorAddr", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolConfigAddr", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + } + ], + "name": "isApproved", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "isApprovedLender", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + } + ], + "name": "isDefaultReady", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + } + ], + "name": "isLate", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "isPoolOn", + "outputs": [ + { + "internalType": "bool", + "name": "status", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "lastDepositTime", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "makeInitialDeposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "makePayment", + "outputs": [ + { + "internalType": "uint256", + "name": "amountPaid", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "paidoff", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "makePayment4Processor", + "outputs": [ + { + "internalType": "uint256", + "name": "amountPaid", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "paidoff", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "onERC721Received", + "outputs": [ + { + "internalType": "bytes4", + "name": "", + "type": "bytes4" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "poolConfig", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "processor", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "receivableInfoMapping", + "outputs": [ + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "uint96", + "name": "receivableAmount", + "type": "uint96" + }, + { + "internalType": "uint256", + "name": "receivableParam", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + } + ], + "name": "refreshAccount", + "outputs": [ + { + "components": [ + { + "internalType": "uint96", + "name": "unbilledPrincipal", + "type": "uint96" + }, + { + "internalType": "uint64", + "name": "dueDate", + "type": "uint64" + }, + { + "internalType": "int96", + "name": "correction", + "type": "int96" + }, + { + "internalType": "uint96", + "name": "totalDue", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "feesAndInterestDue", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "missedPeriods", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "remainingPeriods", + "type": "uint16" + }, + { + "internalType": "enum BaseStructs.CreditState", + "name": "state", + "type": "uint8" + } + ], + "internalType": "struct BaseStructs.CreditRecord", + "name": "cr", + "type": "tuple" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "lender", + "type": "address" + } + ], + "name": "removeApprovedLender", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "creditLimit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "intervalInDays", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numOfPayments", + "type": "uint256" + } + ], + "name": "requestCredit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "poolConfigAddr", + "type": "address" + } + ], + "name": "setPoolConfig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "settlement4Processor", + "outputs": [ + { + "internalType": "uint256", + "name": "amountPaid", + "type": "uint256" + }, + { + "internalType": "bool", + "name": "paidoff", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "totalPoolValue", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + } + ], + "name": "triggerDefault", + "outputs": [ + { + "internalType": "uint256", + "name": "losses", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "updateCoreData", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receivableParam", + "type": "uint256" + } + ], + "name": "validateReceivableAsset", + "outputs": [], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "withdrawAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/SuperAppBase.json b/abi/SuperAppBase.json new file mode 100644 index 00000000..cdc4187d --- /dev/null +++ b/abi/SuperAppBase.json @@ -0,0 +1,251 @@ +[ + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "afterAgreementCreated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "afterAgreementTerminated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "afterAgreementUpdated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "beforeAgreementCreated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "beforeAgreementTerminated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "beforeAgreementUpdated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/SuperfluidFeeManager.json b/abi/SuperfluidFeeManager.json new file mode 100644 index 00000000..c59fee1a --- /dev/null +++ b/abi/SuperfluidFeeManager.json @@ -0,0 +1,513 @@ +[ + { + "inputs": [], + "name": "borrowingAmountLessThanPlatformFees", + "type": "error" + }, + { + "inputs": [], + "name": "minPrincipalPaymentRateSettingTooHigh", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "frontLoandingFeeFlat", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "frontLoadingFeeBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lateFeeFlat", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "lateFeeBps", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "membershipFee", + "type": "uint256" + } + ], + "name": "FeeChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "minPrincipalRateInBps", + "type": "uint256" + } + ], + "name": "MinPrincipalRateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dueDate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "aprInBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "calcCorrection", + "outputs": [ + { + "internalType": "uint256", + "name": "correction", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "calcFrontLoadingFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fees", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "dueDate", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalDue", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalBalance", + "type": "uint256" + } + ], + "name": "calcLateFee", + "outputs": [ + { + "internalType": "uint256", + "name": "fees", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "deleteTempInterest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + } + ], + "name": "distBorrowingAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "amtToBorrower", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "platformFees", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "frontLoadingFeeBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "frontLoadingFeeFlat", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "uint96", + "name": "unbilledPrincipal", + "type": "uint96" + }, + { + "internalType": "uint64", + "name": "dueDate", + "type": "uint64" + }, + { + "internalType": "int96", + "name": "correction", + "type": "int96" + }, + { + "internalType": "uint96", + "name": "totalDue", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "feesAndInterestDue", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "missedPeriods", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "remainingPeriods", + "type": "uint16" + }, + { + "internalType": "enum BaseStructs.CreditState", + "name": "state", + "type": "uint8" + } + ], + "internalType": "struct BaseStructs.CreditRecord", + "name": "_cr", + "type": "tuple" + }, + { + "components": [ + { + "internalType": "uint96", + "name": "creditLimit", + "type": "uint96" + }, + { + "internalType": "uint16", + "name": "aprInBps", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "intervalInDays", + "type": "uint16" + }, + { + "internalType": "uint96", + "name": "defaultAmount", + "type": "uint96" + } + ], + "internalType": "struct BaseStructs.CreditRecordStatic", + "name": "_crStatic", + "type": "tuple" + } + ], + "name": "getDueInfo", + "outputs": [ + { + "internalType": "uint256", + "name": "periodsPassed", + "type": "uint256" + }, + { + "internalType": "uint96", + "name": "feesAndInterestDue", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "totalDue", + "type": "uint96" + }, + { + "internalType": "uint96", + "name": "unbilledPrincipal", + "type": "uint96" + }, + { + "internalType": "int96", + "name": "totalCharges", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getFees", + "outputs": [ + { + "internalType": "uint256", + "name": "_frontLoadingFeeFlat", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_frontLoadingFeeBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lateFeeFlat", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lateFeeBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_membershipFee", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lateFeeBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lateFeeFlat", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "membershipFee", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "minPrincipalRateInBps", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_frontLoadingFeeFlat", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_frontLoadingFeeBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lateFeeFlat", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_lateFeeBps", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_membershipFee", + "type": "uint256" + } + ], + "name": "setFees", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_minPrincipalRateInBps", + "type": "uint256" + } + ], + "name": "setMinPrincipalRateInBps", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_tempInterest", + "type": "uint256" + } + ], + "name": "setTempInterest", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "tempInterest", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/SuperfluidPoolProcessor.json b/abi/SuperfluidPoolProcessor.json new file mode 100644 index 00000000..f4f0a073 --- /dev/null +++ b/abi/SuperfluidPoolProcessor.json @@ -0,0 +1,796 @@ +[ + { + "inputs": [], + "name": "allowanceTooLow", + "type": "error" + }, + { + "inputs": [], + "name": "borrowerMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "creditLineNotInGoodStandingState", + "type": "error" + }, + { + "inputs": [], + "name": "durationTooLong", + "type": "error" + }, + { + "inputs": [], + "name": "flowIsNotTerminated", + "type": "error" + }, + { + "inputs": [], + "name": "flowKeyMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "insufficientReceivableAmount", + "type": "error" + }, + { + "inputs": [], + "name": "invalidFlowrate", + "type": "error" + }, + { + "inputs": [], + "name": "invalidSuperfluidAction", + "type": "error" + }, + { + "inputs": [], + "name": "invalidSuperfluidCallback", + "type": "error" + }, + { + "inputs": [], + "name": "receivableAssetMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "receivableIdMismatch", + "type": "error" + }, + { + "inputs": [], + "name": "settlementTooSoon", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "netAmountToBorrower", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "receivableTokenId", + "type": "uint256" + } + ], + "name": "DrawdownMadeWithReceivable", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "flowKey", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + } + ], + "name": "FlowIsTerminated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + } + ], + "name": "NotGettingEnoughAllowance", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "readyTime", + "type": "uint256" + } + ], + "name": "ReadyToSettlement", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "flowKey", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + } + ], + "name": "ReceivableCleared", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "flowKey", + "type": "bytes32" + } + ], + "name": "ReceivableFlowKey", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "flowKey", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + } + ], + "name": "SettlementMade", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "_agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_ctx", + "type": "bytes" + } + ], + "name": "afterAgreementCreated", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "_superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_ctx", + "type": "bytes" + } + ], + "name": "afterAgreementTerminated", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "_superToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_agreementClass", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "_agreementId", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "_ctx", + "type": "bytes" + } + ], + "name": "afterAgreementUpdated", + "outputs": [ + { + "internalType": "bytes", + "name": "newCtx", + "type": "bytes" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "beforeAgreementCreated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "beforeAgreementTerminated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "name": "beforeAgreementUpdated", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "cfa", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "flowKey", + "type": "bytes32" + } + ], + "name": "flowEndMapping", + "outputs": [ + { + "internalType": "uint256", + "name": "endTime", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "host", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_pool", + "type": "address" + }, + { + "internalType": "address", + "name": "_host", + "type": "address" + }, + { + "internalType": "address", + "name": "_cfa", + "type": "address" + }, + { + "internalType": "address", + "name": "_tradableStream", + "type": "address" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint256", + "name": "borrowAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "bytes", + "name": "dataForMintTo", + "type": "bytes" + } + ], + "name": "mintAndDrawdown", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "flowKey", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + } + ], + "name": "onTerminatedFlow", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pool", + "outputs": [ + { + "internalType": "contract IReceivablePool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + } + ], + "name": "settlement", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + } + ], + "name": "streamInfoMapping", + "outputs": [ + { + "components": [ + { + "internalType": "address", + "name": "borrower", + "type": "address" + }, + { + "internalType": "uint96", + "name": "flowrate", + "type": "uint96" + }, + { + "internalType": "uint64", + "name": "lastStartTime", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "endTime", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "receivedFlowAmount", + "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "flowKey", + "type": "bytes32" + } + ], + "internalType": "struct SuperfluidPoolProcessorStorage.StreamInfo", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tradableStream", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "receivableAsset", + "type": "address" + }, + { + "internalType": "uint256", + "name": "receivableId", + "type": "uint256" + } + ], + "name": "tryTransferAllowance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/SuperfluidPoolProcessorStorage.json b/abi/SuperfluidPoolProcessorStorage.json new file mode 100644 index 00000000..5c578c1b --- /dev/null +++ b/abi/SuperfluidPoolProcessorStorage.json @@ -0,0 +1,41 @@ +[ + { + "inputs": [], + "name": "cfa", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "host", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "tradableStream", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/TestToken.json b/abi/TestToken.json index 313ffd5d..ce6cbefc 100644 --- a/abi/TestToken.json +++ b/abi/TestToken.json @@ -54,6 +54,19 @@ "name": "Transfer", "type": "event" }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -257,6 +270,68 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "permit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { diff --git a/abi/TokenInfo.json b/abi/TokenInfo.json new file mode 100644 index 00000000..175afca5 --- /dev/null +++ b/abi/TokenInfo.json @@ -0,0 +1,41 @@ +[ + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/TradableStream.json b/abi/TradableStream.json new file mode 100644 index 00000000..b6868e75 --- /dev/null +++ b/abi/TradableStream.json @@ -0,0 +1,895 @@ +[ + { + "inputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [], + "name": "AuthorizationExpired", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidAuthorization", + "type": "error" + }, + { + "inputs": [], + "name": "invalidFlowrate", + "type": "error" + }, + { + "inputs": [], + "name": "newReceiverSameToOrigin", + "type": "error" + }, + { + "inputs": [], + "name": "notEnoughAvailableFlowrate", + "type": "error" + }, + { + "inputs": [], + "name": "notTradableStreamOwner", + "type": "error" + }, + { + "inputs": [], + "name": "tradableStreamNotExisting", + "type": "error" + }, + { + "inputs": [], + "name": "tradableStreamNotMatured", + "type": "error" + }, + { + "inputs": [], + "name": "zeroAddressProvided", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "refundAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "sendAmount", + "type": "uint256" + } + ], + "name": "RefundExtraToken", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "matureAt", + "type": "uint256" + } + ], + "name": "TradableStreamStarted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + } + ], + "name": "TradableStreamTerminated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "inputs": [], + "name": "MINTTO_WITH_AUTHORIZATION_TYPEHASH", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "_tradedStream", + "outputs": [ + { + "internalType": "int96", + "name": "", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "cfaV1", + "outputs": [ + { + "internalType": "contract ISuperfluid", + "name": "host", + "type": "address" + }, + { + "internalType": "contract IConstantFlowAgreementV1", + "name": "cfa", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "domainSeparator", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getApproved", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "getTradableStreamData", + "outputs": [ + { + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "started", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "until", + "type": "uint256" + }, + { + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowrate", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "hasMatured", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "operator", + "type": "address" + } + ], + "name": "isApprovedForAll", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "maturesAt", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "metadatas", + "outputs": [ + { + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "started", + "type": "uint256" + }, + { + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowrate", + "type": "int96" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowrate", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "durationInSeconds", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "currentOwner", + "type": "address" + }, + { + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "address", + "name": "origin", + "type": "address" + }, + { + "internalType": "int96", + "name": "flowrate", + "type": "int96" + }, + { + "internalType": "uint256", + "name": "durationInSeconds", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "mintToWithAuthorization", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "nextId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "ownerOf", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "remainingValue", + "outputs": [ + { + "internalType": "contract ISuperToken", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "internalType": "bytes", + "name": "data", + "type": "bytes" + } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes4", + "name": "interfaceId", + "type": "bytes4" + } + ], + "name": "supportsInterface", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "tokenURI", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/contracts/BaseCreditPool.sol b/contracts/BaseCreditPool.sol index a397c843..466dc89b 100644 --- a/contracts/BaseCreditPool.sol +++ b/contracts/BaseCreditPool.sol @@ -7,8 +7,6 @@ import "./BasePool.sol"; import "./BaseCreditPoolStorage.sol"; import "./Errors.sol"; -import "hardhat/console.sol"; - /** * @notice BaseCreditPool is the basic form of a complete pool in Huma Protocol. * All production pools are expected to be instances of BaseCreditPool or diff --git a/contracts/BaseFeeManager.sol b/contracts/BaseFeeManager.sol index 5472a6ff..e0f7eefd 100644 --- a/contracts/BaseFeeManager.sol +++ b/contracts/BaseFeeManager.sol @@ -16,11 +16,11 @@ contract BaseFeeManager is IFeeManager, Ownable { using BS for BS.CreditRecord; // Divider to convert BPS to percentage - uint256 private constant HUNDRED_PERCENT_IN_BPS = 10000; + uint256 internal constant HUNDRED_PERCENT_IN_BPS = 10000; // Divider to get monthly interest rate from APR BPS. 10000 * 12 - uint256 private constant SECONDS_IN_A_YEAR = 365 days; - uint256 private constant SECONDS_IN_A_DAY = 1 days; - uint256 private constant MAX_PERIODS = 360; // 30 years monthly loan + uint256 internal constant SECONDS_IN_A_YEAR = 365 days; + uint256 internal constant SECONDS_IN_A_DAY = 1 days; + uint256 internal constant MAX_PERIODS = 360; // 30 years monthly loan /// Part of platform fee, charged as a flat amount when a borrow happens uint256 public frontLoadingFeeFlat; @@ -110,7 +110,7 @@ contract BaseFeeManager is IFeeManager, Ownable { uint256 dueDate, uint256 aprInBps, uint256 amount - ) external view virtual override returns (uint256 correction) { + ) public view virtual override returns (uint256 correction) { // rounding to days uint256 remainingTime = dueDate - block.timestamp; @@ -163,6 +163,7 @@ contract BaseFeeManager is IFeeManager, Ownable { function distBorrowingAmount(uint256 borrowAmount) external view + virtual returns (uint256 amtToBorrower, uint256 platformFees) { // Calculate platform fee, which includes protocol fee and pool fee diff --git a/contracts/BasePool.sol b/contracts/BasePool.sol index 5c7d7ca9..ae3e8c42 100644 --- a/contracts/BasePool.sol +++ b/contracts/BasePool.sol @@ -48,7 +48,11 @@ abstract contract BasePool is Initializable, BasePoolStorage, ILiquidityProvider _disableInitializers(); } - function initialize(address poolConfigAddr) external initializer { + function initialize(address poolConfigAddr) public initializer { + _baseInitialize(poolConfigAddr); + } + + function _baseInitialize(address poolConfigAddr) internal onlyInitializing { _poolConfig = BasePoolConfig(poolConfigAddr); _updateCoreData(); diff --git a/contracts/BasePoolConfig.sol b/contracts/BasePoolConfig.sol index 2cd0108e..c922af1d 100644 --- a/contracts/BasePoolConfig.sol +++ b/contracts/BasePoolConfig.sol @@ -150,7 +150,7 @@ contract BasePoolConfig is Ownable, Initializable { address _poolToken, address _humaConfig, address _feeManager - ) external onlyOwner initializer { + ) public onlyOwner initializer { poolName = _poolName; if (_poolToken == address(0)) revert Errors.zeroAddressProvided(); if (_humaConfig == address(0)) revert Errors.zeroAddressProvided(); diff --git a/contracts/Errors.sol b/contracts/Errors.sol index 4300ce0c..b0a08def 100644 --- a/contracts/Errors.sol +++ b/contracts/Errors.sol @@ -9,6 +9,9 @@ contract Errors { error amountTooLow(); // 0x5b05bfbf error invalidBasisPointHigherThan10000(); // 0x07982d85 error withdrawnAmountHigherThanBalance(); // 0x477c0ab2 + error allowanceTooLow(); // 0xcd8ef369 + error AuthorizationExpired(); // 0x0f05f5bf + error InvalidAuthorization(); // 0x2ce87eeb // security error permissionDeniedNotAdmin(); // 0xf2c5b6a7 @@ -27,12 +30,13 @@ contract Errors { error notPool(); // 0x26d29bbf error drawdownFunctionUsedInsteadofDrawdownWithReceivable(); // 0x7e737537 error notNFTOwner(); // 0x091a5762 + error notProcessor(); // 0x90409ca1 // system config error defaultGracePeriodLessThanMinAllowed(); // 0xa733ff9c error treasuryFeeHighThanUpperLimit(); // 0x39cda0d1 error alreadyAnOperator(); // 0x75cea0fc - error alreadyAPauser(); // 0xfbca9e38 + error alreadyAPauser(); // 0x9f694c22 error alreadyPoolAdmin(); // 0x7bb356e2 // fee config @@ -63,7 +67,7 @@ contract Errors { error creditLineNotInApprovedState(); // 0xfc91a989 error paymentIdNotUnderReview(); // 0xd1696aaa error creditLineTooHigh(); // 0x552b8377 - error creditLineOutstanding(); // 0x2901939a + error creditLineOutstanding(); // 0xc64e338c // pool operation error exceededPoolLiquidityCap(); // 0x5642ebd4 @@ -74,7 +78,23 @@ contract Errors { error borrowingAmountLessThanPlatformFees(); // 0x97fde118 error withdrawTooSoon(); // 0x67982472 error paymentAlreadyProcessed(); // 0xfd6754cf + error settlementTooSoon(); // 0x0453e75e + error receivableIdMismatch(); // 0x97be2b67 error defaultTriggeredTooEarly(); // 0x7872424e error defaultHasAlreadyBeenTriggered(); // 0xeb8d2ccc + + // superfluid + error durationTooLong(); // 0xf1dd53a8 + error invalidFlowrate(); // 0xd06a9328 + error borrowerMismatch(); // 0x27d3e640 + error flowKeyMismatch(); // 0x29d5a5f3 + error flowIsNotTerminated(); // 0xe9c5922f + error invalidSuperfluidCallback(); // 0xd2747f83 + error invalidSuperfluidAction(); // 0x2f2cd9e9 + error notTradableStreamOwner(); // 0x5709a724 + error tradableStreamNotMatured(); // 0xa42ebb88 + error tradableStreamNotExisting(); // 0xb78e2a5b + error notEnoughAvailableFlowrate(); // 0x9c808ab8 + error newReceiverSameToOrigin(); // 0x6d79ce50 } diff --git a/contracts/ReceivableFactoringPoolProcessor.sol b/contracts/ReceivableFactoringPoolProcessor.sol new file mode 100644 index 00000000..164c6104 --- /dev/null +++ b/contracts/ReceivableFactoringPoolProcessor.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; +import "./ReceivableFactoringPoolProcessorStorage.sol"; + +abstract contract ReceivableFactoringPoolProcessor is + Initializable, + ReceivableFactoringPoolProcessorStorage +{ + uint256 internal constant HUNDRED_PERCENT_IN_BPS = 10000; + uint256 internal constant SECONDS_IN_A_DAY = 1 days; + uint256 internal constant SECONDS_IN_A_YEAR = 365 days; + + event DrawdownMadeWithReceivable( + address pool, + address indexed borrower, + uint256 borrowAmount, + uint256 netAmountToBorrower, + address receivableAsset, + uint256 receivableTokenId + ); + + constructor() { + _disableInitializers(); + } + + function _baseInitialize(address poolAddr) internal onlyInitializing { + pool = IReceivablePool(poolAddr); + } +} diff --git a/contracts/ReceivableFactoringPoolProcessorStorage.sol b/contracts/ReceivableFactoringPoolProcessorStorage.sol new file mode 100644 index 00000000..011964b4 --- /dev/null +++ b/contracts/ReceivableFactoringPoolProcessorStorage.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import "./interfaces/IReceivablePool.sol"; + +contract ReceivableFactoringPoolProcessorStorage { + IReceivablePool public pool; + + uint256[100] private __gap; +} diff --git a/contracts/ReceivableFactoringPoolStorageV2.sol b/contracts/ReceivableFactoringPoolStorageV2.sol new file mode 100644 index 00000000..780720ef --- /dev/null +++ b/contracts/ReceivableFactoringPoolStorageV2.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import {BaseStructs as BS} from "./libraries/BaseStructs.sol"; + +contract ReceivableFactoringPoolStorageV2 { + address public processor; + + /// mapping from wallet address to the receivable supplied by this wallet + mapping(address => BS.ReceivableInfo) public receivableInfoMapping; + + uint256[100] private __gap; +} diff --git a/contracts/ReceivableFactoringPoolV2.sol b/contracts/ReceivableFactoringPoolV2.sol new file mode 100644 index 00000000..d806bb21 --- /dev/null +++ b/contracts/ReceivableFactoringPoolV2.sol @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import {IERC721Receiver} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import {ERC165Checker} from "@openzeppelin/contracts/utils/introspection/ERC165Checker.sol"; + +import {ReceivableFactoringPoolStorageV2} from "./ReceivableFactoringPoolStorageV2.sol"; +import "./BaseCreditPool.sol"; +import {Errors} from "./Errors.sol"; + +/** + * ReceivableFactoringPoolV2 allows a processor to drawdown, make payment on behalf of the borrower. + * These functions are important for Huma to work with stream systems such as Superfluid. + */ +contract ReceivableFactoringPoolV2 is + BaseCreditPool, + ReceivableFactoringPoolStorageV2, + IERC721Receiver +{ + using ERC165Checker for address; + using SafeERC20 for IERC20; + + event ExtraFundsDispersed(address indexed receiver, uint256 amount); + + function initialize(address poolConfigAddr, address processorAddr) external initializer { + super._baseInitialize(poolConfigAddr); + processor = processorAddr; + } + + function onERC721Received( + address, /*operator*/ + address, /*from*/ + uint256, /*tokenId*/ + bytes calldata /*data*/ + ) external virtual override returns (bytes4) { + return this.onERC721Received.selector; + } + + /** + * @notice After the EA (EvalutionAgent) has approved a factoring, it calls this function + * to record the approval on chain and mark as factoring as approved, which will enable + * the borrower to drawdown (borrow) from the approved credit. + * @param borrower the borrower address + * @param creditLimit the limit of the credit + * @param receivableAsset the receivable asset used for this credit + * @param receivableParam additional parameter of the receivable asset, e.g. NFT tokenid + * @param receivableAmount amount of the receivable asset + * @param intervalInDays time interval for each payback in units of days + * @param remainingPeriods the number of pay periods for this credit + * @dev Only Evaluation Agents for this contract can call this function. + */ + function approveCredit( + address borrower, + uint256 creditLimit, + uint256 intervalInDays, + uint256 remainingPeriods, + uint256 aprInBps, + address receivableAsset, + uint256 receivableParam, + uint256 receivableAmount + ) external virtual { + onlyEAServiceAccount(); + + _checkReceivableRequirement(creditLimit, receivableAmount); + + // Populates fields related to receivable + if (receivableAsset == address(0)) revert Errors.zeroAddressProvided(); + + _setReceivableInfo(borrower, receivableAsset, receivableParam, receivableAmount); + + // Pool status and data validation happens within initiate(). + _initiateCredit(borrower, creditLimit, aprInBps, intervalInDays, remainingPeriods, true); + } + + /** + * @notice Drawdown function is disabled for this contract intentionally. + * drawdownWithReceivable() should be used instead. + */ + function drawdown( + uint256 /*borrowAmount*/ + ) external virtual override { + /// Intentional empty implementation to disable this function. + revert Errors.drawdownFunctionUsedInsteadofDrawdownWithReceivable(); + } + + /** + * @notice Checks if the provided receivable matches with what has been approved + * @param borrower The address of the borrower + * @param borrowAmount The amount to be borrowed + * @param receivableAsset The contract address of the receivable asset + * @param receivableParam The token ID of the receivable asset + */ + function validateReceivableAsset( + address borrower, + uint256 borrowAmount, + address receivableAsset, + uint256 receivableParam + ) external view virtual { + if (receivableAsset == address(0)) revert Errors.zeroAddressProvided(); + BS.CreditRecord memory cr = _getCreditRecord(borrower); + super._checkDrawdownEligibility(borrower, cr, borrowAmount); + + BS.ReceivableInfo memory ri = receivableInfoMapping[borrower]; + if (receivableAsset == address(0) || receivableAsset != ri.receivableAsset) + revert Errors.receivableAssetMismatch(); + if (receivableParam == 0 || receivableParam != ri.receivableParam) + revert Errors.receivableAssetParamMismatch(); + } + + /** + * @notice Allows the processor to initiate a drawdown on behalf of a borrower. + * @param borrower The address of the borrower. + * @param borrowAmount The amount to be borrowed. + * @return netAmountToBorrower The net amount to be borrowed after deducting any fees. + */ + function drawdown4Processor(address borrower, uint256 borrowAmount) + external + virtual + returns (uint256 netAmountToBorrower) + { + _onlyProcessor(); + BS.CreditRecord memory cr = _getCreditRecord(borrower); + netAmountToBorrower = super._drawdown(borrower, cr, borrowAmount); + } + + /** + * @notice Allows the processor to record a payment made by the borrower. + * @param borrower The address of the borrower. + * @param amount The amount of the payment. + * @return amountPaid The amount of the payment that was paid for the credit. + * @return paidoff A boolean indicating whether the credit has been fully paid off. + */ + function makePayment4Processor(address borrower, uint256 amount) + external + virtual + returns (uint256 amountPaid, bool paidoff) + { + _onlyProcessor(); + (amountPaid, paidoff, ) = _makePayment( + borrower, + amount, + BS.PaymentStatus.ReceivedAndVerified + ); + } + + /** + * @notice This function is used to settle the credit of a borrower and disburse any remaining funds to them. + * If the credit has been fully paid off, the `paidoff` variable will be set to true and the function can be + * called to settle the credit. However, if the credit is still active and the borrower tries to settle before + * the due date, the function will be reverted. + * @param borrower The address of the borrower whose credit is being settled. + * @param amount The amount to be settled. + * @return amountPaid The amount that was actually paid. + * @return paidoff A boolean indicating whether the credit has been fully paid off. + * + * @dev This function can only be called by the processor address set during contract initialization. + */ + function settlement4Processor(address borrower, uint256 amount) + external + virtual + returns (uint256 amountPaid, bool paidoff) + { + _onlyProcessor(); + (amountPaid, paidoff, ) = _makePayment( + borrower, + amount, + BS.PaymentStatus.ReceivedAndVerified + ); + + if (paidoff) { + delete receivableInfoMapping[borrower]; + if (amount > amountPaid) _disburseRemainingFunds(borrower, amount - amountPaid); + } else { + BS.CreditRecord storage cr = _creditRecordMapping[borrower]; + if (block.timestamp <= cr.dueDate) revert Errors.settlementTooSoon(); + if (cr.state == BS.CreditState.GoodStanding) { + cr.state = BS.CreditState.Delayed; + _updateDueInfo(borrower, false, false); + } + } + } + + /** + * @notice disburse the remaining funds associated with the factoring to the borrower + * @param receiver receiver of the funds, namely, the borrower + * @param amount the amount of the dispursement + */ + function _disburseRemainingFunds(address receiver, uint256 amount) internal { + _underlyingToken.safeTransfer(receiver, amount); + emit ExtraFundsDispersed(receiver, amount); + } + + /** + * @notice Checks if the receivable provided is able fulfill the receivable requirement + * for the requested credit line. + * @param creditLine the credit limit requested + * @param receivableAmount the value of the receivable + */ + function _checkReceivableRequirement(uint256 creditLine, uint256 receivableAmount) + internal + view + { + if ( + receivableAmount < + (creditLine * _poolConfig.receivableRequiredInBps()) / HUNDRED_PERCENT_IN_BPS + ) revert Errors.insufficientReceivableAmount(); + } + + /** + * @notice Sets the receivable asset for the borrower + */ + function _setReceivableInfo( + address borrower, + address receivableAsset, + uint256 receivableParam, + uint256 receivableAmount + ) internal virtual { + // If receivables are required, they need to be ERC721. + if ( + receivableAsset != address(0) && + !receivableAsset.supportsInterface(type(IERC721).interfaceId) + ) revert Errors.unsupportedReceivableAsset(); + + BS.ReceivableInfo memory ri = BS.ReceivableInfo( + receivableAsset, + uint88(receivableAmount), + receivableParam + ); + receivableInfoMapping[borrower] = ri; + } + + function _onlyProcessor() internal view { + if (msg.sender != processor) revert Errors.notProcessor(); + } +} diff --git a/contracts/interfaces/IReceivablePool.sol b/contracts/interfaces/IReceivablePool.sol new file mode 100644 index 00000000..f9b59c5c --- /dev/null +++ b/contracts/interfaces/IReceivablePool.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import {BaseStructs as BS} from "../libraries/BaseStructs.sol"; + +/** + * @notice Interface for contracts that can record pre-approved credit request + */ +interface IReceivablePool { + function getCoreData() + external + view + returns ( + address underlyingToken_, + address poolToken_, + address humaConfig_, + address feeManager_ + ); + + function creditRecordStaticMapping(address account) + external + view + returns (BS.CreditRecordStatic memory); + + function creditRecordMapping(address account) external view returns (BS.CreditRecord memory); + + function validateReceivableAsset( + address borrower, + uint256 borrowAmount, + address receivableAsset, + uint256 receivableParam + ) external; + + function drawdown4Processor(address borrower, uint256 borrowAmount) + external + returns (uint256 netAmountToBorrower); + + function makePayment4Processor(address borrower, uint256 amount) + external + returns (uint256 amountPaid, bool paidoff); + + function settlement4Processor(address borrower, uint256 amount) + external + virtual + returns (uint256 amountPaid, bool paidoff); +} diff --git a/contracts/mock/MockSuperAppRegister.sol b/contracts/mock/MockSuperAppRegister.sol new file mode 100644 index 00000000..2ece507f --- /dev/null +++ b/contracts/mock/MockSuperAppRegister.sol @@ -0,0 +1,22 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ISuperfluid, ISuperApp, SuperAppDefinitions} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; + +contract MockSuperAppRegister { + ISuperfluid public host; + + constructor(ISuperfluid _host) { + host = _host; + } + + function register(ISuperApp app) external { + host.registerAppByFactory( + app, + SuperAppDefinitions.APP_LEVEL_FINAL | + SuperAppDefinitions.BEFORE_AGREEMENT_CREATED_NOOP | + SuperAppDefinitions.BEFORE_AGREEMENT_UPDATED_NOOP | + SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP + ); + } +} diff --git a/contracts/mock/TestToken.sol b/contracts/mock/TestToken.sol index 1d37be51..b45c084b 100644 --- a/contracts/mock/TestToken.sol +++ b/contracts/mock/TestToken.sol @@ -1,11 +1,12 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +// import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol"; import "@openzeppelin/contracts/utils/introspection/IERC165.sol"; -contract TestToken is ERC20, IERC165 { - constructor() ERC20("TestToken", "USDC") { +contract TestToken is ERC20Permit, IERC165 { + constructor() ERC20Permit("TestToken") ERC20("TestToken", "USDC") { _mint(msg.sender, 1000 * 10**decimals()); } diff --git a/contracts/superfluid/CFALib.sol b/contracts/superfluid/CFALib.sol new file mode 100644 index 00000000..85dd51a2 --- /dev/null +++ b/contracts/superfluid/CFALib.sol @@ -0,0 +1,97 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; +import {IConstantFlowAgreementV1} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol"; +import {CFAv1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/CFAv1Library.sol"; + +library CFALib { + using CFAv1Library for CFAv1Library.InitData; + + function _decreaseFlow( + CFAv1Library.InitData storage cfaV1, + IConstantFlowAgreementV1 _cfa, + ISuperToken token, + address to, + int96 by + ) internal { + (, int96 curRate, , ) = _cfa.getFlow(token, address(this), to); + int96 newRate = curRate - by; + require(newRate >= 0, "new rate would be negative"); + + if (newRate == 0) { + cfaV1.deleteFlow(address(this), to, token); + } else { + cfaV1.updateFlow(to, token, newRate); + } + } + + function _increaseFlow( + CFAv1Library.InitData storage cfaV1, + IConstantFlowAgreementV1 _cfa, + ISuperToken token, + address to, + int96 by + ) internal { + (, int96 curRate, , ) = _cfa.getFlow(token, address(this), to); + if (curRate == 0) { + cfaV1.createFlow(to, token, by); + } else { + int96 newRate = curRate + by; + cfaV1.updateFlow(to, token, newRate); + } + } + + /** + * @notice Increase the rate of the specified flow by authorized operator, + * if this flow doesn't exist, create it, + * if this flow exists, update it. + */ + function _increaseFlowByOperator( + CFAv1Library.InitData storage cfaV1, + IConstantFlowAgreementV1 _cfa, + ISuperToken token, + address from, + address to, + int96 by + ) internal { + (, uint8 permissions, int96 allowance) = _cfa.getFlowOperatorData( + token, + from, + address(this) + ); + + //always true when full control has been given + require(permissions == 7, "origin hasn't permitted Niflot as operator"); + (, int96 curRate, , ) = _cfa.getFlow(token, from, to); + + if (curRate == 0) { + cfaV1.createFlowByOperator(from, to, token, by); + } else { + int96 newRate = curRate + by; + require(newRate < allowance, "origin doesn't allow us to allocate that flowrate"); + + cfaV1.updateFlowByOperator(from, to, token, newRate); + } + } + + function _decreaseFlowByOperator( + CFAv1Library.InitData storage cfaV1, + IConstantFlowAgreementV1 _cfa, + ISuperToken token, + address from, + address to, + int96 by + ) internal { + (, int96 curRate, , ) = _cfa.getFlow(token, from, to); + // int96 newRate = curRate - by; + // require(newRate >= 0, "new rate would be negative"); + if (curRate > 0) { + if (curRate > by) { + cfaV1.updateFlowByOperator(from, to, token, curRate - by); + } else { + cfaV1.deleteFlowByOperator(from, to, token); + } + } + } +} diff --git a/contracts/superfluid/SuperfluidFeeManager.sol b/contracts/superfluid/SuperfluidFeeManager.sol new file mode 100644 index 00000000..26bc8466 --- /dev/null +++ b/contracts/superfluid/SuperfluidFeeManager.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import "../BaseFeeManager.sol"; + +contract SuperfluidFeeManager is BaseFeeManager { + uint256 public tempInterest; + + function distBorrowingAmount(uint256 borrowAmount) + external + view + override + returns (uint256 amtToBorrower, uint256 platformFees) + { + // Calculate platform fee, which includes protocol fee and pool fee + platformFees = calcFrontLoadingFee(borrowAmount); + // uint256 interest = (borrowAmount * + // _tempCrStatic.aprInBps * + // _tempCrStatic.intervalInDays * + // SECONDS_IN_A_DAY) / + // SECONDS_IN_A_YEAR / + // HUNDRED_PERCENT_IN_BPS; + platformFees += tempInterest; + + if (borrowAmount < platformFees) revert Errors.borrowingAmountLessThanPlatformFees(); + + amtToBorrower = borrowAmount - platformFees; + } + + function setTempInterest(uint256 _tempInterest) public { + tempInterest = _tempInterest; + } + + function deleteTempInterest() public { + delete tempInterest; + } + + function getDueInfo( + BaseStructs.CreditRecord memory _cr, + BaseStructs.CreditRecordStatic memory _crStatic + ) + public + view + virtual + override + returns ( + uint256 periodsPassed, + uint96 feesAndInterestDue, + uint96 totalDue, + uint96 unbilledPrincipal, + int96 totalCharges + ) + { + if (_cr.state > BS.CreditState.GoodStanding) { + (periodsPassed, feesAndInterestDue, totalDue, unbilledPrincipal, totalCharges) = super + .getDueInfo(_cr, _crStatic); + } else if (_cr.state == BS.CreditState.Approved) { + periodsPassed = 1; + totalDue = _cr.unbilledPrincipal; + } else if (_cr.state == BS.CreditState.GoodStanding) { + periodsPassed = 0; + totalDue = _cr.totalDue; + } + } + + function calcCorrection( + uint256 dueDate, + uint256 aprInBps, + uint256 amount + ) public view virtual override returns (uint256 correction) { + if (dueDate > block.timestamp) { + correction = super.calcCorrection(dueDate, aprInBps, amount); + } + } +} diff --git a/contracts/superfluid/SuperfluidPoolProcessor.sol b/contracts/superfluid/SuperfluidPoolProcessor.sol new file mode 100644 index 00000000..c5780c41 --- /dev/null +++ b/contracts/superfluid/SuperfluidPoolProcessor.sol @@ -0,0 +1,538 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +import {IERC20, IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/ERC20.sol"; +import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; +import {IConstantFlowAgreementV1} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol"; +import {SuperAppBase} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBase.sol"; + +import "../ReceivableFactoringPoolProcessor.sol"; +import "./SuperfluidPoolProcessorStorage.sol"; +import "../Errors.sol"; +import "./TradableStream.sol"; +import "./SuperfluidFeeManager.sol"; + +/** + * + */ +contract SuperfluidPoolProcessor is + ReceivableFactoringPoolProcessor, + SuperfluidPoolProcessorStorage, + SuperAppBase +{ + using SafeERC20 for IERC20; + + event ReadyToSettlement( + address pool, + address borrower, + address receivableAsset, + uint256 receivableId, + uint256 readyTime + ); + event NotGettingEnoughAllowance( + address pool, + address borrower, + address receivableAsset, + uint256 receivableId + ); + + event FlowIsTerminated(bytes32 flowKey, uint256 endTime); + event ReceivableFlowKey(address pool, address borrower, uint256 receivableId, bytes32 flowKey); + event ReceivableCleared( + address pool, + address borrower, + bytes32 flowKey, + address receivableAsset, + uint256 receivableId + ); + event SettlementMade( + address pool, + address borrower, + bytes32 flowKey, + address receivableAsset, + uint256 receivableId + ); + + function initialize( + address _pool, + address _host, + address _cfa, + address _tradableStream + ) public initializer { + super._baseInitialize(_pool); + host = _host; + cfa = _cfa; + tradableStream = _tradableStream; + } + + /** + * @notice Mint a new NFT representing a receivable asset, and drawdown funds from the pool to the borrower's account + * @dev The `receivableAsset` must be the same as the `tradableStream` address stored in the contract. + * @param borrower The address of the borrower who will receive the funds + * @param borrowAmount The amount of funds to be drawn down from the pool + * @param receivableAsset The address of the receivable asset used as collateral + * @param dataForMintTo Additional data to be passed to the `mintTo` function when minting the NFT + */ + function mintAndDrawdown( + address borrower, + uint256 borrowAmount, + address receivableAsset, + bytes calldata dataForMintTo + ) external virtual { + if (receivableAsset != tradableStream) revert Errors.receivableAssetMismatch(); + (address underlyingToken, , , address feeManager) = pool.getCoreData(); + BS.CreditRecordStatic memory crs = _validateReceivableAsset( + borrower, + borrowAmount, + receivableAsset, + dataForMintTo, + underlyingToken + ); + + uint256 allowance = IERC20(underlyingToken).allowance(borrower, address(this)); + if (allowance < borrowAmount) revert Errors.allowanceTooLow(); + + _internalCall = true; + + uint256 receivableId = _mintNFT(receivableAsset, dataForMintTo); + + uint256 interest = (borrowAmount * crs.aprInBps * crs.intervalInDays * SECONDS_IN_A_DAY) / + SECONDS_IN_A_YEAR / + HUNDRED_PERCENT_IN_BPS; + SuperfluidFeeManager(feeManager).setTempInterest(interest); + uint256 netAmountToBorrower = pool.drawdown4Processor(borrower, borrowAmount); + SuperfluidFeeManager(feeManager).deleteTempInterest(); + + emit DrawdownMadeWithReceivable( + address(pool), + borrower, + borrowAmount, + netAmountToBorrower, + receivableAsset, + receivableId + ); + + _internalCall = false; + } + + /** + * @notice Withdraws funds from the NFT and settles the receivable asset. + * @dev It can be called for the first time only when + * a. Flow is terminated(flow rate is 0) and the credit line can be paid off + * b. The first due date has expired. + * It should pay off the credit line or change its state to delayed. It can be called repeatedly + * in the latter case(delayed state). + * It should be called to delete streamInfo and burn TradableStream NFT if the borrower paid off + * a credit line manually by calling makePaymenet function. + * @param receivableAsset The address of the receivable asset used as collateral. + * @param receivableId The ID of the NFT representing the receivable asset. + */ + function settlement(address receivableAsset, uint256 receivableId) external virtual { + if (receivableAsset != tradableStream) revert Errors.receivableAssetMismatch(); + + StreamInfo memory si = _streamInfoMapping[receivableId]; + if (si.borrower == address(0)) revert Errors.receivableIdMismatch(); + if (block.timestamp <= si.endTime && si.flowrate > 0) revert Errors.settlementTooSoon(); + + _internalCall = true; + + (address underlyingTokenAddr, , , ) = pool.getCoreData(); + IERC20 underlyingToken = IERC20(underlyingTokenAddr); + + address poolAddr = address(pool); + uint256 beforeAmount = underlyingToken.balanceOf(poolAddr); + _withdrawFromNFT(receivableAsset, receivableId, si); + uint256 amountReceived = underlyingToken.balanceOf(poolAddr) - beforeAmount; + + BS.CreditRecord memory cr = pool.creditRecordMapping(si.borrower); + if (amountReceived < cr.totalDue) { + uint256 difference = cr.totalDue - amountReceived; + uint256 received = _transferFromAccount( + underlyingToken, + si.borrower, + poolAddr, + difference + ); + amountReceived += received; + } + + bool paidoff; + if (amountReceived > 0) { + (, paidoff) = pool.settlement4Processor(si.borrower, amountReceived); + } + + if (cr.totalDue == 0) { + // This branch is only for the case when user paid off by pool.makePayment function manually + // after the loan is delayed + paidoff = true; + } + + if (paidoff) { + delete _streamInfoMapping[receivableId]; + _burnNFT(receivableAsset, receivableId); + emit ReceivableCleared( + poolAddr, + si.borrower, + si.flowKey, + receivableAsset, + receivableId + ); + } + emit SettlementMade(poolAddr, si.borrower, si.flowKey, receivableAsset, receivableId); + + _internalCall = false; + } + + /** + * @notice Transfer the borrower's allowance and make payment + * @dev This function is called by bots if the flow associated with a receivable is closed. + * It can be called only when the flow is terminated, and it can be called only once. + * NotGettingEnoughAllowance will be sent if not getting enough balance from borrowers, + * ReadyToSettlement will be sent if getting enough balance. + * @param flowKey The flow key generated based on ISuperToken, origin and receiver. + * @param receivableId The ID of the NFT representing the receivable asset. + */ + function onTerminatedFlow(bytes32 flowKey, uint256 receivableId) external { + StreamInfo memory si = _streamInfoMapping[receivableId]; + address borrower = si.borrower; + if (borrower == address(0)) revert Errors.receivableIdMismatch(); + if (si.flowKey != flowKey) revert Errors.flowKeyMismatch(); + uint256 endTime = _flowEndMapping[si.flowKey]; + if (endTime == 0 || endTime <= si.lastStartTime) revert Errors.flowIsNotTerminated(); + + uint256 flowrate = si.flowrate; + si.receivedFlowAmount = (endTime - si.lastStartTime) * flowrate; + si.lastStartTime = uint64(endTime); + si.flowrate = 0; + + (address underlyingTokenAddr, , , ) = pool.getCoreData(); + IERC20 underlyingToken = IERC20(underlyingTokenAddr); + uint256 difference = flowrate * (si.endTime - endTime); + uint256 received = _transferFromAccount( + underlyingToken, + borrower, + address(pool), + difference + ); + + if (received > 0) { + pool.makePayment4Processor(borrower, received); + } + + if (received < difference) { + // didn't receive enough amount + // send an event to trigger tryTransferFromBorrower function periodically + + emit NotGettingEnoughAllowance(address(pool), borrower, tradableStream, receivableId); + } else { + // received enough amount from borrower's allowance + // send an event to notify settlement is ready to be called + + emit ReadyToSettlement( + address(pool), + borrower, + tradableStream, + receivableId, + block.timestamp + ); + } + + _streamInfoMapping[receivableId] = si; + } + + /** + * @notice Try to transfer the borrower's allowance and make payment + * @dev It can be called only when + * a. Flow is terminated(flow rate is 0) + * b. The settlement function has not be called(credit line state is GoodStanding) + * @param receivableAsset The address of the receivable asset used as collateral. + * @param receivableId The ID of the NFT representing the receivable asset. + */ + function tryTransferAllowance(address receivableAsset, uint256 receivableId) external { + if (receivableAsset != tradableStream) revert Errors.receivableAssetMismatch(); + StreamInfo memory si = _streamInfoMapping[receivableId]; + if (si.flowrate != 0) revert Errors.invalidFlowrate(); + BS.CreditRecord memory cr = pool.creditRecordMapping(si.borrower); + if (cr.state > BS.CreditState.GoodStanding) + revert Errors.creditLineNotInGoodStandingState(); + + uint256 amount = si.receivedFlowAmount; + (address underlyingTokenAddr, , , ) = pool.getCoreData(); + IERC20 underlyingToken = IERC20(underlyingTokenAddr); + if (amount < cr.totalDue) { + uint256 diff = cr.totalDue - amount; + uint256 received = _transferFromAccount( + underlyingToken, + si.borrower, + address(pool), + diff + ); + + if (received > 0) { + pool.makePayment4Processor(si.borrower, received); + if (received >= diff) { + emit ReadyToSettlement( + address(pool), + si.borrower, + tradableStream, + receivableId, + block.timestamp + ); + } + } + } + } + + function afterAgreementUpdated( + ISuperToken _superToken, + address _agreementClass, + bytes32 _agreementId, + bytes calldata, // _agreementData, + bytes calldata, // _cbdata, + bytes calldata _ctx + ) external virtual override returns (bytes memory newCtx) { + _onlySuperfluid(msg.sender, _agreementClass); + (, int96 rate, , ) = IConstantFlowAgreementV1(_agreementClass).getFlowByID( + _superToken, + _agreementId + ); + assert(rate > 0); + _handleFlowChange(_superToken, _agreementId, uint96(rate)); + newCtx = _ctx; + } + + function afterAgreementTerminated( + ISuperToken _superToken, + address _agreementClass, + bytes32 _agreementId, + bytes calldata, // _agreementData, + bytes calldata, // _cbdata, + bytes calldata _ctx + ) external virtual override returns (bytes memory newCtx) { + _onlySuperfluid(msg.sender, _agreementClass); + _handleFlowChange(_superToken, _agreementId, 0); + newCtx = _ctx; + } + + function afterAgreementCreated( + ISuperToken, /*superToken*/ + address _agreementClass, + bytes32, /*agreementId*/ + bytes calldata, /*agreementData*/ + bytes calldata, /*cbdata*/ + bytes calldata _ctx + ) external virtual override returns (bytes memory newCtx) { + _onlySuperfluid(msg.sender, _agreementClass); + if (_internalCall) { + newCtx = _ctx; + } else { + revert Errors.invalidSuperfluidAction(); + } + } + + function streamInfoMapping(uint256 receivableId) external view returns (StreamInfo memory) { + return _streamInfoMapping[receivableId]; + } + + function flowEndMapping(bytes32 flowKey) external view returns (uint256 endTime) { + endTime = _flowEndMapping[flowKey]; + } + + function _burnNFT(address receivableAsset, uint256 receivableId) internal virtual { + ( + , + address receiver, + uint256 duration, + uint256 started, + , + ISuperToken token, + int96 flowrate + ) = TradableStream(receivableAsset).getTradableStreamData(receivableId); + + if (block.timestamp > started + duration && flowrate > 0) { + // Refund the extra amount to receiver + // TODO move this logic to TradableStream + + uint256 refundAmount = (block.timestamp - (started + duration)) * + uint256(uint96(flowrate)); + uint256 balance = token.balanceOf(address(this)); + uint256 sendAmount = balance < refundAmount ? balance : refundAmount; + if (sendAmount > 0) { + token.transfer(receiver, sendAmount); + } + } + + TradableStream(receivableAsset).burn(receivableId); + } + + function _withdrawFromNFT( + address receivableAsset, + uint256 receivableId, + StreamInfo memory si + ) internal virtual { + (, , , , , ISuperToken token, ) = TradableStream(receivableAsset).getTradableStreamData( + receivableId + ); + uint256 amount = si.receivedFlowAmount; + if (si.endTime > si.lastStartTime) { + amount += (si.endTime - si.lastStartTime) * si.flowrate; + } + + if (amount > 0) { + token.downgradeTo(address(pool), amount); + + si.lastStartTime = si.endTime; + si.receivedFlowAmount = 0; + _streamInfoMapping[receivableId] = si; + } + } + + /** + * @notice Convert amount from tokenIn unit to tokenOut unit, e.g. from usdcx to usdc + * @param amountIn the amount value expressed in tokenIn unit + * @param tokenIn the address of tokenIn + * @param tokenOut the address of tokenOut + * @return amountOut the amount value expressed in tokenOut unit + */ + function _convertAmount( + uint256 amountIn, + address tokenIn, + address tokenOut + ) internal view returns (uint256 amountOut) { + uint256 decimalsIn = IERC20Metadata(tokenIn).decimals(); + uint256 decimalsOut = IERC20Metadata(tokenOut).decimals(); + if (decimalsIn == decimalsOut) { + amountOut = amountIn; + } else { + amountOut = (amountIn * decimalsOut) / decimalsIn; + } + } + + function _validateReceivableAsset( + address borrower, + uint256 borrowAmount, + address receivableAsset, + bytes memory dataForMintTo, + address underlyingToken + ) internal virtual returns (BS.CreditRecordStatic memory crs) { + ( + address receiver, + address superToken, + address origin, + int96 _flowrate, + uint256 duration, + , + , + , + + ) = abi.decode( + dataForMintTo, + (address, address, address, int96, uint256, uint256, uint8, bytes32, bytes32) + ); + + if (borrower != receiver) revert Errors.borrowerMismatch(); + + pool.validateReceivableAsset( + receiver, + borrowAmount, + receivableAsset, + uint256(keccak256(abi.encodePacked(superToken, origin, receiver))) + ); + + if (_flowrate <= 0) revert Errors.invalidFlowrate(); + uint256 flowrate = uint256(uint96(_flowrate)); + + crs = pool.creditRecordStaticMapping(receiver); + if (duration > crs.intervalInDays * SECONDS_IN_A_DAY) revert Errors.durationTooLong(); + + uint256 receivableAmount = flowrate * duration; + receivableAmount = _convertAmount(receivableAmount, superToken, underlyingToken); + if (receivableAmount < borrowAmount) revert Errors.insufficientReceivableAmount(); + } + + function _mintNFT(address receivableAsset, bytes memory data) + internal + returns (uint256 receivableId) + { + ( + address receiver, + address superToken, + address origin, + int96 flowrate, + uint256 duration, + uint256 expiry, + uint8 v, + bytes32 r, + bytes32 s + ) = abi.decode( + data, + (address, address, address, int96, uint256, uint256, uint8, bytes32, bytes32) + ); + + receivableId = TradableStream(receivableAsset).mintToWithAuthorization( + receiver, + superToken, + origin, + flowrate, + duration, + expiry, + v, + r, + s + ); + + bytes32 flowId = keccak256(abi.encode(origin, address(this))); + bytes32 key = keccak256(abi.encodePacked(superToken, flowId)); + + StreamInfo memory streamInfo; + streamInfo.lastStartTime = uint64(block.timestamp); + streamInfo.endTime = uint64(block.timestamp + duration); + streamInfo.flowrate = uint96(flowrate); + streamInfo.borrower = receiver; + streamInfo.flowKey = key; + // Store a keccak256 hash of the receivableAsset and receivableParam on-chain + _streamInfoMapping[receivableId] = streamInfo; + + emit ReceivableFlowKey(address(pool), receiver, receivableId, key); + } + + function _transferFromAccount( + IERC20 token, + address from, + address to, + uint256 amount + ) internal returns (uint256 transferredAmount) { + uint256 allowance = token.allowance(from, address(this)); + uint256 balance = token.balanceOf(from); + transferredAmount = amount; + if (transferredAmount > allowance) transferredAmount = allowance; + if (transferredAmount > balance) transferredAmount = balance; + if (transferredAmount > 0) token.safeTransferFrom(from, to, transferredAmount); + } + + function _handleFlowChange( + ISuperToken superToken, + bytes32 flowId, + uint96 newFlowrate + ) internal { + if (!_internalCall) { + bytes32 key = keccak256(abi.encodePacked(superToken, flowId)); + if (newFlowrate == 0) { + // flow is terminated + _flowEndMapping[key] = block.timestamp; + emit FlowIsTerminated(key, block.timestamp); + } else { + // flow is decreased or increased + revert Errors.invalidSuperfluidAction(); + } + } else { + // ignore internal call + } + } + + function _onlySuperfluid(address hostValue, address cfaValue) internal view { + if (host != hostValue || cfa != cfaValue) revert Errors.invalidSuperfluidCallback(); + } +} diff --git a/contracts/superfluid/SuperfluidPoolProcessorStorage.sol b/contracts/superfluid/SuperfluidPoolProcessorStorage.sol new file mode 100644 index 00000000..4d285e6d --- /dev/null +++ b/contracts/superfluid/SuperfluidPoolProcessorStorage.sol @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +contract SuperfluidPoolProcessorStorage { + address public host; + + address public cfa; + + address public tradableStream; + + struct StreamInfo { + address borrower; + uint96 flowrate; + uint64 lastStartTime; + uint64 endTime; + uint256 receivedFlowAmount; + bytes32 flowKey; //the keccak256 hash of the Super token address and flowId + } + + /// The mapping from the keccak256 hash of the flow to StreamInfo including + /// the borrower address. This is needed for us to locate the borrower using + /// the received receivable asset. + // todo why isn't it bytes32? + mapping(uint256 => StreamInfo) internal _streamInfoMapping; + + /// The mapping from the keccak256 hash of the flow to to the flow end time + mapping(bytes32 => uint256) internal _flowEndMapping; + + bool internal _internalCall; + + uint256[100] private __gap; +} diff --git a/contracts/superfluid/TradableStream.sol b/contracts/superfluid/TradableStream.sol new file mode 100644 index 00000000..6ba12d1d --- /dev/null +++ b/contracts/superfluid/TradableStream.sol @@ -0,0 +1,405 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {ERC721} from "@openzeppelin/contracts/token/ERC721/ERC721.sol"; +import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; + +import {ISuperfluid, ISuperToken, ISuperApp} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; +import {IConstantFlowAgreementV1} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol"; +import {CFAv1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/CFAv1Library.sol"; +import {CFALib} from "./CFALib.sol"; + +import {Errors} from "../Errors.sol"; + +struct TradableStreamMetadata { + uint256 duration; + uint256 started; + address origin; + address receiver; + ISuperToken token; + int96 flowrate; +} + +/** + * TradableStream uses an NFT to make a Superfluid stream tradable. + */ +contract TradableStream is ERC721, Ownable { + string public constant version = "1"; + + using CFAv1Library for CFAv1Library.InitData; + using CFALib for CFAv1Library.InitData; + CFAv1Library.InitData public cfaV1; + + /// @dev emitted when a TradableStream is minted and transferred ownership + event TradableStreamStarted( + // token id of the TradableStream + uint256 tokenId, + // original sender of the tokenized stream + address indexed origin, + // the original receiver of the tokenized stream + address indexed receiver, + // the timestamp where the TradableStream will become burnable + uint256 matureAt + ); + + /// @dev emitted when a TradableStream is burned + event TradableStreamTerminated( + // token id of the TradableStream + uint256 tokenId, + // original sender of the tokenized stream + address indexed origin, + // the original receiver of the tokenized stream + address indexed receiver + ); + + /** + * @notice Refund the excessive token received (e.g. Flowrate increased during + * the period when the token was traded) + */ + event RefundExtraToken( + address receiver, + address owner, + uint256 refundAmount, + uint256 sendAmount + ); + + /// @notice token ids => metadata + mapping(uint256 => TradableStreamMetadata) public metadatas; + + /// @notice origin => currentReceiver => flowrate in the tradableStream + mapping(address => mapping(address => int96)) public _tradedStream; + + /// @notice current token id + uint256 public nextId; + + bytes32 public immutable domainSeparator; + bytes32 public constant MINTTO_WITH_AUTHORIZATION_TYPEHASH = + keccak256( + "MintToWithAuthorization(address receiver,address token,address origin,address owner,int96 flowrate,uint256 durationInSeconds,uint256 nonce,uint256 expiry)" + ); + mapping(address => uint256) public nonces; + + constructor(ISuperfluid host) payable Ownable() ERC721("TradableStream", "TSTRM") { + IConstantFlowAgreementV1 cfa = IConstantFlowAgreementV1( + address( + host.getAgreementClass( + keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1") + ) + ) + ); + + cfaV1 = CFAv1Library.InitData(host, cfa); + + domainSeparator = keccak256( + abi.encode( + keccak256( + "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" + ), + keccak256(bytes("TradableStream")), + keccak256(bytes(version)), + block.chainid, + address(this) + ) + ); + } + + /// @notice require that tokenId exists (minted and not burnt) + /// @param tokenId ID of token to be checked + modifier exists(uint256 tokenId) { + if (!_exists(tokenId)) { + revert Errors.tradableStreamNotExisting(); + } + _; + } + + /// @notice Burns an expired TradableStream, resture the stream back to the original receiver + /// @dev Anyone can call this method to burn the tradableStream at any time, + /// will revert if it is not expired and its flow is not zero yet + /// @dev See `_beforeTokenTransfer` for the handover process. + /// @param tokenId The token ID of the TradableStream to be burned + function burn(uint256 tokenId) external { + TradableStreamMetadata memory meta = metadatas[tokenId]; + + address owner = ownerOf(tokenId); + (, int96 flowrate, , ) = cfaV1.cfa.getFlow(meta.token, meta.origin, owner); + if (meta.started == 0 && msg.sender != owner) { + revert Errors.notTradableStreamOwner(); + } + if (!hasMatured(tokenId) && flowrate > 0) { + revert Errors.tradableStreamNotMatured(); + } + _burn(tokenId); + + emit TradableStreamTerminated(tokenId, meta.origin, meta.receiver); + } + + /// @notice Mint a TradableStream from an existing stream + /// @param token the super token + /// @param origin the payer of the stream + /// @param flowrate the flowrate that will be traded. It can be part of the entire steam. + /// @param durationInSeconds the duration for the stream to be traded and owned by the a new receiver + function mint( + ISuperToken token, + address origin, + int96 flowrate, + uint256 durationInSeconds + ) external { + _mintTo(msg.sender, token, origin, msg.sender, flowrate, durationInSeconds); + } + + function _mintTo( + address receiver, + ISuperToken token, + address origin, + address newOwner, + int96 flowrate, + uint256 durationInSeconds + ) internal returns (uint256 tokenId) { + if ( + receiver == address(0) || + address(token) == address(0) || + origin == address(0) || + newOwner == address(0) + ) revert Errors.zeroAddressProvided(); + + if (flowrate <= 0) revert Errors.invalidFlowrate(); + + // Get flow from origin to receiver + (, int96 allFlowrate, , ) = cfaV1.cfa.getFlow(token, origin, receiver); + + // Get investments + int96 alreadyTraded = _tradedStream[origin][receiver]; + if (alreadyTraded >= allFlowrate) revert Errors.notEnoughAvailableFlowrate(); + int96 availableFlowrate = allFlowrate - alreadyTraded; + if (flowrate > availableFlowrate) revert Errors.notEnoughAvailableFlowrate(); + + tokenId = nextId; + + metadatas[tokenId] = TradableStreamMetadata({ + origin: origin, + receiver: receiver, + flowrate: flowrate, + token: token, + duration: durationInSeconds, + started: 0 + }); + + //will start streaming from TradableStream to msg.sender / receiver + _mint(receiver, tokenId); + nextId += 1; + + if (newOwner != receiver) { + _transfer(receiver, newOwner, tokenId); + } + } + + /// @notice Mint a TradableStream to msg.sender based on receiver's authorization + /// @dev This function is to combine mint, approve and transfer in one function. + /// The receiver generates authorization proof( + /// the format is 'MintToWithAuthorization(address receiver,address token,address origin,address owner,int96 flowrate,uint256 durationInSeconds,uint256 nonce,uint256 expiry)' + /// ). The owner(who will receive this TradableStream) can call this function with the signature(v, r, s). + /// @param currentOwner the flow's current receiver who creates the proof + /// @param token the supertoken + /// @param origin the payer of the stream + /// @param flowrate the flowrate that will be traded. It can be part of the entire steam. + /// @param durationInSeconds the duration for the stream to be traded and owned by the a new receiver + /// @param expiry the expiration timestamp(second) of the proof + /// @param v v of the signature + /// @param r r of the signature + /// @param s s of the signature + function mintToWithAuthorization( + address currentOwner, + address token, + address origin, + int96 flowrate, + uint256 durationInSeconds, + uint256 expiry, + uint8 v, + bytes32 r, + bytes32 s + ) external returns (uint256) { + if (expiry > 0 && block.timestamp > expiry) revert Errors.AuthorizationExpired(); + + uint256 nonce = nonces[currentOwner]++; + + bytes32 data = keccak256( + abi.encodePacked( + "\x19\x01", + domainSeparator, + keccak256( + abi.encode( + MINTTO_WITH_AUTHORIZATION_TYPEHASH, + currentOwner, + token, + origin, + msg.sender, + flowrate, + durationInSeconds, + nonce, + expiry + ) + ) + ) + ); + + if (currentOwner != ecrecover(data, v, r, s)) revert Errors.InvalidAuthorization(); + return + _mintTo( + currentOwner, + ISuperToken(token), + origin, + msg.sender, + flowrate, + durationInSeconds + ); + } + + function _beforeTokenTransfer( + address oldReceiver, + address newReceiver, + uint256 tokenId + ) internal override { + TradableStreamMetadata memory meta = metadatas[tokenId]; + + if (newReceiver == meta.origin) revert Errors.newReceiverSameToOrigin(); + + if (oldReceiver == address(0)) { + //to mint + _tradedStream[meta.origin][newReceiver] += meta.flowrate; + } else if (newReceiver == address(0)) { + //to burn + _tradedStream[meta.origin][oldReceiver] -= meta.flowrate; + delete metadatas[tokenId]; + + (, int96 flowrate, , ) = cfaV1.cfa.getFlow(meta.token, meta.origin, oldReceiver); + if (flowrate > 0) { + // If the flowrate has been changed after the TradableStream was transferred, + // the current flowrate can be different from the initial flowrate. + + // todo This seems to be broken. meta.flowrate may not equal to the flowrate from the statement below. + // check if meta.flowrate should be used in the next two statements instead of flowrate + + // decrease the current flowrate from oldReceiver + cfaV1._decreaseFlowByOperator( + cfaV1.cfa, + meta.token, + meta.origin, + oldReceiver, + flowrate + ); + + // increase current flowrate to the initial receiver + cfaV1._increaseFlowByOperator( + cfaV1.cfa, + meta.token, + meta.origin, + meta.receiver, + flowrate + ); + } + // If the flow has been terminated, do nothing. + } else { + //transfer + if (meta.started == 0) { + metadatas[tokenId].started = block.timestamp; + emit TradableStreamStarted( + tokenId, + meta.origin, + meta.receiver, + block.timestamp + meta.duration + ); + } else { + if (hasMatured(tokenId)) { + revert("this tradableStream has expired"); + } + } + + _tradedStream[meta.origin][oldReceiver] -= meta.flowrate; + _tradedStream[meta.origin][newReceiver] += meta.flowrate; + + //handover flow + cfaV1._decreaseFlowByOperator( + cfaV1.cfa, + meta.token, + meta.origin, + oldReceiver, + meta.flowrate + ); + cfaV1._increaseFlowByOperator( + cfaV1.cfa, + meta.token, + meta.origin, + newReceiver, + meta.flowrate + ); + } + } + + function maturesAt(uint256 tokenId) public view exists(tokenId) returns (uint256) { + if (metadatas[tokenId].started == 0) return 0; + + return metadatas[tokenId].started + metadatas[tokenId].duration; + } + + function hasMatured(uint256 tokenId) public view exists(tokenId) returns (bool) { + uint256 _maturesAt = maturesAt(tokenId); + if (_maturesAt == 0) return false; + return (_maturesAt < block.timestamp); + } + + /** + * @notice Gets the remaining value in the TradableStream. + */ + function remainingValue(uint256 tokenId) + public + view + exists(tokenId) + returns (ISuperToken token, uint256 value) + { + TradableStreamMetadata memory meta = metadatas[tokenId]; + assert(meta.flowrate > 0); + + token = meta.token; + int256 remainingSeconds; + if (meta.started == 0) { + remainingSeconds = int256(meta.duration); + } else { + remainingSeconds = + int256(meta.started) + + int256(meta.duration) - + int256(block.timestamp); + } + + if (remainingSeconds <= 0) { + value = 0; + } else { + value = uint256(remainingSeconds) * uint256(uint96(meta.flowrate)); + } + } + + function getTradableStreamData(uint256 tokenId) + public + view + exists(tokenId) + returns ( + address origin, + address receiver, + uint256 duration, + uint256 started, + uint256 until, + ISuperToken token, + int96 flowrate + ) + { + TradableStreamMetadata memory meta = metadatas[tokenId]; + return ( + meta.origin, + meta.receiver, + meta.duration, + meta.started, + maturesAt(tokenId), + meta.token, + meta.flowrate + ); + } +} diff --git a/contracts/utils/Multisend.sol b/contracts/utils/Multisend.sol new file mode 100644 index 00000000..5fdf6512 --- /dev/null +++ b/contracts/utils/Multisend.sol @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: AGPL-3.0-or-later +pragma solidity ^0.8.0; + +contract Multisend { + function multisend(address[] calldata tos, bytes[] calldata datas) + external + returns (bytes[] memory results) + { + results = new bytes[](datas.length); + for (uint256 i = 0; i < datas.length; i++) { + (bool success, bytes memory returndata) = tos[i].call(datas[i]); + + if (!success) { + // Look for revert reason and bubble it up if present + if (returndata.length > 0) { + // The easiest way to bubble the revert reason is using memory via assembly + /// @solidity memory-safe-assembly + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(); + } + } + + results[i] = returndata; + } + } +} diff --git a/deployment/goerli-deployed-contracts.json b/deployment/goerli-deployed-contracts.json index a5b99a45..bc553e40 100644 --- a/deployment/goerli-deployed-contracts.json +++ b/deployment/goerli-deployed-contracts.json @@ -18,4 +18,14 @@ "HDT":"0x27Fa332a5cA06492C2007FF4b143C921Cf779C3b", "ReceivableFactoringPoolConfig":"0xBa779F41ae414dEc63265D79a02DED47fbe007a5", "ReceivableFactoringPoolImpl":"0x470f71B48B42BE5B4B47D9f9A407bDA98DbDEb8D", -"ReceivableFactoringPool":"0x11672c0bBFF498c72BC2200f42461c0414855042"} \ No newline at end of file +"ReceivableFactoringPool":"0x11672c0bBFF498c72BC2200f42461c0414855042", +"SuperfluidFactoringPoolTimelock":"0x3b96db8cE5A50D6B49ebF6b377899f0C04e34cB9", +"SuperfluidFactoringPoolProxyAdminTimelock":"0xeE6E341C6569fA66efB77Aac9981e13104424E48", +"SuperfluidFactoringPoolFeeManager":"0x74CE2FD3Acfd99642aBa82397B47754DFd596771", +"SuperfluidPoolHDTImpl":"0x22F8027c539f4E08E8Ce7654E028729D0bC54B43", +"SuperfluidPoolHDT":"0x16E9EdbC0bA959612973803804917cF5702126a5", +"SuperfluidFactoringPoolConfig":"0x87dd95FFf17174217584ABC6e4354C89DAc448A8", +"SuperfluidFactoringPoolImpl":"0x9E7cC9EbEBec7c787d5b2DF5f2a9Dd0C918593D5", +"SuperfluidFactoringPool":"0x572A37c3ECa682e8d5F6Dd659419C15d8b79615F", +"SuperfluidTradableStream":"0xba5bF43dD32929ea725532Ca7B9B66156060d3eE", +"Multisend":"0x11ED387Fa673852Ba47F96Aa9BEdE37F12De2998"} \ No newline at end of file diff --git a/deployment/goerli-initialized-contracts.json b/deployment/goerli-initialized-contracts.json index f716231b..11dfd5b8 100644 --- a/deployment/goerli-initialized-contracts.json +++ b/deployment/goerli-initialized-contracts.json @@ -1,12 +1,14 @@ -{ - "EANFT": "Done", - "HumaConfig": "Done", - "BaseCreditPoolFeeManager": "Done", - "BaseCreditHDT": "Done", - "BaseCreditPoolConfig": "Done", - "BaseCreditPool": "Done", - "ReceivableFactoringPoolFeeManager": "Done", - "HDT": "Done", - "ReceivableFactoringPoolConfig": "Done", - "ReceivableFactoringPool": "Done" -} \ No newline at end of file +{"EANFT":"Done", +"HumaConfig":"Done", +"BaseCreditPoolFeeManager":"Done", +"BaseCreditHDT":"Done", +"BaseCreditPoolConfig":"Done", +"BaseCreditPool":"Done", +"ReceivableFactoringPoolFeeManager":"Done", +"HDT":"Done", +"ReceivableFactoringPoolConfig":"Done", +"ReceivableFactoringPool":"Done", +"SuperfluidFactoringPoolFeeManager":"Done", +"SuperfluidPoolHDT":"Done", +"SuperfluidFactoringPoolConfig":"Done", +"SuperfluidFactoringPool":"Done"} \ No newline at end of file diff --git a/deployment/goerli-verified-contracts.json b/deployment/goerli-verified-contracts.json index be219128..1c83b4b9 100644 --- a/deployment/goerli-verified-contracts.json +++ b/deployment/goerli-verified-contracts.json @@ -18,4 +18,14 @@ "HDT":"Done", "ReceivableFactoringPoolConfig":"Done", "ReceivableFactoringPoolImpl":"Done", -"ReceivableFactoringPool":"Done"} \ No newline at end of file +"ReceivableFactoringPool":"Done", +"SuperfluidTradableStream":"Done", +"SuperfluidFactoringPoolTimelock":"Done", +"SuperfluidFactoringPoolProxyAdminTimelock":"Done", +"SuperfluidFactoringPoolFeeManager":"Done", +"SuperfluidPoolHDTImpl":"Done", +"SuperfluidPoolHDT":"Done", +"SuperfluidFactoringPoolConfig":"Done", +"SuperfluidFactoringPoolImpl":"Done", +"SuperfluidFactoringPool":"Done", +"Multisend":"Done"} \ No newline at end of file diff --git a/deployment/goerli/deploy-goerli-superfluid-factoring-pool.js b/deployment/goerli/deploy-goerli-superfluid-factoring-pool.js new file mode 100644 index 00000000..1ba9c4c0 --- /dev/null +++ b/deployment/goerli/deploy-goerli-superfluid-factoring-pool.js @@ -0,0 +1,75 @@ +const {deploy} = require("../utils.js"); + +const HUMA_OWNER_MULTI_SIG = "0x1931bD73055335Ba06efB22DB96169dbD4C5B4DB"; +const POOL_OWNER_MULTI_SIG = "0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA"; + +const SF_USDC_ADDRESS = "0xc94dd466416A7dFE166aB2cF916D3875C049EBB7"; +const SF_HOST_ADDRESS = "0x22ff293e14F1EC3A09B137e9e06084AFd63adDF9"; + +async function deployContracts() { + const network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + const accounts = await hre.ethers.getSigners(); + if (accounts.length == 0) { + throw new Error("Accounts not set!"); + } + const deployer = await accounts[0]; + console.log("deployer address: " + deployer.address); + const proxyOwner = await accounts[1]; + + const eaService = await accounts[4]; + console.log("ea service address: " + eaService.address); + + // Deploying Superfluid factoring pool + + const humaConfig = await deploy("HumaConfig", "HumaConfig"); + const humaConfigTL = await deploy("TimelockController", "HumaConfigTimelock", [ + 0, + [HUMA_OWNER_MULTI_SIG], + [deployer.address], + ]); + + const superfluidFactoringPoolTL = await deploy( + "TimelockController", + "SuperfluidFactoringPoolTimelock", + [0, [POOL_OWNER_MULTI_SIG], [deployer.address]] + ); + + const superfluidFactoringPoolProxyAdminTL = await deploy( + "TimelockController", + "SuperfluidFactoringPoolProxyAdminTimelock", + [0, [POOL_OWNER_MULTI_SIG], [deployer.address]] + ); + + const feeManager = await deploy("StreamFeeManager", "SuperfluidFactoringPoolFeeManager"); + const hdtImpl = await deploy("HDT", "SuperfluidPoolHDTImpl"); + const hdt = await deploy("TransparentUpgradeableProxy", "SuperfluidPoolHDT", [ + hdtImpl.address, + superfluidFactoringPoolProxyAdminTL.address, + [], + ]); + + const poolConfig = await deploy("BasePoolConfig", "SuperfluidFactoringPoolConfig"); + + const poolImpl = await deploy("SuperfluidFactoringPool", "SuperfluidFactoringPoolImpl"); + const pool = await deploy("TransparentUpgradeableProxy", "SuperfluidFactoringPool", [ + poolImpl.address, + superfluidFactoringPoolProxyAdminTL.address, + [], + ]); + + // const evaluationAgentNFT = await deploy("EvaluationAgentNFT", "EANFT", [], eaService); + + const tradableStream = await deploy("TradableStream", "SuperfluidTradableStream", [ + SF_HOST_ADDRESS, + ]); + + await deploy("Multisend", "Multisend"); +} + +deployContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/deployment/goerli/init-goerli-superfluid-factoring-pool.js b/deployment/goerli/init-goerli-superfluid-factoring-pool.js new file mode 100644 index 00000000..14ece954 --- /dev/null +++ b/deployment/goerli/init-goerli-superfluid-factoring-pool.js @@ -0,0 +1,424 @@ +const {BigNumber: BN} = require("ethers"); +const { + getInitilizedContract, + updateInitilizedContract, + getDeployedContracts, + sendTransaction, +} = require("../utils.js"); + +let deployer, deployedContracts, lender, eaService, pdsService, treasury, payer; +let ea_sfp, sfpOperator, sfpOwnerTreasury; + +const USDC_ADDRESS = "0xc94dd466416A7dFE166aB2cF916D3875C049EBB7"; + +const HUMA_OWNER_ADRESS = "0x1931bD73055335Ba06efB22DB96169dbD4C5B4DB"; +const POOL_OWNER_MULTI_SIG = "0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA"; + +async function transferOwnershipToTL(contractName, contractKey, timeLockKey) { + if (!deployedContracts[timeLockKey]) { + throw new Error(`${timeLockKey} not deployed yet!`); + } + + if (!deployedContracts[contractKey]) { + throw new Error(`${contractKey} not deployed yet!`); + } + + const TimeLockController = await hre.ethers.getContractFactory("TimelockController"); + const timeLockController = TimeLockController.attach(deployedContracts[timeLockKey]); + + const Contract = await hre.ethers.getContractFactory(contractName); + const contract = Contract.attach(deployedContracts[contractKey]); + + await sendTransaction(contractKey, contract, "transferOwnership", [ + timeLockController.address, + ]); + + const adminRole = await timeLockController.TIMELOCK_ADMIN_ROLE(); + await sendTransaction(contractKey, timeLockController, "renounceRole", [ + adminRole, + deployer.address, + ]); +} + +async function initHumaConfig() { + const initilized = await getInitilizedContract("HumaConfig"); + if (initilized) { + console.log("HumaConfig is already initialized!"); + return; + } + + if (!deployedContracts["HumaConfig"]) { + throw new Error("HumaConfig not deployed yet!"); + } + + if (!deployedContracts["HumaConfigTimelock"]) { + throw new Error("HumaConfigTimelock not deployed yet!"); + } + + if (!deployedContracts["EANFT"]) { + throw new Error("EANFT not deployed yet!"); + } + + if (!deployedContracts["USDC"]) { + throw new Error("USDC not deployed yet!"); + } + + const HumaConfig = await hre.ethers.getContractFactory("HumaConfig"); + const humaConfig = HumaConfig.attach(deployedContracts["HumaConfig"]); + + const TimelockController = await hre.ethers.getContractFactory("TimelockController"); + const humaConfigTL = TimelockController.attach(deployedContracts["HumaConfigTimelock"]); + + await sendTransaction("HumaConfig", humaConfig, "setProtocolDefaultGracePeriod", [ + 30 * 24 * 3600, + ]); + await sendTransaction("HumaConfig", humaConfig, "setTreasuryFee", [500]); + await sendTransaction("HumaConfig", humaConfig, "setEANFTContractAddress", [ + deployedContracts["EANFT"], + ]); + + await sendTransaction("HumaConfig", humaConfig, "setEAServiceAccount", [eaService.address]); + await sendTransaction("HumaConfig", humaConfig, "setPDSServiceAccount", [pdsService.address]); + + // Add usdc as an asset supported by the protocol + await sendTransaction("HumaConfig", humaConfig, "setLiquidityAsset", [USDC_ADDRESS, true]); + + // Set treasury for the protocol + await sendTransaction("HumaConfig", humaConfig, "setHumaTreasury", [treasury.address]); + + await transferOwnershipToTL("HumaConfig", "HumaConfig", "HumaConfigTimelock"); + + await updateInitilizedContract("HumaConfig"); +} + +async function initFeeManager() { + const initilized = await getInitilizedContract("SuperfluidFactoringPoolFeeManager"); + if (initilized) { + console.log("SuperfluidFactoringPoolFeeManager is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidFactoringPoolFeeManager"]) { + throw new Error("SuperfluidFactoringPoolFeeManager not deployed yet!"); + } + + const StreamFeeManager = await hre.ethers.getContractFactory("StreamFeeManager"); + const feeManager = StreamFeeManager.attach( + deployedContracts["SuperfluidFactoringPoolFeeManager"] + ); + + // await sendTransaction( + // "SuperfluidFactoringPoolFeeManager", + // feeManager, + // "setFees", + // [0, 0, 0, 0, 0] + // ); + // await sendTransaction( + // "SuperfluidFactoringPoolFeeManager", + // feeManager, + // "setMinPrincipalRateInBps", + // [0] + // ); + + await updateInitilizedContract("SuperfluidFactoringPoolFeeManager"); +} + +async function initHDT() { + const initilized = await getInitilizedContract("SuperfluidPoolHDT"); + if (initilized) { + console.log("SuperfluidPoolHDT is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidPoolHDT"]) { + throw new Error("SuperfluidPoolHDT not deployed yet!"); + } + + const HDT = await hre.ethers.getContractFactory("HDT"); + const hdt = HDT.attach(deployedContracts["SuperfluidPoolHDT"]); + + if (!deployedContracts["SuperfluidFactoringPool"]) { + throw new Error("SuperfluidFactoringPool not deployed yet!"); + } + + await sendTransaction("SuperfluidPoolHDT", hdt, "initialize", [ + "Superfluid HDT", + "SFHDT", + USDC_ADDRESS, + ]); + + await sendTransaction("SuperfluidPoolHDT", hdt, "setPool", [ + deployedContracts["SuperfluidFactoringPool"], + ]); + + await transferOwnershipToTL("HDT", "SuperfluidPoolHDT", "SuperfluidFactoringPoolTimelock"); + + await updateInitilizedContract("SuperfluidPoolHDT"); +} + +async function initEA() { + const initilized = await getInitilizedContract("EANFT"); + if (initilized) { + console.log("EANFT is already initialized!"); + return; + } + + if (!deployedContracts["EANFT"]) { + throw new Error("EANFT not deployed yet!"); + } + + const EANFT = await hre.ethers.getContractFactory("EvaluationAgentNFT"); + const eaNFT = EANFT.attach(deployedContracts["EANFT"]); + + const eaNFTFromEA = eaNFT.connect(ea_sfp); + await sendTransaction("EvaluationAgentNFT", eaNFTFromEA, "mintNFT", [ea_sfp.address]); + await updateInitilizedContract("EANFT"); +} + +async function initPoolConfig() { + const initilized = await getInitilizedContract("SuperfluidFactoringPoolConfig"); + if (initilized) { + console.log("SuperfluidFactoringPoolConfig is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidFactoringPoolConfig"]) { + throw new Error("SuperfluidFactoringPoolConfig not deployed yet!"); + } + + const BasePoolConfig = await hre.ethers.getContractFactory("BasePoolConfig"); + const poolConfig = BasePoolConfig.attach(deployedContracts["SuperfluidFactoringPoolConfig"]); + + if (!deployedContracts["ReceivableFactoringPool"]) { + throw new Error("ReceivableFactoringPool not deployed yet!"); + } + + if (!deployedContracts["SuperfluidPoolHDT"]) { + throw new Error("SuperfluidPoolHDT not deployed yet!"); + } + + if (!deployedContracts["HumaConfig"]) { + throw new Error("HumaConfig not deployed yet!"); + } + + if (!deployedContracts["SuperfluidFactoringPoolFeeManager"]) { + throw new Error("SuperfluidFactoringPoolFeeManager not deployed yet!"); + } + + const HDT = await hre.ethers.getContractFactory("HDT"); + const hdt = HDT.attach(deployedContracts["SuperfluidPoolHDT"]); + + const HumaConfig = await hre.ethers.getContractFactory("HumaConfig"); + const humaConfig = HumaConfig.attach(deployedContracts["HumaConfig"]); + + const StreamFeeManager = await hre.ethers.getContractFactory("StreamFeeManager"); + const feeManager = StreamFeeManager.attach( + deployedContracts["SuperfluidFactoringPoolFeeManager"] + ); + + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "initialize", [ + "SuperfluidFactoringPool", + hdt.address, + humaConfig.address, + feeManager.address, + ]); + + const decimals = await hdt.decimals(); + const cap = BN.from(1_000_000).mul(BN.from(10).pow(BN.from(decimals))); + console.log("cap: " + cap); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPoolLiquidityCap", [ + cap, + ]); + + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPool", [ + deployedContracts["SuperfluidFactoringPool"], + ]); + console.log(`ea_sfp: ${ea_sfp.address}`); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setEvaluationAgent", [ + 1, + ea_sfp.address, + ]); + + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setPoolOwnerRewardsAndLiquidity", + [500, 200] + ); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setEARewardsAndLiquidity", + [1000, 100] + ); + const maxCL = BN.from(1_000).mul(BN.from(10).pow(BN.from(decimals))); + console.log("maxCL: " + maxCL); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setMaxCreditLine", [ + maxCL, + ]); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setAPR", [0]); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setReceivableRequiredInBps", + [10000] + ); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPoolPayPeriod", [30]); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPoolToken", [ + deployedContracts["SuperfluidPoolHDT"], + ]); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setWithdrawalLockoutPeriod", + [90] + ); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setPoolDefaultGracePeriod", + [60] + ); + + await sendTransaction("ReceivableFactoringPoolConfig", poolConfig, "addPoolOperator", [ + sfpOperator.address, + ]); + await sendTransaction("ReceivableFactoringPoolConfig", poolConfig, "setPoolOwnerTreasury", [ + sfpOwnerTreasury.address, + ]); + + await transferOwnershipToTL( + "BasePoolConfig", + "SuperfluidFactoringPoolConfig", + "SuperfluidFactoringPoolTimelock" + ); + + await updateInitilizedContract("SuperfluidFactoringPoolConfig"); +} + +async function initPool() { + const initilized = await getInitilizedContract("SuperfluidFactoringPool"); + if (initilized) { + console.log("SuperfluidFactoringPool is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidFactoringPool"]) { + throw new Error("SuperfluidFactoringPool not deployed yet!"); + } + + if (!deployedContracts["SuperfluidFactoringPoolConfig"]) { + throw new Error("SuperfluidFactoringPoolConfig not deployed yet!"); + } + + const SuperfluidFactoringPool = await hre.ethers.getContractFactory("SuperfluidFactoringPool"); + const pool = SuperfluidFactoringPool.attach(deployedContracts["SuperfluidFactoringPool"]); + + await sendTransaction("SuperfluidFactoringPool", pool, "initialize", [ + deployedContracts["SuperfluidFactoringPoolConfig"], + ]); + + await updateInitilizedContract("SuperfluidFactoringPool"); +} + +async function prepare() { + if (!deployedContracts["SuperfluidFactoringPool"]) { + throw new Error("SuperfluidFactoringPool not deployed yet!"); + } + + const SuperfluidFactoringPool = await hre.ethers.getContractFactory("SuperfluidFactoringPool"); + const pool = SuperfluidFactoringPool.attach(deployedContracts["SuperfluidFactoringPool"]); + const poolFromOperator = pool.connect(sfpOperator); + + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + deployer.address, + ]); + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + ea_sfp.address, + ]); + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + lender.address, + ]); + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + sfpOwnerTreasury.address, + ]); + + const USDC = await hre.ethers.getContractFactory("TestToken"); + const usdc = USDC.attach(USDC_ADDRESS); + const decimals = await usdc.decimals(); + + // Owner + const usdcFromPoolOwnerTreasury = await usdc.connect(sfpOwnerTreasury); + const poolFromPoolOwnerTreasury = await pool.connect(sfpOwnerTreasury); + const amountOwner = BN.from(20_000).mul(BN.from(10).pow(BN.from(decimals))); + await sendTransaction("TestToken", usdc, "mint", [sfpOwnerTreasury.address, amountOwner]); + await sendTransaction("TestToken", usdcFromPoolOwnerTreasury, "approve", [ + pool.address, + amountOwner, + ]); + await sendTransaction( + "SuperfluidFactoringPool", + poolFromPoolOwnerTreasury, + "makeInitialDeposit", + [amountOwner] + ); + + // EA + const usdcFromEA = await usdc.connect(ea_sfp); + const poolFromEA = await pool.connect(ea_sfp); + const amountEA = BN.from(10_000).mul(BN.from(10).pow(BN.from(decimals))); + await sendTransaction("TestToken", usdc, "mint", [ea_sfp.address, amountEA]); + await sendTransaction("TestToken", usdcFromEA, "approve", [pool.address, amountEA]); + await sendTransaction("SuperfluidFactoringPool", poolFromEA, "makeInitialDeposit", [amountEA]); + + // await sendTransaction("SuperfluidFactoringPool", pool, "enablePool", []); + + //payer + const amountPayer = BN.from(100_000_000).mul(BN.from(10).pow(BN.from(decimals))); + await sendTransaction("TestToken", usdc, "mint", [payer.address, amountPayer]); +} + +async function initContracts() { + const network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + const accounts = await hre.ethers.getSigners(); + [ + deployer, + proxyOwner, + lender, + , + eaService, + pdsService, + treasury, + , + payer, + , + , + , + , + ea_sfp, + sfpOperator, + sfpOwnerTreasury, + ] = await accounts; + console.log("deployer address: " + deployer.address); + console.log("lender address: " + lender.address); + console.log("ea_sfp address: " + ea_sfp.address); + + deployedContracts = await getDeployedContracts(); + + await initHumaConfig(); + await initFeeManager(); + await initHDT(); + await initEA(); + await initPoolConfig(); + await initPool(); + + await prepare(); +} + +initContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/deployment/goerli/verification-test-superfluid-factoring-pool.js b/deployment/goerli/verification-test-superfluid-factoring-pool.js new file mode 100644 index 00000000..2ebc27d4 --- /dev/null +++ b/deployment/goerli/verification-test-superfluid-factoring-pool.js @@ -0,0 +1,279 @@ +const {getDeployedContracts, impersonate, advanceClock} = require("../utils.js"); +const {BigNumber: BN} = require("ethers"); +const {displayCreditRecord} = require("../verification-test-utils.js"); + +const NETWORK = "goerli"; +const SF_USDC_ADDRESS = "0xc94dd466416A7dFE166aB2cF916D3875C049EBB7"; +const SF_USDCX_ADDRESS = "0x8aE68021f6170E5a766bE613cEA0d75236ECCa9a"; +const SF_HOST_ADDRESS = "0x22ff293e14F1EC3A09B137e9e06084AFd63adDF9"; +const SF_CFA_ADDRESS = "0xEd6BcbF6907D4feEEe8a8875543249bEa9D308E8"; + +let deployedContracts, accounts; + +let usdc, decimals, sf, usdcx, cfa, nft; + +let humaConfig, eaService, pdsService; + +async function createFlow(xToken, payer, payee, flowrate) { + const calldata = cfa.interface.encodeFunctionData("createFlow", [ + xToken.address, + payee.address, + flowrate, + "0x", + ]); + + await sf.connect(payer).callAgreement(cfa.address, calldata, "0x"); +} + +async function authorizeFlow(xToken, sender, operator) { + const calldata = cfa.interface.encodeFunctionData("authorizeFlowOperatorWithFullControl", [ + xToken.address, + operator.address, + "0x", + ]); + await sf.connect(sender).callAgreement(cfa.address, calldata, "0x"); +} + +async function prepare(network) { + deployedContracts = await getDeployedContracts(network); + accounts = await hre.ethers.getSigners(); + + const TestToken = await hre.ethers.getContractFactory("TestToken"); + usdc = TestToken.attach(SF_USDC_ADDRESS); + decimals = await usdc.decimals(); + + const HumaConfig = await hre.ethers.getContractFactory("HumaConfig"); + humaConfig = HumaConfig.attach(deployedContracts["HumaConfig"]); + + const eaServiceAddress = await humaConfig.eaServiceAccount(); + console.log(`ea service: ${eaServiceAddress}`); + eaService = await impersonate(eaServiceAddress); + + const pdsServiceAddress = await humaConfig.pdsServiceAccount(); + console.log(`pds service: ${pdsServiceAddress}`); + pdsService = await impersonate(pdsServiceAddress); + + sf = await ethers.getContractAt("ISuperfluid", SF_HOST_ADDRESS); + usdcx = await ethers.getContractAt("ISuperToken", SF_USDCX_ADDRESS); + cfa = await ethers.getContractAt("IConstantFlowAgreementV1", SF_CFA_ADDRESS); + + const TradableStream = await hre.ethers.getContractFactory("TradableStream"); + nft = TradableStream.attach(deployedContracts["SuperfluidTradableStream"]); +} + +async function verifySuperfluidFactoringPool() { + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Prepare SuperfluidFactoringPool data *"); + console.log("*******************************************************************"); + console.log(`\n`); + + const poolOperator = accounts[0]; + const lender = accounts[1]; + const payer = accounts[2]; + console.log(`pool operator address: ${poolOperator.address}`); + console.log(`lender address: ${lender.address}`); + console.log(`payer address: ${payer.address}`); + + const BasePoolConfig = await hre.ethers.getContractFactory("BasePoolConfig"); + const poolConfig = BasePoolConfig.attach(deployedContracts["SuperfluidFactoringPoolConfig"]); + + const SuperfluidFactoringPool = await hre.ethers.getContractFactory("SuperfluidFactoringPool"); + const pool = SuperfluidFactoringPool.attach(deployedContracts["SuperfluidFactoringPool"]); + + const HDT = await hre.ethers.getContractFactory("HDT"); + const hdt = HDT.attach(deployedContracts["SuperfluidPoolHDT"]); + + const poolOwnerAddres = await poolConfig.owner(); + console.log( + `pool owner: ${poolOwnerAddres}, isOperator: ${await poolConfig.isOperator( + poolOwnerAddres + )}` + ); + const poolOwner = await impersonate(poolOwnerAddres); + + let isOperator = await poolConfig.isOperator(poolOperator.address); + if (!isOperator) { + await poolConfig.connect(poolOwner).addPoolOperator(poolOperator.address); + } + await pool.connect(poolOperator).addApprovedLender(lender.address); + + // choose borrower + + let borrower, cr; + for (let i = 3; i < 10; i++) { + cr = await pool.creditRecordMapping(accounts[i].address); + if (cr.state == 0 || cr.state == 2) { + borrower = accounts[i]; + } + // console.log(`${accounts[i].address} state: ${cr.state}`); + } + if (borrower) { + console.log(`borrower address: ${borrower.address}`); + } else { + throw new Error("Can't find available borrower!"); + } + + let amount = BN.from(10000).mul(BN.from(10).pow(BN.from(decimals))); + await usdc.mint(payer.address, amount); + await usdc.connect(payer).approve(usdcx.address, amount); + await usdcx.connect(payer).upgrade(amount); + + const streamAmount = BN.from(800).mul(BN.from(10).pow(BN.from(decimals))); + const streamDays = 10; + const streamDuration = streamDays * 24 * 3600; + + let flowrate = streamAmount.div(BN.from(streamDuration)); + await createFlow(usdcx, payer, borrower, flowrate); + + await authorizeFlow(usdcx, payer, nft); + + // deposit by lender + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool deposit *"); + console.log("*******************************************************************"); + console.log(`\n`); + + let balance = await usdc.balanceOf(lender.address); + let depositAmount = BN.from(10000).mul(BN.from(10).pow(BN.from(decimals))); + if (balance.lt(depositAmount)) { + await usdc.mint(lender.address, depositAmount); + } + console.log(`lender usdc amount before deposit: ${await usdc.balanceOf(lender.address)}`); + + await usdc.connect(lender).approve(pool.address, depositAmount); + await pool.connect(lender).deposit(depositAmount); + + console.log(`lender usdc amount after deposit: ${await usdc.balanceOf(lender.address)}`); + console.log(`lender hdt amount after deposit: ${await hdt.balanceOf(lender.address)}`); + + // borrow + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool borrow *"); + console.log("*******************************************************************"); + console.log(`\n`); + + const collateralAmount = BN.from(500).mul(BN.from(10).pow(BN.from(decimals))); + flowrate = collateralAmount.div(BN.from(streamDuration)).add(BN.from(1)); + await nft.connect(borrower).mint(usdcx.address, payer.address, flowrate, streamDuration); + const streamId = (await nft.balanceOf(borrower.address)).sub(BN.from(1)); + + await nft.connect(borrower).approve(pool.address, streamId); + + let creditLimit = BN.from(1000).mul(BN.from(10).pow(BN.from(decimals))); + await pool + .connect(eaService) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + streamAmount, + streamDays, + 1, + 1217, + nft.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + streamAmount + ); + await usdc.connect(borrower).approve(pool.address, streamAmount.mul(BN.from(2))); + + let beforeAmount = await usdc.balanceOf(borrower.address); + await pool.connect(borrower).drawdownWithReceivable(collateralAmount, nft.address, streamId); + let afterAmount = await usdc.balanceOf(borrower.address); + console.log(`${borrower.address} borrowed amount: ${afterAmount.sub(beforeAmount)}`); + cr = await displayCreditRecord(pool, borrower); + + // makePayment by borrower + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool makePayment by borrower *"); + console.log("*******************************************************************"); + console.log(`\n`); + + beforeAmount = cr.totalDue; + let paymentAmount = BN.from(10).mul(BN.from(10).pow(BN.from(decimals))); + await pool.connect(borrower).makePayment(borrower.address, paymentAmount); + cr = await displayCreditRecord(pool, borrower); + if (beforeAmount.sub(cr.totalDue).lt(paymentAmount)) { + throw new Error("totalDue decrease is less than payment amount!"); + } + + // makePayment by PDS + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool makePayment by PDS *"); + console.log("*******************************************************************"); + console.log(`\n`); + + beforeAmount = cr.totalDue; + paymentAmount = BN.from(10).mul(BN.from(10).pow(BN.from(decimals))); + await pool.connect(pdsService).makePayment(borrower.address, paymentAmount); + cr = await displayCreditRecord(pool, borrower); + if (beforeAmount.sub(cr.totalDue).lt(paymentAmount)) { + throw new Error("totalDue decrease is less than payment amount!"); + } + + // payoff + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool payoff *"); + console.log("*******************************************************************"); + console.log(`\n`); + + await advanceClock(streamDays); + + await pool.payoff(nft.address, streamId); + cr = await displayCreditRecord(pool, borrower); + if (cr.totalDue > 0 || cr.unbilledPrincipal > 0 || cr.state > 3) { + throw new Error("Data is wrong after payoff!"); + } + + // TODO onReceivedPayment with review + + // withdraw by lender + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool withdraw *"); + console.log("*******************************************************************"); + console.log(`\n`); + + await poolConfig.connect(poolOwner).setWithdrawalLockoutPeriod(0); + + amount = await hdt.withdrawableFundsOf(lender.address); + console.log(`lender ${lender.address} withdrawable amount: ${amount}`); + if (amount < depositAmount) { + throw new Error("Withrawable amount is less than deposit amount!"); + } + beforeAmount = await usdc.balanceOf(lender.address); + await pool.connect(lender).withdraw(amount); + afterAmount = await usdc.balanceOf(lender.address); + console.log(`withdrawn amount: ${afterAmount.sub(beforeAmount)}`); + if (afterAmount.sub(beforeAmount).lt(amount)) { + throw new Error("Withrawn amount is less than withdrawable amount!"); + } +} + +async function verificationTest(network) { + console.log("forking network : ", network); + + await prepare(network); + await verifySuperfluidFactoringPool(); + + console.log("\n"); +} + +verificationTest(NETWORK) + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/deployment/goerli/verify-goerli-superfluid-factoring-pool.js b/deployment/goerli/verify-goerli-superfluid-factoring-pool.js new file mode 100644 index 00000000..e5292ea5 --- /dev/null +++ b/deployment/goerli/verify-goerli-superfluid-factoring-pool.js @@ -0,0 +1,167 @@ +const execSync = require("child_process").execSync; +const {getDeployedContracts, getVerifiedContract, updateVerifiedContract} = require("../utils.js"); + +const fs = require("fs"); + +const VERIFY_ARGS_PATH = "./deployment/goerli/verify_args/"; + +const HUMA_OWNER_MULTI_SIG = "0x1931bD73055335Ba06efB22DB96169dbD4C5B4DB"; +const POOL_OWNER_MULTI_SIG = "0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA"; + +const SF_USDC_ADDRESS = "0xc94dd466416A7dFE166aB2cF916D3875C049EBB7"; +const SF_HOST_ADDRESS = "0x22ff293e14F1EC3A09B137e9e06084AFd63adDF9"; + +let deployedContracts, proxyOwner, network, deployer; + +const getArgsFile = async function (contractName) { + const argsFile = `${VERIFY_ARGS_PATH}${contractName}.js`; + return argsFile; +}; + +const writeVerifyArgs = async function (contractName, args) { + const argsFile = await getArgsFile(contractName); + let data = `module.exports = [ + ${args.toString()}, + ];`; + // console.log(data) + await fs.mkdir(`${VERIFY_ARGS_PATH}`, {recursive: true}, (err) => { + if (err) throw err; + }); + fs.writeFileSync(argsFile, data, {flag: "w"}); + return argsFile; +}; + +const sleep = (ms) => new Promise((res) => setTimeout(res, ms)); + +async function etherscanVerify(contractName, contractAddress, argsFile, logMessage) { + await sleep(5000); + logMessage = !logMessage ? contractAddress : logMessage; + console.log(`Verifying ${contractName}:${logMessage}`); + + const command = !argsFile + ? `yarn hardhat verify '${contractAddress}' --network ${network}` + : `yarn hardhat verify ${contractAddress} --constructor-args ${argsFile} --network ${network}`; + let result; + try { + const verifyResult = execSync(command); + // console.log(verifyResult); + result = "successful"; + } catch (error) { + if (!error.toString().toLowerCase().includes("already verified")) { + throw error; + } else { + result = "already verified"; + } + } + console.log(`Verifying ${contractName}:${logMessage} ended!`); + return result; +} + +async function verifyContract(contractKey, args) { + const verified = await getVerifiedContract(contractKey); + if (verified) { + console.log(`${contractKey} is already verified!`); + return "already verified"; + } + + if (!deployedContracts[contractKey]) { + throw new Error(`${contractKey} not deployed yet!`); + } + let result; + if (args) { + const argsFile = await writeVerifyArgs(contractKey, args); + result = await etherscanVerify(contractKey, deployedContracts[contractKey], argsFile); + } else { + result = await etherscanVerify(contractKey, deployedContracts[contractKey]); + } + await updateVerifiedContract(contractKey); + return result; +} + +async function verifyContracts() { + network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + deployedContracts = await getDeployedContracts(); + const accounts = await hre.ethers.getSigners(); + if (accounts.length == 0) { + throw new Error("Accounts not set!"); + } + deployer = await accounts[0]; + proxyOwner = await accounts[1]; + console.log("proxyOwner address: " + proxyOwner.address); + + // const verifyUsdc = await verifyContract('USDC'); + // console.log(`Verify USDC result: ${verifyUsdc}`); + + // const verifyEANFT = await verifyContract('EANFT'); + // console.log(`Verify EANFT result: ${verifyEANFT}`); + + const verifyTradableStream = await verifyContract("SuperfluidTradableStream", [ + `'${SF_HOST_ADDRESS}'`, + ]); + console.log(`Verify SuperfluidTradableStream result: ${verifyTradableStream}`); + + // const verifyHumaConfig = await verifyContract("HumaConfig"); + // console.log(`Verify HumaConfig result: ${verifyHumaConfig}`); + + // const verifyHumaConfigTL = await verifyContract("HumaConfigTimelock", [ + // 0, + // `['${HUMA_OWNER_MULTI_SIG}']`, + // `['${deployer.address}']`, + // ]); + // console.log(`Verify HumaConfigTimelock result: ${verifyHumaConfigTL}`); + + const verifySuperfluidFactoringPoolTL = await verifyContract( + "SuperfluidFactoringPoolTimelock", + [0, `['${POOL_OWNER_MULTI_SIG}']`, `['${deployer.address}']`] + ); + console.log( + `Verify SuperfluidFactoringPoolTimelock result: ${verifySuperfluidFactoringPoolTL}` + ); + + const verifyrSuperfluidFactoringPoolProxyAdminTL = await verifyContract( + "SuperfluidFactoringPoolProxyAdminTimelock", + [0, `['${POOL_OWNER_MULTI_SIG}']`, `['${deployer.address}']`] + ); + console.log( + `Verify SuperfluidFactoringPoolProxyAdminTimelock result: ${verifyrSuperfluidFactoringPoolProxyAdminTL}` + ); + + const verifyFeeManager = await verifyContract("SuperfluidFactoringPoolFeeManager"); + console.log(`Verify FeeManager result: ${verifyFeeManager}`); + + const verifyHDTImpl = await verifyContract("SuperfluidPoolHDTImpl"); + console.log(`Verify SuperfluidPoolHDTImpl result: ${verifyHDTImpl}`); + + const verifyHDT = await verifyContract("SuperfluidPoolHDT", [ + `'${deployedContracts["SuperfluidPoolHDTImpl"]}'`, + `'${deployedContracts["SuperfluidFactoringPoolProxyAdminTimelock"]}'`, + "[]", + ]); + console.log(`Verify SuperfluidPoolHDT result: ${verifyHDT}`); + + const verifyPoolConfig = await verifyContract("SuperfluidFactoringPoolConfig"); + console.log(`Verify SuperfluidFactoringPoolConfig result: ${verifyPoolConfig}`); + + const verifyPoolImpl = await verifyContract("SuperfluidFactoringPoolImpl"); + console.log(`Verify SuperfluidFactoringPoolImpl result: ${verifyPoolImpl}`); + + const verifyPool = await verifyContract("SuperfluidFactoringPool", [ + `'${deployedContracts["SuperfluidFactoringPoolImpl"]}'`, + `'${deployedContracts["SuperfluidFactoringPoolProxyAdminTimelock"]}'`, + "[]", + ]); + console.log(`Verify SuperfluidFactoringPool result: ${verifyPool}`); + + const verifyMultisend = await verifyContract("Multisend"); + console.log(`Verify Multisend result: ${verifyMultisend}`); +} + +verifyContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); + +// Reason: Already Verified diff --git a/deployment/goerli/verify_args/HumaConfigTimelock.js b/deployment/goerli/verify_args/HumaConfigTimelock.js new file mode 100644 index 00000000..fbe138ee --- /dev/null +++ b/deployment/goerli/verify_args/HumaConfigTimelock.js @@ -0,0 +1,3 @@ +module.exports = [ + 0,['0x60891b087E81Ee2a61B7606f68019ec112c539B9'],['0x60891b087E81Ee2a61B7606f68019ec112c539B9'], + ]; \ No newline at end of file diff --git a/deployment/goerli/verify_args/SuperfluidFactoringPool.js b/deployment/goerli/verify_args/SuperfluidFactoringPool.js new file mode 100644 index 00000000..dfa08916 --- /dev/null +++ b/deployment/goerli/verify_args/SuperfluidFactoringPool.js @@ -0,0 +1,3 @@ +module.exports = [ + '0x613D52C29f2132E842cB3cE30483FF2460356678','0xc6a12f3606A9229CAC6573b9Af58F10a8Fa1B4AD',[], + ]; \ No newline at end of file diff --git a/deployment/goerli/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js b/deployment/goerli/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js new file mode 100644 index 00000000..979ae7a3 --- /dev/null +++ b/deployment/goerli/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js @@ -0,0 +1,3 @@ +module.exports = [ + 0,['0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA'],['0x60891b087E81Ee2a61B7606f68019ec112c539B9'], + ]; \ No newline at end of file diff --git a/deployment/goerli/verify_args/SuperfluidFactoringPoolTimelock.js b/deployment/goerli/verify_args/SuperfluidFactoringPoolTimelock.js new file mode 100644 index 00000000..979ae7a3 --- /dev/null +++ b/deployment/goerli/verify_args/SuperfluidFactoringPoolTimelock.js @@ -0,0 +1,3 @@ +module.exports = [ + 0,['0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA'],['0x60891b087E81Ee2a61B7606f68019ec112c539B9'], + ]; \ No newline at end of file diff --git a/deployment/goerli/verify_args/SuperfluidPoolHDT.js b/deployment/goerli/verify_args/SuperfluidPoolHDT.js new file mode 100644 index 00000000..0543910e --- /dev/null +++ b/deployment/goerli/verify_args/SuperfluidPoolHDT.js @@ -0,0 +1,3 @@ +module.exports = [ + '0x6548f5146c8deA61C4C7269988DDfB22BC431cd2','0xc6a12f3606A9229CAC6573b9Af58F10a8Fa1B4AD',[], + ]; \ No newline at end of file diff --git a/deployment/goerli/verify_args/SuperfluidTradableStream.js b/deployment/goerli/verify_args/SuperfluidTradableStream.js new file mode 100644 index 00000000..08b1855b --- /dev/null +++ b/deployment/goerli/verify_args/SuperfluidTradableStream.js @@ -0,0 +1,3 @@ +module.exports = [ + '0xEB796bdb90fFA0f28255275e16936D25d3418603', + ]; \ No newline at end of file diff --git a/deployment/maticmum-deployed-contracts.json b/deployment/maticmum-deployed-contracts.json new file mode 100644 index 00000000..426e42df --- /dev/null +++ b/deployment/maticmum-deployed-contracts.json @@ -0,0 +1,18 @@ +{ + "HumaConfig": "0xc8eE3e49b060b118413F2493D30fB5666AeD8A2E", + "HumaConfigTimelock": "0x4d04FA40f2cb094439a78F0bEBa3763b82255b04", + "SuperfluidFactoringPoolTimelock": "0x562826a357377128cd2Ef4eCA367b68710EF8F45", + "SuperfluidFactoringPoolProxyAdminTimelock": "0x63B0Cd5aB037939269027B8687B6Ff2d3Cb67F10", + "SuperfluidFactoringPoolFeeManager": "0x69824d6d54ac67C6b18F509802b3B09bd46A3D71", + "SuperfluidPoolHDTImpl": "0xA168879fC4D4932f0EB0a5FeBeFc5Acc66FEe2AC", + "SuperfluidPoolHDT": "0xEf86bB7e7b059C78BC50679c5CA92A835a2f7CE1", + "SuperfluidFactoringPoolConfig": "0x2Cd56e0d786d87d1dA78c1eb2a1A0c86762685cC", + "SuperfluidFactoringPoolImpl": "0x48AC68d5F996eD3C6a6Bb916A121552dD01C87A1", + "SuperfluidFactoringPool": "0xC5BF9750A7BF93479990EF940d7e3984caa22558", + "SuperfluidProcessorImpl": "0xDaD5A07c3a5737A546b15aE72436d049da6702ff", + "SuperfluidProcessor": "0xA529F930273c58d557475c206cBE85903fDee65b", + "EANFT": "0xea477cD203d3F7c0b2F7B5E9B34c439c6057dfD7", + "SuperfluidTradableStream": "0x3ad49C053DCDF96788c0e40c1771d41422ddBb6A", + "Multisend": "0x174aBAE032174a4bfd3eE63Cb62626a6fcE457ed", + "MockSuperAppRegister": "0xdb4E4010810Da955E385E4b7682279237acF61Db" +} diff --git a/deployment/maticmum-initialized-contracts.json b/deployment/maticmum-initialized-contracts.json new file mode 100644 index 00000000..11e33179 --- /dev/null +++ b/deployment/maticmum-initialized-contracts.json @@ -0,0 +1,6 @@ +{"HumaConfig":"Done", +"SuperfluidFactoringPoolFeeManager":"Done", +"SuperfluidPoolHDT":"Done", +"EANFT":"Done", +"SuperfluidFactoringPoolConfig":"Done", +"SuperfluidFactoringPool":"Done"} \ No newline at end of file diff --git a/deployment/maticmum-verified-contracts.json b/deployment/maticmum-verified-contracts.json new file mode 100644 index 00000000..a06d8e01 --- /dev/null +++ b/deployment/maticmum-verified-contracts.json @@ -0,0 +1,17 @@ +{ + "EANFT": "Done", + "SuperfluidTradableStream": "Done", + "HumaConfig": "Done", + "HumaConfigTimelock": "Done", + "SuperfluidFactoringPoolTimelock": "Done", + "SuperfluidFactoringPoolProxyAdminTimelock": "Done", + "SuperfluidFactoringPoolFeeManager": "Done", + "SuperfluidPoolHDTImpl": "Done", + "SuperfluidPoolHDT": "Done", + "SuperfluidFactoringPoolConfig": "Done", + "SuperfluidFactoringPoolImpl": "Done", + "SuperfluidFactoringPool": "Done", + "SuperfluidProcessorImpl": "Done", + "Multisend": "Done", + "MockSuperAppRegister": "Done" +} diff --git a/deployment/mumbai/deploy-superfluid-factoring-pool.js b/deployment/mumbai/deploy-superfluid-factoring-pool.js new file mode 100644 index 00000000..693e7f45 --- /dev/null +++ b/deployment/mumbai/deploy-superfluid-factoring-pool.js @@ -0,0 +1,82 @@ +const {deploy} = require("../utils.js"); + +const HUMA_OWNER_MULTI_SIG = "0x1931bD73055335Ba06efB22DB96169dbD4C5B4DB"; +const POOL_OWNER_MULTI_SIG = "0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA"; + +const SF_USDC_ADDRESS = "0xbe49ac1EadAc65dccf204D4Df81d650B50122aB2"; +const SF_HOST_ADDRESS = "0xEB796bdb90fFA0f28255275e16936D25d3418603"; + +async function deployContracts() { + const network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + const accounts = await hre.ethers.getSigners(); + if (accounts.length == 0) { + throw new Error("Accounts not set!"); + } + const deployer = await accounts[0]; + console.log("deployer address: " + deployer.address); + const proxyOwner = await accounts[1]; + + const eaService = await accounts[4]; + console.log("ea service address: " + eaService.address); + + // Deploying Superfluid factoring pool + + const humaConfig = await deploy("HumaConfig", "HumaConfig"); + const humaConfigTL = await deploy("TimelockController", "HumaConfigTimelock", [ + 0, + [HUMA_OWNER_MULTI_SIG], + [deployer.address], + ]); + + const superfluidFactoringPoolTL = await deploy( + "TimelockController", + "SuperfluidFactoringPoolTimelock", + [0, [POOL_OWNER_MULTI_SIG], [deployer.address]] + ); + + const superfluidFactoringPoolProxyAdminTL = await deploy( + "TimelockController", + "SuperfluidFactoringPoolProxyAdminTimelock", + [0, [POOL_OWNER_MULTI_SIG], [deployer.address]] + ); + + const feeManager = await deploy("SuperfluidFeeManager", "SuperfluidFactoringPoolFeeManager"); + const hdtImpl = await deploy("HDT", "SuperfluidPoolHDTImpl"); + const hdt = await deploy("TransparentUpgradeableProxy", "SuperfluidPoolHDT", [ + hdtImpl.address, + superfluidFactoringPoolProxyAdminTL.address, + [], + ]); + + const poolConfig = await deploy("BasePoolConfig", "SuperfluidFactoringPoolConfig"); + + const poolImpl = await deploy("ReceivableFactoringPoolV2", "SuperfluidFactoringPoolImpl"); + const pool = await deploy("TransparentUpgradeableProxy", "SuperfluidFactoringPool", [ + poolImpl.address, + superfluidFactoringPoolProxyAdminTL.address, + [], + ]); + + const processorImpl = await deploy("SuperfluidPoolProcessor", "SuperfluidProcessorImpl"); + const processor = await deploy("TransparentUpgradeableProxy", "SuperfluidProcessor", [ + processorImpl.address, + superfluidFactoringPoolProxyAdminTL.address, + [], + ]); + + const evaluationAgentNFT = await deploy("EvaluationAgentNFT", "EANFT", [], eaService); + + const tradableStream = await deploy("TradableStream", "SuperfluidTradableStream", [ + SF_HOST_ADDRESS, + ]); + + await deploy("Multisend", "Multisend"); +} + +deployContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/deployment/mumbai/deploy-superfluid-mock-super-app-register.js b/deployment/mumbai/deploy-superfluid-mock-super-app-register.js new file mode 100644 index 00000000..3b3afa72 --- /dev/null +++ b/deployment/mumbai/deploy-superfluid-mock-super-app-register.js @@ -0,0 +1,28 @@ +const {deploy} = require("../utils.js"); + +const MUMBAI_SF_HOST_ADDRESS = "0xEB796bdb90fFA0f28255275e16936D25d3418603"; + +async function deployContracts() { + const network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + const accounts = await hre.ethers.getSigners(); + if (accounts.length == 0) { + throw new Error("Accounts not set!"); + } + const deployer = await accounts[0]; + console.log("deployer address: " + deployer.address); + + const eaService = await accounts[4]; + console.log("ea service address: " + eaService.address); + + const MockSuperAppRegister = await deploy("MockSuperAppRegister", "MockSuperAppRegister", [ + MUMBAI_SF_HOST_ADDRESS, + ]); +} + +deployContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/deployment/mumbai/init-superfluid-factoring-pool.js b/deployment/mumbai/init-superfluid-factoring-pool.js new file mode 100644 index 00000000..762fdcc4 --- /dev/null +++ b/deployment/mumbai/init-superfluid-factoring-pool.js @@ -0,0 +1,457 @@ +const {BigNumber: BN} = require("ethers"); +const { + getInitilizedContract, + updateInitilizedContract, + getDeployedContracts, + sendTransaction, +} = require("../utils.js"); + +let deployer, + deployedContracts, + lender, + ea_sfp, + eaService, + pdsService, + treasury, + sfpOperator, + sfpOwnerTreasury, + payer; + +const SF_FUSDC_ADDRESS = "0xbe49ac1EadAc65dccf204D4Df81d650B50122aB2"; +const SF_HOST_ADDRESS = "0xEB796bdb90fFA0f28255275e16936D25d3418603"; +const SF_CFA_ADDRESS = "0x49e565Ed1bdc17F3d220f72DF0857C26FA83F873"; + +const USDC_ADDRESS = SF_FUSDC_ADDRESS; + +const HUMA_OWNER_MULTI_SIG = "0x1931bD73055335Ba06efB22DB96169dbD4C5B4DB"; +const POOL_OWNER_MULTI_SIG = "0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA"; + +async function transferOwnershipToTL(contractName, contractKey, timeLockKey) { + if (!deployedContracts[timeLockKey]) { + throw new Error(`${timeLockKey} not deployed yet!`); + } + + if (!deployedContracts[contractKey]) { + throw new Error(`${contractKey} not deployed yet!`); + } + + const TimeLockController = await hre.ethers.getContractFactory("TimelockController"); + const timeLockController = TimeLockController.attach(deployedContracts[timeLockKey]); + + const Contract = await hre.ethers.getContractFactory(contractName); + const contract = Contract.attach(deployedContracts[contractKey]); + + await sendTransaction(contractKey, contract, "transferOwnership", [ + timeLockController.address, + ]); + + const adminRole = await timeLockController.TIMELOCK_ADMIN_ROLE(); + await sendTransaction(contractKey, timeLockController, "renounceRole", [ + adminRole, + deployer.address, + ]); +} + +async function initHumaConfig() { + const initilized = await getInitilizedContract("HumaConfig"); + if (initilized) { + console.log("HumaConfig is already initialized!"); + return; + } + + if (!deployedContracts["HumaConfig"]) { + throw new Error("HumaConfig not deployed yet!"); + } + + if (!deployedContracts["HumaConfigTimelock"]) { + throw new Error("HumaConfigTimelock not deployed yet!"); + } + + if (!deployedContracts["EANFT"]) { + throw new Error("EANFT not deployed yet!"); + } + + const HumaConfig = await hre.ethers.getContractFactory("HumaConfig"); + const humaConfig = HumaConfig.attach(deployedContracts["HumaConfig"]); + + const TimelockController = await hre.ethers.getContractFactory("TimelockController"); + const humaConfigTL = TimelockController.attach(deployedContracts["HumaConfigTimelock"]); + + await sendTransaction("HumaConfig", humaConfig, "setProtocolDefaultGracePeriod", [ + 30 * 24 * 3600, + ]); + await sendTransaction("HumaConfig", humaConfig, "setTreasuryFee", [500]); + await sendTransaction("HumaConfig", humaConfig, "setEANFTContractAddress", [ + deployedContracts["EANFT"], + ]); + + await sendTransaction("HumaConfig", humaConfig, "setEAServiceAccount", [eaService.address]); + await sendTransaction("HumaConfig", humaConfig, "setPDSServiceAccount", [pdsService.address]); + + // Add usdc as an asset supported by the protocol + await sendTransaction("HumaConfig", humaConfig, "setLiquidityAsset", [USDC_ADDRESS, true]); + + // Set treasury for the protocol + await sendTransaction("HumaConfig", humaConfig, "setHumaTreasury", [treasury.address]); + + // Notice: Gnosis Safe doesn't support Mumbai now + // await transferOwnershipToTL("HumaConfig", "HumaConfig", "HumaConfigTimelock"); + + await updateInitilizedContract("HumaConfig"); +} + +async function initFeeManager() { + const initilized = await getInitilizedContract("SuperfluidFactoringPoolFeeManager"); + if (initilized) { + console.log("SuperfluidFactoringPoolFeeManager is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidFactoringPoolFeeManager"]) { + throw new Error("SuperfluidFactoringPoolFeeManager not deployed yet!"); + } + + const SuperfluidFeeManager = await hre.ethers.getContractFactory("SuperfluidFeeManager"); + const feeManager = SuperfluidFeeManager.attach( + deployedContracts["SuperfluidFactoringPoolFeeManager"] + ); + + // await sendTransaction( + // "SuperfluidFactoringPoolFeeManager", + // feeManager, + // "setFees", + // [0, 0, 0, 0, 0] + // ); + // await sendTransaction( + // "SuperfluidFactoringPoolFeeManager", + // feeManager, + // "setMinPrincipalRateInBps", + // [0] + // ); + + await updateInitilizedContract("SuperfluidFactoringPoolFeeManager"); +} + +async function initHDT() { + const initilized = await getInitilizedContract("SuperfluidPoolHDT"); + if (initilized) { + console.log("SuperfluidPoolHDT is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidPoolHDT"]) { + throw new Error("SuperfluidPoolHDT not deployed yet!"); + } + + const HDT = await hre.ethers.getContractFactory("HDT"); + const hdt = HDT.attach(deployedContracts["SuperfluidPoolHDT"]); + + if (!deployedContracts["SuperfluidFactoringPool"]) { + throw new Error("SuperfluidFactoringPool not deployed yet!"); + } + + await sendTransaction("SuperfluidPoolHDT", hdt, "initialize", [ + "Superfluid HDT", + "SFHDT", + USDC_ADDRESS, + ]); + + await sendTransaction("SuperfluidPoolHDT", hdt, "setPool", [ + deployedContracts["SuperfluidFactoringPool"], + ]); + + // Notice: Gnosis Safe doesn't support Mumbai now + // await transferOwnershipToTL("HDT", "SuperfluidPoolHDT", "SuperfluidFactoringPoolTimelock"); + + await updateInitilizedContract("SuperfluidPoolHDT"); +} + +async function initEA() { + const initilized = await getInitilizedContract("EANFT"); + if (initilized) { + console.log("EANFT is already initialized!"); + return; + } + + if (!deployedContracts["EANFT"]) { + throw new Error("EANFT not deployed yet!"); + } + + const EANFT = await hre.ethers.getContractFactory("EvaluationAgentNFT"); + const eaNFT = EANFT.attach(deployedContracts["EANFT"]); + + const eaNFTFromEA = eaNFT.connect(ea_sfp); + await sendTransaction("EvaluationAgentNFT", eaNFTFromEA, "mintNFT", [ea_sfp.address]); + await updateInitilizedContract("EANFT"); +} + +async function initPoolConfig() { + const initilized = await getInitilizedContract("SuperfluidFactoringPoolConfig"); + if (initilized) { + console.log("SuperfluidFactoringPoolConfig is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidFactoringPoolConfig"]) { + throw new Error("SuperfluidFactoringPoolConfig not deployed yet!"); + } + + const BasePoolConfig = await hre.ethers.getContractFactory("BasePoolConfig"); + const poolConfig = BasePoolConfig.attach(deployedContracts["SuperfluidFactoringPoolConfig"]); + + if (!deployedContracts["SuperfluidFactoringPool"]) { + throw new Error("SuperfluidFactoringPool not deployed yet!"); + } + + if (!deployedContracts["SuperfluidPoolHDT"]) { + throw new Error("SuperfluidPoolHDT not deployed yet!"); + } + + if (!deployedContracts["HumaConfig"]) { + throw new Error("HumaConfig not deployed yet!"); + } + + if (!deployedContracts["SuperfluidFactoringPoolFeeManager"]) { + throw new Error("SuperfluidFactoringPoolFeeManager not deployed yet!"); + } + + const HDT = await hre.ethers.getContractFactory("HDT"); + const hdt = HDT.attach(deployedContracts["SuperfluidPoolHDT"]); + + const HumaConfig = await hre.ethers.getContractFactory("HumaConfig"); + const humaConfig = HumaConfig.attach(deployedContracts["HumaConfig"]); + + const SuperfluidFeeManager = await hre.ethers.getContractFactory("SuperfluidFeeManager"); + const feeManager = SuperfluidFeeManager.attach( + deployedContracts["SuperfluidFactoringPoolFeeManager"] + ); + + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "initialize", [ + "SuperfluidFactoringPool", + hdt.address, + humaConfig.address, + feeManager.address, + ]); + + const decimals = await hdt.decimals(); + const cap = BN.from(1_000_000).mul(BN.from(10).pow(BN.from(decimals))); + console.log("cap: " + cap); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPoolLiquidityCap", [ + cap, + ]); + + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPool", [ + deployedContracts["SuperfluidFactoringPool"], + ]); + console.log(`ea_sfp: ${ea_sfp.address}`); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setEvaluationAgent", [ + 1, + ea_sfp.address, + ]); + + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setPoolOwnerRewardsAndLiquidity", + [500, 200] + ); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setEARewardsAndLiquidity", + [1000, 100] + ); + const maxCL = BN.from(1_000).mul(BN.from(10).pow(BN.from(decimals))); + console.log("maxCL: " + maxCL); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setMaxCreditLine", [ + maxCL, + ]); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setAPR", [0]); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setReceivableRequiredInBps", + [10000] + ); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPoolPayPeriod", [30]); + await sendTransaction("SuperfluidFactoringPoolConfig", poolConfig, "setPoolToken", [ + deployedContracts["SuperfluidPoolHDT"], + ]); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setWithdrawalLockoutPeriod", + [90] + ); + await sendTransaction( + "SuperfluidFactoringPoolConfig", + poolConfig, + "setPoolDefaultGracePeriod", + [60] + ); + + await sendTransaction("ReceivableFactoringPoolConfig", poolConfig, "addPoolOperator", [ + sfpOperator.address, + ]); + await sendTransaction("ReceivableFactoringPoolConfig", poolConfig, "setPoolOwnerTreasury", [ + sfpOwnerTreasury.address, + ]); + + // Notice: Gnosis Safe doesn't support Mumbai now + // await transferOwnershipToTL( + // "BasePoolConfig", + // "SuperfluidFactoringPoolConfig", + // "SuperfluidFactoringPoolTimelock" + // ); + + await updateInitilizedContract("SuperfluidFactoringPoolConfig"); +} + +async function initPool() { + const initilized = await getInitilizedContract("SuperfluidFactoringPool"); + if (initilized) { + console.log("SuperfluidFactoringPool is already initialized!"); + return; + } + + if (!deployedContracts["SuperfluidFactoringPool"]) { + throw new Error("SuperfluidFactoringPool not deployed yet!"); + } + + if (!deployedContracts["SuperfluidFactoringPoolConfig"]) { + throw new Error("SuperfluidFactoringPoolConfig not deployed yet!"); + } + + if (!deployedContracts["SuperfluidProcessor"]) { + throw new Error("SuperfluidProcessor not deployed yet!"); + } + + if (!deployedContracts["SuperfluidTradableStream"]) { + throw new Error("SuperfluidTradableStream not deployed yet!"); + } + + const ReceivableFactoringPoolV2 = await hre.ethers.getContractFactory( + "ReceivableFactoringPoolV2" + ); + const pool = ReceivableFactoringPoolV2.attach(deployedContracts["SuperfluidFactoringPool"]); + + await sendTransaction("SuperfluidFactoringPool", pool, "initialize(address,address)", [ + deployedContracts["SuperfluidFactoringPoolConfig"], + deployedContracts["SuperfluidProcessor"], + ]); + + const SuperfluidPoolProcessor = await hre.ethers.getContractFactory("SuperfluidPoolProcessor"); + const processor = SuperfluidPoolProcessor.attach(deployedContracts["SuperfluidProcessor"]); + + await sendTransaction( + "SuperfluidProcessor", + processor, + "initialize(address,address,address,address)", + [ + deployedContracts["SuperfluidFactoringPool"], + SF_HOST_ADDRESS, + SF_CFA_ADDRESS, + deployedContracts["SuperfluidTradableStream"], + ] + ); + + await updateInitilizedContract("SuperfluidFactoringPool"); +} + +async function prepare() { + if (!deployedContracts["SuperfluidFactoringPool"]) { + throw new Error("SuperfluidFactoringPool not deployed yet!"); + } + + const ReceivableFactoringPoolV2 = await hre.ethers.getContractFactory( + "ReceivableFactoringPoolV2" + ); + const pool = ReceivableFactoringPoolV2.attach(deployedContracts["SuperfluidFactoringPool"]); + const poolFromOperator = pool.connect(sfpOperator); + + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + deployer.address, + ]); + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + ea_sfp.address, + ]); + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + lender.address, + ]); + await sendTransaction("SuperfluidFactoringPool", poolFromOperator, "addApprovedLender", [ + sfpOwnerTreasury.address, + ]); + + const USDC = await hre.ethers.getContractFactory("TestToken"); + const usdc = USDC.attach(USDC_ADDRESS); + const decimals = await usdc.decimals(); + + // Owner + const usdcFromPoolOwnerTreasury = await usdc.connect(sfpOwnerTreasury); + const poolFromPoolOwnerTreasury = await pool.connect(sfpOwnerTreasury); + const amountOwner = BN.from(20_000).mul(BN.from(10).pow(BN.from(decimals))); + await sendTransaction("TestToken", usdc, "mint", [sfpOwnerTreasury.address, amountOwner]); + await sendTransaction("TestToken", usdcFromPoolOwnerTreasury, "approve", [ + pool.address, + amountOwner, + ]); + await sendTransaction( + "SuperfluidFactoringPool", + poolFromPoolOwnerTreasury, + "makeInitialDeposit", + [amountOwner] + ); + + // EA + const usdcFromEA = await usdc.connect(ea_sfp); + const poolFromEA = await pool.connect(ea_sfp); + const amountEA = BN.from(10_000).mul(BN.from(10).pow(BN.from(decimals))); + await sendTransaction("TestToken", usdc, "mint", [ea_sfp.address, amountEA]); + await sendTransaction("TestToken", usdcFromEA, "approve", [pool.address, amountEA]); + await sendTransaction("SuperfluidFactoringPool", poolFromEA, "makeInitialDeposit", [amountEA]); + + await sendTransaction("SuperfluidFactoringPool", pool, "enablePool", []); + + //payer + const amountPayer = BN.from(100_000_000).mul(BN.from(10).pow(BN.from(decimals))); + await sendTransaction("TestToken", usdc, "mint", [payer.address, amountPayer]); +} + +async function initContracts() { + const network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + const accounts = await hre.ethers.getSigners(); + [ + deployer, + proxyOwner, + lender, + ea_sfp, + eaService, + pdsService, + treasury, + payer, + sfpOperator, + sfpOwnerTreasury, + ] = await accounts; + console.log("deployer address: " + deployer.address); + console.log("lender address: " + lender.address); + console.log("ea address: " + ea_sfp.address); + + deployedContracts = await getDeployedContracts(); + + await initHumaConfig(); + await initFeeManager(); + await initHDT(); + await initEA(); + await initPoolConfig(); + await initPool(); + + await prepare(); +} + +initContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/deployment/mumbai/verification-test-superfluid-factoring-pool.js b/deployment/mumbai/verification-test-superfluid-factoring-pool.js new file mode 100644 index 00000000..7bbe5ff7 --- /dev/null +++ b/deployment/mumbai/verification-test-superfluid-factoring-pool.js @@ -0,0 +1,371 @@ +const {getDeployedContracts, impersonate, advanceClock} = require("../utils.js"); +const {BigNumber: BN} = require("ethers"); +const {displayCreditRecord} = require("../verification-test-utils.js"); + +let chainUrl = process.env["MUMBAI_URL"]; +const MUMBAI_CHAIN_ID = 80001; + +const NETWORK = "maticmum"; +const SF_USDC_ADDRESS = "0xbe49ac1EadAc65dccf204D4Df81d650B50122aB2"; +const SF_USDCX_ADDRESS = "0x42bb40bF79730451B11f6De1CbA222F17b87Afd7"; +const SF_HOST_ADDRESS = "0xEB796bdb90fFA0f28255275e16936D25d3418603"; +const SF_CFA_ADDRESS = "0x49e565Ed1bdc17F3d220f72DF0857C26FA83F873"; + +let deployedContracts, accounts; + +let usdc, decimals, sf, usdcx, cfa, nft, multisend, nftVersion; + +let humaConfig, eaService, pdsService; + +async function createFlow(xToken, payer, payee, flowrate) { + const calldata = cfa.interface.encodeFunctionData("createFlow", [ + xToken.address, + payee.address, + flowrate, + "0x", + ]); + + await sf.connect(payer).callAgreement(cfa.address, calldata, "0x"); +} + +async function authorizeFlow(xToken, sender, operator) { + const calldata = cfa.interface.encodeFunctionData("authorizeFlowOperatorWithFullControl", [ + xToken.address, + operator.address, + "0x", + ]); + await sf.connect(sender).callAgreement(cfa.address, calldata, "0x"); +} + +async function prepare(network) { + deployedContracts = await getDeployedContracts(network); + accounts = await hre.ethers.getSigners(); + + const TestToken = await hre.ethers.getContractFactory("TestToken"); + usdc = TestToken.attach(SF_USDC_ADDRESS); + decimals = await usdc.decimals(); + + const HumaConfig = await hre.ethers.getContractFactory("HumaConfig"); + humaConfig = HumaConfig.attach(deployedContracts["HumaConfig"]); + + const eaServiceAddress = await humaConfig.eaServiceAccount(); + console.log(`ea service: ${eaServiceAddress}`); + eaService = await impersonate(eaServiceAddress); + + const pdsServiceAddress = await humaConfig.pdsServiceAccount(); + console.log(`pds service: ${pdsServiceAddress}`); + pdsService = await impersonate(pdsServiceAddress); + + sf = await ethers.getContractAt("ISuperfluid", SF_HOST_ADDRESS); + usdcx = await ethers.getContractAt("ISuperToken", SF_USDCX_ADDRESS); + cfa = await ethers.getContractAt("IConstantFlowAgreementV1", SF_CFA_ADDRESS); + + const TradableStream = await hre.ethers.getContractFactory("TradableStream"); + nft = TradableStream.attach(deployedContracts["SuperfluidTradableStream"]); + + const Multisend = await hre.ethers.getContractFactory("Multisend"); + multisend = Multisend.attach(deployedContracts["Multisend"]); + + nftVersion = await nft.version(); +} + +async function verifySuperfluidFactoringPool() { + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Prepare SuperfluidFactoringPool data *"); + console.log("*******************************************************************"); + console.log(`\n`); + + const poolOperator = accounts[0]; + const lender = accounts[1]; + const payer = accounts[2]; + console.log(`pool operator address: ${poolOperator.address}`); + console.log(`lender address: ${lender.address}`); + console.log(`payer address: ${payer.address}`); + + const BasePoolConfig = await hre.ethers.getContractFactory("BasePoolConfig"); + const poolConfig = BasePoolConfig.attach(deployedContracts["SuperfluidFactoringPoolConfig"]); + + const ReceivableFactoringPoolV2 = await hre.ethers.getContractFactory( + "ReceivableFactoringPoolV2" + ); + const pool = ReceivableFactoringPoolV2.attach(deployedContracts["SuperfluidFactoringPool"]); + + const SuperfluidPoolProcessor = await hre.ethers.getContractFactory("SuperfluidPoolProcessor"); + const processor = SuperfluidPoolProcessor.attach(deployedContracts["SuperfluidProcessor"]); + + const HDT = await hre.ethers.getContractFactory("HDT"); + const hdt = HDT.attach(deployedContracts["SuperfluidPoolHDT"]); + + const poolOwnerAddres = await poolConfig.owner(); + console.log( + `pool owner: ${poolOwnerAddres}, isOperator: ${await poolConfig.isOperator( + poolOwnerAddres + )}` + ); + const poolOwner = await impersonate(poolOwnerAddres); + + let isOperator = await poolConfig.isOperator(poolOperator.address); + if (!isOperator) { + await poolConfig.connect(poolOwner).addPoolOperator(poolOperator.address); + } + await pool.connect(poolOperator).addApprovedLender(lender.address); + + // choose borrower + + let borrower, cr; + for (let i = 3; i < 10; i++) { + cr = await pool.creditRecordMapping(accounts[i].address); + if (cr.state == 0 || cr.state == 2) { + borrower = accounts[i]; + } + // console.log(`${accounts[i].address} state: ${cr.state}`); + } + if (borrower) { + console.log(`borrower address: ${borrower.address}`); + } else { + throw new Error("Can't find available borrower!"); + } + + let amount = BN.from(10000).mul(BN.from(10).pow(BN.from(decimals))); + await usdc.mint(payer.address, amount); + await usdc.connect(payer).approve(usdcx.address, amount); + await usdcx.connect(payer).upgrade(amount); + + const streamAmount = BN.from(800).mul(BN.from(10).pow(BN.from(decimals))); + const streamDays = 10; + const streamDuration = streamDays * 24 * 3600; + + let flowrate = streamAmount.div(BN.from(streamDuration)); + await createFlow(usdcx, payer, borrower, flowrate); + + await authorizeFlow(usdcx, payer, nft); + + // deposit by lender + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool deposit *"); + console.log("*******************************************************************"); + console.log(`\n`); + + let balance = await usdc.balanceOf(lender.address); + let depositAmount = BN.from(10000).mul(BN.from(10).pow(BN.from(decimals))); + if (balance.lt(depositAmount)) { + await usdc.mint(lender.address, depositAmount); + } + console.log(`lender usdc amount before deposit: ${await usdc.balanceOf(lender.address)}`); + + await usdc.connect(lender).approve(pool.address, depositAmount); + await pool.connect(lender).deposit(depositAmount); + + console.log(`lender usdc amount after deposit: ${await usdc.balanceOf(lender.address)}`); + console.log(`lender hdt amount after deposit: ${await hdt.balanceOf(lender.address)}`); + + // borrow + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool borrow *"); + console.log("*******************************************************************"); + console.log(`\n`); + + await pool + .connect(eaService) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + streamAmount, + streamDays, + 1, + 1217, + nft.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + streamAmount + ); + + await usdc.connect(borrower).approve(processor.address, streamAmount.mul(BN.from(2))); + let collateralAmount = BN.from(500).mul(BN.from(10).pow(BN.from(decimals))); + flowrate = collateralAmount.div(BN.from(streamDuration)).add(BN.from(1)); + collateralAmount = flowrate.mul(BN.from(streamDuration)); + let nonce = await nft.nonces(borrower.address); + let expiry = Math.ceil(Date.now() / 1000) + 300; + + let signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: MUMBAI_CHAIN_ID, + verifyingContract: nft.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: processor.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + let signature = ethers.utils.splitSignature(signatureData); + + let calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + let beforeAmount = await usdc.balanceOf(borrower.address); + await multisend.multisend( + [processor.address], + [ + processor.interface.encodeFunctionData("mintAndDrawdown", [ + borrower.address, + collateralAmount, + nft.address, + calldata, + ]), + ] + ); + let afterAmount = await usdc.balanceOf(borrower.address); + console.log(`${borrower.address} borrowed amount: ${afterAmount.sub(beforeAmount)}`); + cr = await displayCreditRecord(pool, borrower); + const streamId = (await nft.balanceOf(processor.address)).sub(BN.from(1)); + console.log(`streamId: ${streamId}`); + + // makePayment by borrower + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool makePayment by borrower *"); + console.log("*******************************************************************"); + console.log(`\n`); + + await usdc.connect(borrower).approve(pool.address, streamAmount.mul(BN.from(2))); + beforeAmount = cr.totalDue; + let paymentAmount = BN.from(10).mul(BN.from(10).pow(BN.from(decimals))); + await pool.connect(borrower).makePayment(borrower.address, paymentAmount); + cr = await displayCreditRecord(pool, borrower); + if (beforeAmount.sub(cr.totalDue).lt(paymentAmount)) { + throw new Error("totalDue decrease is less than payment amount!"); + } + + // makePayment by PDS + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool makePayment by PDS *"); + console.log("*******************************************************************"); + console.log(`\n`); + + beforeAmount = cr.totalDue; + paymentAmount = BN.from(10).mul(BN.from(10).pow(BN.from(decimals))); + await pool.connect(pdsService).makePayment(borrower.address, paymentAmount); + cr = await displayCreditRecord(pool, borrower); + if (beforeAmount.sub(cr.totalDue).lt(paymentAmount)) { + throw new Error("totalDue decrease is less than payment amount!"); + } + + // payoff + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool settlement *"); + console.log("*******************************************************************"); + console.log(`\n`); + + await advanceClock(streamDays); + + await processor.settlement(nft.address, streamId); + cr = await displayCreditRecord(pool, borrower); + if (cr.totalDue > 0 || cr.unbilledPrincipal > 0 || cr.state > 3) { + throw new Error("Data is wrong after payoff!"); + } + + // TODO terminate flow + + // withdraw by lender + + console.log(`\n`); + console.log("*******************************************************************"); + console.log("* Checking SuperfluidFactoringPool withdraw *"); + console.log("*******************************************************************"); + console.log(`\n`); + + await poolConfig.connect(poolOwner).setWithdrawalLockoutPeriod(0); + + amount = await hdt.withdrawableFundsOf(lender.address); + console.log(`lender ${lender.address} withdrawable amount: ${amount}`); + if (amount < depositAmount) { + throw new Error("Withrawable amount is less than deposit amount!"); + } + beforeAmount = await usdc.balanceOf(lender.address); + await pool.connect(lender).withdraw(amount); + afterAmount = await usdc.balanceOf(lender.address); + console.log(`withdrawn amount: ${afterAmount.sub(beforeAmount)}`); + if (afterAmount.sub(beforeAmount).lt(amount)) { + throw new Error("Withrawn amount is less than withdrawable amount!"); + } +} + +async function verificationTest(network) { + await hre.network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: chainUrl, + }, + }, + ], + }); + + console.log("forking network : ", network); + + await prepare(network); + await verifySuperfluidFactoringPool(); + + console.log("\n"); +} + +verificationTest(NETWORK) + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/deployment/mumbai/verify-superfluid-factoring-pool.js b/deployment/mumbai/verify-superfluid-factoring-pool.js new file mode 100644 index 00000000..dc6888fa --- /dev/null +++ b/deployment/mumbai/verify-superfluid-factoring-pool.js @@ -0,0 +1,170 @@ +const execSync = require("child_process").execSync; +const {getDeployedContracts, getVerifiedContract, updateVerifiedContract} = require("../utils.js"); + +const fs = require("fs"); + +const VERIFY_ARGS_PATH = "./deployment/mumbai/verify_args/"; + +const HUMA_OWNER_MULTI_SIG = "0x1931bD73055335Ba06efB22DB96169dbD4C5B4DB"; +const POOL_OWNER_MULTI_SIG = "0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA"; + +const SF_USDC_ADDRESS = "0xbe49ac1EadAc65dccf204D4Df81d650B50122aB2"; +const SF_HOST_ADDRESS = "0xEB796bdb90fFA0f28255275e16936D25d3418603"; + +let deployedContracts, proxyOwner, network, deployer; + +const getArgsFile = async function (contractName) { + const argsFile = `${VERIFY_ARGS_PATH}${contractName}.js`; + return argsFile; +}; + +const writeVerifyArgs = async function (contractName, args) { + const argsFile = await getArgsFile(contractName); + let data = `module.exports = [ + ${args.toString()}, + ];`; + // console.log(data) + await fs.mkdir(`${VERIFY_ARGS_PATH}`, {recursive: true}, (err) => { + if (err) throw err; + }); + fs.writeFileSync(argsFile, data, {flag: "w"}); + return argsFile; +}; + +const sleep = (ms) => new Promise((res) => setTimeout(res, ms)); + +async function etherscanVerify(contractName, contractAddress, argsFile, logMessage) { + await sleep(5000); + logMessage = !logMessage ? contractAddress : logMessage; + console.log(`Verifying ${contractName}:${logMessage}`); + + const command = !argsFile + ? `yarn hardhat verify '${contractAddress}' --network ${network}` + : `yarn hardhat verify ${contractAddress} --constructor-args ${argsFile} --network ${network}`; + let result; + try { + const verifyResult = execSync(command); + // console.log(verifyResult); + result = "successful"; + } catch (error) { + if (!error.toString().toLowerCase().includes("already verified")) { + throw error; + } else { + result = "already verified"; + } + } + console.log(`Verifying ${contractName}:${logMessage} ended!`); + return result; +} + +async function verifyContract(contractKey, args) { + const verified = await getVerifiedContract(contractKey); + if (verified) { + console.log(`${contractKey} is already verified!`); + return "already verified"; + } + + if (!deployedContracts[contractKey]) { + throw new Error(`${contractKey} not deployed yet!`); + } + let result; + if (args) { + const argsFile = await writeVerifyArgs(contractKey, args); + result = await etherscanVerify(contractKey, deployedContracts[contractKey], argsFile); + } else { + result = await etherscanVerify(contractKey, deployedContracts[contractKey]); + } + await updateVerifiedContract(contractKey); + return result; +} + +async function verifyContracts() { + network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + deployedContracts = await getDeployedContracts(); + const accounts = await hre.ethers.getSigners(); + if (accounts.length == 0) { + throw new Error("Accounts not set!"); + } + deployer = await accounts[0]; + proxyOwner = await accounts[1]; + console.log("proxyOwner address: " + proxyOwner.address); + + // const verifyUsdc = await verifyContract('USDC'); + // console.log(`Verify USDC result: ${verifyUsdc}`); + + const verifyEANFT = await verifyContract("EANFT"); + console.log(`Verify EANFT result: ${verifyEANFT}`); + + const verifyTradableStream = await verifyContract("SuperfluidTradableStream", [ + `'${SF_HOST_ADDRESS}'`, + ]); + console.log(`Verify SuperfluidTradableStream result: ${verifyTradableStream}`); + + const verifyHumaConfig = await verifyContract("HumaConfig"); + console.log(`Verify HumaConfig result: ${verifyHumaConfig}`); + + const verifyHumaConfigTL = await verifyContract("HumaConfigTimelock", [ + 0, + `['${deployer.address}']`, + `['${deployer.address}']`, + ]); + console.log(`Verify HumaConfigTimelock result: ${verifyHumaConfigTL}`); + + const verifySuperfluidFactoringPoolTL = await verifyContract( + "SuperfluidFactoringPoolTimelock", + [0, `['${POOL_OWNER_MULTI_SIG}']`, `['${deployer.address}']`] + ); + console.log( + `Verify SuperfluidFactoringPoolTimelock result: ${verifySuperfluidFactoringPoolTL}` + ); + + const verifyrSuperfluidFactoringPoolProxyAdminTL = await verifyContract( + "SuperfluidFactoringPoolProxyAdminTimelock", + [0, `['${POOL_OWNER_MULTI_SIG}']`, `['${deployer.address}']`] + ); + console.log( + `Verify SuperfluidFactoringPoolProxyAdminTimelock result: ${verifyrSuperfluidFactoringPoolProxyAdminTL}` + ); + + const verifyFeeManager = await verifyContract("SuperfluidFactoringPoolFeeManager"); + console.log(`Verify FeeManager result: ${verifyFeeManager}`); + + const verifyHDTImpl = await verifyContract("SuperfluidPoolHDTImpl"); + console.log(`Verify SuperfluidPoolHDTImpl result: ${verifyHDTImpl}`); + + const verifyHDT = await verifyContract("SuperfluidPoolHDT", [ + `'${deployedContracts["SuperfluidPoolHDTImpl"]}'`, + `'${deployedContracts["SuperfluidFactoringPoolProxyAdminTimelock"]}'`, + "[]", + ]); + console.log(`Verify SuperfluidPoolHDT result: ${verifyHDT}`); + + const verifyPoolConfig = await verifyContract("SuperfluidFactoringPoolConfig"); + console.log(`Verify SuperfluidFactoringPoolConfig result: ${verifyPoolConfig}`); + + const verifyPoolImpl = await verifyContract("SuperfluidFactoringPoolImpl"); + console.log(`Verify SuperfluidFactoringPoolImpl result: ${verifyPoolImpl}`); + + const verifyPool = await verifyContract("SuperfluidFactoringPool", [ + `'${deployedContracts["SuperfluidFactoringPoolImpl"]}'`, + `'${deployedContracts["SuperfluidFactoringPoolProxyAdminTimelock"]}'`, + "[]", + ]); + console.log(`Verify SuperfluidFactoringPool result: ${verifyPool}`); + + const verifyProcessorImpl = await verifyContract("SuperfluidProcessorImpl"); + console.log(`Verify SuperfluidProcessorImpl result: ${verifyProcessorImpl}`); + + const verifyMultisend = await verifyContract("Multisend"); + console.log(`Verify Multisend result: ${verifyMultisend}`); +} + +verifyContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); + +// Reason: Already Verified diff --git a/deployment/mumbai/verify-superfluid-mock-super-app-register.js b/deployment/mumbai/verify-superfluid-mock-super-app-register.js new file mode 100644 index 00000000..dc6c2c15 --- /dev/null +++ b/deployment/mumbai/verify-superfluid-mock-super-app-register.js @@ -0,0 +1,99 @@ +const execSync = require("child_process").execSync; +const {getDeployedContracts, getVerifiedContract, updateVerifiedContract} = require("../utils.js"); + +const fs = require("fs"); + +const VERIFY_ARGS_PATH = "./deployment/mumbai/verify_args/"; + +const MUMBAI_SF_HOST_ADDRESS = "0xEB796bdb90fFA0f28255275e16936D25d3418603"; + +let deployedContracts, network; + +const getArgsFile = async function (contractName) { + const argsFile = `${VERIFY_ARGS_PATH}${contractName}.js`; + return argsFile; +}; + +const writeVerifyArgs = async function (contractName, args) { + const argsFile = await getArgsFile(contractName); + let data = `module.exports = [ + ${args.toString()}, + ];`; + // console.log(data) + await fs.mkdir(`${VERIFY_ARGS_PATH}`, {recursive: true}, (err) => { + if (err) throw err; + }); + fs.writeFileSync(argsFile, data, {flag: "w"}); + return argsFile; +}; + +const sleep = (ms) => new Promise((res) => setTimeout(res, ms)); + +async function etherscanVerify(contractName, contractAddress, argsFile, logMessage) { + await sleep(5000); + logMessage = !logMessage ? contractAddress : logMessage; + console.log(`Verifying ${contractName}:${logMessage}`); + + const command = !argsFile + ? `yarn hardhat verify '${contractAddress}' --network ${network}` + : `yarn hardhat verify ${contractAddress} --constructor-args ${argsFile} --network ${network}`; + let result; + try { + const verifyResult = execSync(command); + // console.log(verifyResult); + result = "successful"; + } catch (error) { + if (!error.toString().toLowerCase().includes("already verified")) { + throw error; + } else { + result = "already verified"; + } + } + console.log(`Verifying ${contractName}:${logMessage} ended!`); + return result; +} + +async function verifyContract(contractKey, args) { + const verified = await getVerifiedContract(contractKey); + if (verified) { + console.log(`${contractKey} is already verified!`); + return "already verified"; + } + + if (!deployedContracts[contractKey]) { + throw new Error(`${contractKey} not deployed yet!`); + } + let result; + if (args) { + const argsFile = await writeVerifyArgs(contractKey, args); + result = await etherscanVerify(contractKey, deployedContracts[contractKey], argsFile); + } else { + result = await etherscanVerify(contractKey, deployedContracts[contractKey]); + } + await updateVerifiedContract(contractKey); + return result; +} + +async function verifyContracts() { + network = (await hre.ethers.provider.getNetwork()).name; + console.log("network : ", network); + deployedContracts = await getDeployedContracts(); + const accounts = await hre.ethers.getSigners(); + if (accounts.length == 0) { + throw new Error("Accounts not set!"); + } + + const verifyMockSuperAppRegister = await verifyContract("MockSuperAppRegister", [ + `'${MUMBAI_SF_HOST_ADDRESS}'`, + ]); + console.log(`Verify MockSuperAppRegister result: ${verifyMockSuperAppRegister}`); +} + +verifyContracts() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); + +// Reason: Already Verified diff --git a/deployment/mumbai/verify_args/HumaConfigTimelock.js b/deployment/mumbai/verify_args/HumaConfigTimelock.js new file mode 100644 index 00000000..fbe138ee --- /dev/null +++ b/deployment/mumbai/verify_args/HumaConfigTimelock.js @@ -0,0 +1,3 @@ +module.exports = [ + 0,['0x60891b087E81Ee2a61B7606f68019ec112c539B9'],['0x60891b087E81Ee2a61B7606f68019ec112c539B9'], + ]; \ No newline at end of file diff --git a/deployment/mumbai/verify_args/MockSuperAppRegister.js b/deployment/mumbai/verify_args/MockSuperAppRegister.js new file mode 100644 index 00000000..08b1855b --- /dev/null +++ b/deployment/mumbai/verify_args/MockSuperAppRegister.js @@ -0,0 +1,3 @@ +module.exports = [ + '0xEB796bdb90fFA0f28255275e16936D25d3418603', + ]; \ No newline at end of file diff --git a/deployment/mumbai/verify_args/SuperfluidFactoringPool.js b/deployment/mumbai/verify_args/SuperfluidFactoringPool.js new file mode 100644 index 00000000..b2a900b6 --- /dev/null +++ b/deployment/mumbai/verify_args/SuperfluidFactoringPool.js @@ -0,0 +1,5 @@ +module.exports = [ + "0x1dD73dF9B461E4e9e888dc31DFD37C1b06620296", + "0x17e205Cd4aD1FEEd56A42E418E551CC8ef672300", + [], +]; diff --git a/deployment/mumbai/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js b/deployment/mumbai/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js new file mode 100644 index 00000000..979ae7a3 --- /dev/null +++ b/deployment/mumbai/verify_args/SuperfluidFactoringPoolProxyAdminTimelock.js @@ -0,0 +1,3 @@ +module.exports = [ + 0,['0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA'],['0x60891b087E81Ee2a61B7606f68019ec112c539B9'], + ]; \ No newline at end of file diff --git a/deployment/mumbai/verify_args/SuperfluidFactoringPoolTimelock.js b/deployment/mumbai/verify_args/SuperfluidFactoringPoolTimelock.js new file mode 100644 index 00000000..979ae7a3 --- /dev/null +++ b/deployment/mumbai/verify_args/SuperfluidFactoringPoolTimelock.js @@ -0,0 +1,3 @@ +module.exports = [ + 0,['0xB69cD2CC66583a4f46c1a8C977D5A8Bf9ecc81cA'],['0x60891b087E81Ee2a61B7606f68019ec112c539B9'], + ]; \ No newline at end of file diff --git a/deployment/mumbai/verify_args/SuperfluidPoolHDT.js b/deployment/mumbai/verify_args/SuperfluidPoolHDT.js new file mode 100644 index 00000000..cf4c39b0 --- /dev/null +++ b/deployment/mumbai/verify_args/SuperfluidPoolHDT.js @@ -0,0 +1,5 @@ +module.exports = [ + "0xcaEE180a4038B360F64Afc313acCcE8CB2000571", + "0x17e205Cd4aD1FEEd56A42E418E551CC8ef672300", + [], +]; diff --git a/deployment/mumbai/verify_args/SuperfluidTradableStream.js b/deployment/mumbai/verify_args/SuperfluidTradableStream.js new file mode 100644 index 00000000..08b1855b --- /dev/null +++ b/deployment/mumbai/verify_args/SuperfluidTradableStream.js @@ -0,0 +1,3 @@ +module.exports = [ + '0xEB796bdb90fFA0f28255275e16936D25d3418603', + ]; \ No newline at end of file diff --git a/deployment/utils.js b/deployment/utils.js index e25c1d31..eae6f33c 100644 --- a/deployment/utils.js +++ b/deployment/utils.js @@ -2,7 +2,7 @@ const {BigNumber: BN, ethers} = require("ethers"); const fs = require("fs"); const DEPLOYED_PATH = "./deployment/"; -const MAX_FEE_PER_GAS = 30_000_000_000; +const MAX_FEE_PER_GAS = 80_000_000_000; const MAX_PRIORITY_FEE_PER_GAS = 2_000_000_000; const getContractAddressFile = async function (fileType = "deployed", network) { @@ -167,6 +167,11 @@ const impersonate = async function (account) { return await hre.ethers.provider.getSigner(account); }; +async function advanceClock(days) { + await network.provider.send("evm_increaseTime", [3600 * 24 * days]); + await network.provider.send("evm_mine", []); +} + module.exports = { getInitilizedContract, updateInitilizedContract, @@ -183,4 +188,5 @@ module.exports = { getVerifiedContract, updateVerifiedContract, impersonate, + advanceClock, }; diff --git a/hardhat.config.js b/hardhat.config.js index 1d44297c..2ebaae0a 100644 --- a/hardhat.config.js +++ b/hardhat.config.js @@ -1,6 +1,3 @@ -require("dotenv").config(); -require("hardhat-contract-sizer"); - require("@nomicfoundation/hardhat-chai-matchers"); require("@tenderly/hardhat-tenderly"); @@ -11,6 +8,7 @@ require("@nomiclabs/hardhat-ethers"); require("@nomiclabs/hardhat-etherscan"); require("hardhat-prettier"); require("solidity-coverage"); +require("hardhat-contract-sizer"); require("hardhat-abi-exporter"); require("dotenv").config(); @@ -67,14 +65,24 @@ let ea_bcp = process.env["EA_BASE_CREDIT"]; if (!ea_bcp) { ea_bcp = EMPTY_PRIVATE_KEY; } -let invoicePayer = process.env["INVOICE_PAYER"]; -if (!invoicePayer) { - invoicePayer = EMPTY_PRIVATE_KEY; +let ea_sfp = process.env["EA_SUPERFLUID"]; +if (!ea_sfp) { + ea_sfp = EMPTY_PRIVATE_KEY; +} +let payer = process.env["PAYER"]; +if (!payer) { + payer = EMPTY_PRIVATE_KEY; } + let baseCreditPoolOperator = process.env["BASE_CREDIT_POOL_OPERATOR"]; if (!baseCreditPoolOperator) { baseCreditPoolOperator = EMPTY_PRIVATE_KEY; } +let baseCreditPoolOwnerTreasury = process.env["BASE_CREDIT_POOL_OWNER_TREASURY"]; +if (!baseCreditPoolOwnerTreasury) { + baseCreditPoolOwnerTreasury = EMPTY_PRIVATE_KEY; +} + let receivableFactoringPoolOperator = process.env["RECEIVABLE_FACTORING_POOL_OPERATOR"]; if (!receivableFactoringPoolOperator) { receivableFactoringPoolOperator = EMPTY_PRIVATE_KEY; @@ -83,9 +91,14 @@ let receivableFactoringPoolOwnerTreasury = process.env["RECEIVABLE_FACTORING_POO if (!receivableFactoringPoolOwnerTreasury) { receivableFactoringPoolOwnerTreasury = EMPTY_PRIVATE_KEY; } -let baseCreditPoolOwnerTreasury = process.env["BASE_CREDIT_POOL_OWNER_TREASURY"]; -if (!baseCreditPoolOwnerTreasury) { - baseCreditPoolOwnerTreasury = EMPTY_PRIVATE_KEY; + +let sfpOperator = process.env["SUPERFLUID_POOL_OPERATOR"]; +if (!sfpOperator) { + sfpOperator = EMPTY_PRIVATE_KEY; +} +let sfpTreasury = process.env["SUPERFLUID_POOL_OWNER_TREASURY"]; +if (!sfpTreasury) { + sfpTreasury = EMPTY_PRIVATE_KEY; } // @@ -172,11 +185,14 @@ module.exports = { pdsService, treasury, ea_bcp, - invoicePayer, + payer, baseCreditPoolOperator, receivableFactoringPoolOperator, baseCreditPoolOwnerTreasury, receivableFactoringPoolOwnerTreasury, + ea_sfp, + sfpOperator, + sfpTreasury, ], }, xdai: { @@ -204,23 +220,39 @@ module.exports = { url: polygonUrl, accounts: [deployer, eaService], }, + matic: { + url: polygonUrl, + accounts: [deployer, eaService, pdsService], + }, mumbai: { url: mumbaiUrl, accounts: [ deployer, proxyOwner, lender, - ea, + ea_sfp, eaService, pdsService, treasury, - ea_bcp, - invoicePayer, + payer, + sfpOperator, + sfpTreasury, ], }, - matic: { - url: polygonUrl, - accounts: [deployer, eaService, pdsService], + maticmum: { + url: mumbaiUrl, + accounts: [ + deployer, + proxyOwner, + lender, + ea_sfp, + eaService, + pdsService, + treasury, + payer, + sfpOperator, + sfpTreasury, + ], }, optimism: { url: "https://mainnet.optimism.io", @@ -338,7 +370,7 @@ module.exports = { solidity: { compilers: [ { - version: "0.8.4", + version: "0.8.11", settings: { optimizer: { enabled: true, @@ -360,8 +392,9 @@ module.exports = { etherscan: { apiKey: { goerli: process.env.ETHERSCAN_API_KEY || null, - polygon: process.env.POLYGONSCAN_API_KEY || null, mainnet: process.env.ETHERSCAN_API_KEY || null, + polygon: process.env.POLYGONSCAN_API_KEY || null, + polygonMumbai: process.env.POLYGONSCAN_API_KEY || null, }, }, contractSizer: { diff --git a/package.json b/package.json index 47672754..1f5067c4 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { + "@nomicfoundation/hardhat-network-helpers": "^1.0.7", "@nomicfoundation/hardhat-chai-matchers": "^1.0.5", "@nomiclabs/hardhat-ethers": "^2.1.1", "@nomiclabs/hardhat-etherscan": "^3.1.0", @@ -34,12 +35,14 @@ "lint-solidity": "yarn solhint -f table 'contracts/**/*.sol'", "postinstall": "husky install", "coverage": "hardhat coverage --network hardhat", - "gitleaks": "bash scripts/gitleaks.sh" + "gitleaks": "bash scripts/gitleaks.sh", + "gen-error-ids": "hardhat run scripts/gen-error-function-ids.js --network hardhat" }, "dependencies": { "@openzeppelin/contracts": "^4.7.3", - "@openzeppelin/contracts-upgradeable": "^4.8.3", + "@openzeppelin/contracts-upgradeable": "^4.7.3", + "@superfluid-finance/ethereum-contracts": "^1.5.0", "dotenv": "^16.0.2", "hardhat": "^2.11.1" } -} \ No newline at end of file +} diff --git a/scripts/error-functions.json b/scripts/error-functions.json index 4a415730..33bacdcc 100644 --- a/scripts/error-functions.json +++ b/scripts/error-functions.json @@ -16,7 +16,7 @@ "notPool()": "0x26d29bbf", "defaultGracePeriodLessThanMinAllowed()": "0xa733ff9c", "treasuryFeeHighThanUpperLimit()": "0x39cda0d1", - "alreayAPauser()": "0xfbca9e38", + "alreadyAPauser()": "0x9f694c22", "alreadyPoolAdmin()": "0x7bb356e2", "minPrincipalPaymentRateSettingTooHigh()": "0xc11fc042", "proposedEADoesNotOwnProvidedEANFT()": "0x75b0da3b", @@ -57,5 +57,23 @@ "notPoolOwnerTreasuryOrEA()": "0xc74cb44c", "paymentIdNotUnderReview()": "0xd1696aaa", "creditLineTooHigh()": "0x552b8377", - "creditLineOutstanding": "0x2901939a" + "creditLineOutstanding()": "0xc64e338c", + "allowanceTooLow()": "0xcd8ef369", + "durationTooLong()": "0xf1dd53a8", + "invalidFlowrate()": "0xd06a9328", + "settlementTooSoon()": "0x0453e75e", + "borrowerMismatch()": "0x27d3e640", + "notProcessor()": "0x90409ca1", + "receivableIdMismatch()": "0x97be2b67", + "flowKeyMismatch()": "0x29d5a5f3", + "flowIsNotTerminated()": "0xe9c5922f", + "invalidSuperfluidCallback()": "0xd2747f83", + "invalidSuperfluidAction()": "0x2f2cd9e9", + "notTradableStreamOwner()": "0x5709a724", + "tradableStreamNotMatured()": "0xa42ebb88", + "tradableStreamNotExisting()": "0xb78e2a5b", + "notEnoughAvailableFlowrate()": "0x9c808ab8", + "newReceiverSameToOrigin()": "0x6d79ce50", + "AuthorizationExpired()": "0x0f05f5bf", + "InvalidAuthorization()": "0x2ce87eeb" } diff --git a/test/BasePoolConfigTest.js b/test/BasePoolConfigTest.js index b05c81df..29e781a5 100644 --- a/test/BasePoolConfigTest.js +++ b/test/BasePoolConfigTest.js @@ -439,13 +439,10 @@ describe("Base Pool Config", function () { ); await poolContract.connect(borrower).requestCredit(toToken(1_000_000), 30, 12); - console.log("done"); await poolContract .connect(eaServiceAccount) .approveCredit(borrower.address, toToken(1_000_000), 30, 12, 1217); - console.log("done"); await poolContract.connect(borrower).drawdown(toToken(1_000_000)); - console.log("done"); // origination fee: 11000000000 // first month interest: 10002739726 let accruedIncome = await poolConfigContract.accruedIncome(); diff --git a/test/BaseTest.js b/test/BaseTest.js index ef96b2d5..efa50d24 100644 --- a/test/BaseTest.js +++ b/test/BaseTest.js @@ -7,8 +7,8 @@ function toBN(number, decimals) { return BN.from(number).mul(BN.from(10).pow(BN.from(decimals))); } -function toToken(number) { - return toBN(number, 6); +function toToken(number, decimals = 6) { + return toBN(number, decimals); } async function deployContracts( @@ -231,7 +231,7 @@ async function evmRevert(sId) { function checkRecord(r, rs, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) { if (v1 != "SKIP") expect(rs.creditLimit).to.equal(v1); if (v2 != "SKIP") expect(r.unbilledPrincipal).to.equal(v2); - if (v3 != "SKIP") expect(r.dueDate).to.be.equal(v3); + if (v3 != "SKIP") expect(r.dueDate).to.equal(v3); if (v4 != "SKIP") expect(r.correction).to.equal(v4); //be.within(v4 - 1, v4 + 1); if (v5 != "SKIP") expect(r.totalDue).to.equal(v5); if (v6 != "SKIP") expect(r.feesAndInterestDue).to.equal(v6); @@ -257,6 +257,34 @@ function checkArruedIncome(r, v1, v2, v3) { expect(r.poolOwnerIncome).to.equal(v3); } +function checkResults(r, vs) { + expect(r.length).to.equal(vs.length); + for (let i = 0; i < r.length; i++) { + if (vs[i] != null) expect(r[i]).to.equal(vs[i]); + } +} + +function printRecord(r, rs) { + if (r) + console.log( + `cr: [unbilledPrincipal: ${r.unbilledPrincipal}` + + `, dueDate: ${r.dueDate}` + + `, correction: ${r.correction}` + + `, totalDue: ${r.totalDue}` + + `, feesAndInterestDue: ${r.feesAndInterestDue}` + + `, missedPeriods: ${r.missedPeriods}` + + `, remainingPeriods: ${r.remainingPeriods}` + + `, state: ${r.state}]` + ); + if (rs) + console.log( + `crs: [creditLimit: ${rs.creditLimit}` + + `, aprInBps: ${rs.aprInBps}` + + `, intervalInDays: ${rs.intervalInDays}` + + `, state: ${rs.state}]` + ); +} + module.exports = { deployContracts, deployAndSetupPool, @@ -270,4 +298,6 @@ module.exports = { mineNextBlockWithTimestamp, evmSnapshot, evmRevert, + checkResults, + printRecord, }; diff --git a/test/SuperfluidFactoringTest.js b/test/SuperfluidFactoringTest.js new file mode 100644 index 00000000..fd217295 --- /dev/null +++ b/test/SuperfluidFactoringTest.js @@ -0,0 +1,4498 @@ +const {ethers} = require("hardhat"); +const {expect} = require("chai"); +const {BigNumber: BN} = require("ethers"); +const {loadFixture} = require("@nomicfoundation/hardhat-network-helpers"); +const { + toToken, + advanceClock, + checkResults, + setNextBlockTimestamp, + checkRecord, + printRecord, +} = require("./BaseTest"); + +require("dotenv").config(); + +const GOERLI_CHAIN_ID = 5; +const HARDHAT_CHAIN_ID = 31337; + +const POLYGON_USDC_MAP_SLOT = "0x0"; +const GOERLI_USDC_MAP_SLOT = "0x0"; +const MUMBAI_USDC_MAP_SLOT = "0x0"; + +let polygonUrl = process.env["POLYGON_URL"]; +let goerliUrl = process.env["GOERLI_URL"]; +let mumbaiUrl = process.env["MUMBAI_URL"]; + +const POLYGON_USDC_ADDRESS = "0x2791bca1f2de4661ed88a30c99a7a9449aa84174"; +const POLYGON_SF_USDCX_ADDRESS = "0xCAa7349CEA390F89641fe306D93591f87595dc1F"; +const POLYGON_SF_HOST_ADDRESS = "0x3E14dC1b13c488a8d5D310918780c983bD5982E7"; +const POLYGON_SF_CFA_ADDRESS = "0x6EeE6060f715257b970700bc2656De21dEdF074C"; + +const GOERLI_USDC_ADDRESS = "0xc94dd466416A7dFE166aB2cF916D3875C049EBB7"; +const GOERLI_SF_USDCX_ADDRESS = "0x8aE68021f6170E5a766bE613cEA0d75236ECCa9a"; +const GOERLI_SF_HOST_ADDRESS = "0x22ff293e14F1EC3A09B137e9e06084AFd63adDF9"; +const GOERLI_SF_CFA_ADDRESS = "0xEd6BcbF6907D4feEEe8a8875543249bEa9D308E8"; + +const MUMBAI_USDC_ADDRESS = "0xbe49ac1EadAc65dccf204D4Df81d650B50122aB2"; +const MUMBAI_SF_USDCX_ADDRESS = "0x42bb40bF79730451B11f6De1CbA222F17b87Afd7"; +const MUMBAI_SF_HOST_ADDRESS = "0xEB796bdb90fFA0f28255275e16936D25d3418603"; +const MUMBAI_SF_CFA_ADDRESS = "0x49e565Ed1bdc17F3d220f72DF0857C26FA83F873"; + +// let chainUrl = polygonUrl; +// let usdcMapSlot = POLYGON_USDC_MAP_SLOT; +// let usdcDecimals = 6; + +// let usdcAddress = POLYGON_USDC_ADDRESS; +// let sfUsdcxAddress = POLYGON_SF_USDCX_ADDRESS; +// let sfHostAddress = POLYGON_SF_HOST_ADDRESS; +// let sfCFAAddress = POLYGON_SF_CFA_ADDRESS; + +let chainUrl = mumbaiUrl; +let usdcMapSlot = MUMBAI_USDC_MAP_SLOT; +let usdcDecimals = 18; + +let usdcAddress = MUMBAI_USDC_ADDRESS; +let sfUsdcxAddress = MUMBAI_SF_USDCX_ADDRESS; +let sfHostAddress = MUMBAI_SF_HOST_ADDRESS; +let sfCFAAddress = MUMBAI_SF_CFA_ADDRESS; + +let usdc, sf, usdcx, cfa; + +let defaultDeployer, + poolOwner, + proxyOwner, + treasury, + lender, + protocolOwner, + eaServiceAccount, + pdsServiceAccount, + borrower, + evaluationAgent, + poolOperator, + poolOwnerTreasury, + payer, + borrower1; + +let humaConfigContract, + eaNFTContract, + feeManagerContract, + hdtContract, + poolConfigContract, + poolContract, + poolProcessorContract, + nftContract, + sfRegisterContract; + +function toDefaultToken(amount) { + return toToken(amount, 18); +} + +function toUSDC(amount) { + return toToken(amount, usdcDecimals); +} + +function convertDefaultToUSDC(amount) { + if (usdcDecimals != 18) { + return amount + .mul(BN.from(10).pow(BN.from(usdcDecimals))) + .div(BN.from(10).pow(BN.from(18))); + } else { + return amount; + } +} + +async function mint(address, amount) { + await mintToken(usdc, usdcMapSlot, address, amount); +} + +async function mintToken(token, mapSlot, address, amount) { + const beforeAmount = await token.balanceOf(address); + const newAmount = amount.add(beforeAmount); + await setToken(token.address, mapSlot, address, newAmount); +} + +async function setToken(tokenAddress, mapSlot, address, amount) { + const mintAmount = ethers.utils.hexZeroPad(amount.toHexString(), 32); + const slot = ethers.utils.hexStripZeros( + ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [address, mapSlot]) + ) + ); + await network.provider.send("hardhat_setStorageAt", [tokenAddress, slot, mintAmount]); +} + +async function createFlow(xToken, payer, payee, flowrate) { + const calldata = cfa.interface.encodeFunctionData("createFlow", [ + xToken.address, + payee.address, + flowrate, + "0x", + ]); + + await sf.connect(payer).callAgreement(cfa.address, calldata, "0x"); +} + +async function authorizeFlow(xToken, sender, operator) { + const calldata = cfa.interface.encodeFunctionData("authorizeFlowOperatorWithFullControl", [ + xToken.address, + operator.address, + "0x", + ]); + await sf.connect(sender).callAgreement(cfa.address, calldata, "0x"); +} + +async function deleteFlow(xToken, sender, receiver) { + const calldata = cfa.interface.encodeFunctionData("deleteFlow", [ + xToken.address, + sender.address, + receiver.address, + "0x", + ]); + + await sf.connect(sender).callAgreement(cfa.address, calldata, "0x"); +} + +function genDeleteFlowCalldata(xToken, sender, receiver) { + return cfa.interface.encodeFunctionData("deleteFlow", [ + xToken.address, + sender.address, + receiver.address, + "0x", + ]); +} + +function genUpdateFlowCalldata(xToken, receiver, flowrate) { + return cfa.interface.encodeFunctionData("updateFlow", [ + xToken.address, + receiver.address, + flowrate, + "0x", + ]); +} + +function genCreateFlowCalldata(xToken, receiver, flowrate) { + return cfa.interface.encodeFunctionData("createFlow", [ + xToken.address, + receiver.address, + flowrate, + "0x", + ]); +} + +async function deployContracts( + poolOwner, + treasury, + protocolOwner, + eaServiceAccount, + pdsServiceAccount, + assetToken +) { + // Deploy EvaluationAgentNFT + const EvaluationAgentNFT = await ethers.getContractFactory("EvaluationAgentNFT"); + eaNFTContract = await EvaluationAgentNFT.deploy(); + + // Deploy HumaConfig + const HumaConfig = await ethers.getContractFactory("HumaConfig"); + humaConfigContract = await HumaConfig.deploy(); + // await humaConfigContract.setHumaTreasury(treasury.address); + await humaConfigContract.setHumaTreasury(treasury.address); + await humaConfigContract.setTreasuryFee(2000); + await humaConfigContract.addPauser(poolOwner.address); + await humaConfigContract.setEANFTContractAddress(eaNFTContract.address); + await humaConfigContract.setEAServiceAccount(eaServiceAccount.address); + await humaConfigContract.setPDSServiceAccount(pdsServiceAccount.address); + + await humaConfigContract.transferOwnership(protocolOwner.address); + await humaConfigContract.connect(protocolOwner).addPauser(protocolOwner.address); + if (await humaConfigContract.connect(protocolOwner).paused()) + await humaConfigContract.connect(protocolOwner).unpause(); + + await humaConfigContract.connect(protocolOwner).setLiquidityAsset(assetToken.address, true); + + return [humaConfigContract, eaNFTContract]; +} + +async function deployAndSetupPool( + poolOwner, + proxyOwner, + evaluationAgent, + lender, + humaConfigContract, + eaNFTContract, + poolOperator, + poolOwnerTreasury +) { + await mint(lender.address, toUSDC(10_000_000)); + await mint(poolOwnerTreasury.address, toUSDC(10_000_000)); + await mint(evaluationAgent.address, toUSDC(10_000_000)); + + // Deploy Fee Manager + const feeManagerFactory = await ethers.getContractFactory("SuperfluidFeeManager"); + const feeManagerContract = await feeManagerFactory.deploy(); + await feeManagerContract.transferOwnership(poolOwner.address); + + const TransparentUpgradeableProxy = await ethers.getContractFactory( + "TransparentUpgradeableProxy" + ); + + const HDT = await ethers.getContractFactory("HDT"); + const hdtImpl = await HDT.deploy(); + await hdtImpl.deployed(); + const hdtProxy = await TransparentUpgradeableProxy.deploy( + hdtImpl.address, + proxyOwner.address, + [] + ); + await hdtProxy.deployed(); + const hdtContract = HDT.attach(hdtProxy.address); + await hdtContract.initialize("Base Credit HDT", "CHDT", usdc.address); + + const BasePoolConfig = await ethers.getContractFactory("BasePoolConfig"); + const poolConfig = await BasePoolConfig.deploy(); + await poolConfig.deployed(); + await poolConfig.initialize( + "Base Credit Pool", + hdtContract.address, + humaConfigContract.address, + feeManagerContract.address + ); + + // Deploy pool contract + const poolContractFactory = await ethers.getContractFactory("ReceivableFactoringPoolV2"); + const poolImpl = await poolContractFactory.deploy(); + await poolImpl.deployed(); + const poolProxy = await TransparentUpgradeableProxy.deploy( + poolImpl.address, + proxyOwner.address, + [] + ); + await poolProxy.deployed(); + const poolContract = poolContractFactory.attach(poolProxy.address); + + const poolProcessorContractFactory = await ethers.getContractFactory( + "SuperfluidPoolProcessor" + ); + const poolProcessorImpl = await poolProcessorContractFactory.deploy(); + await poolProcessorImpl.deployed(); + const poolProcessorProxy = await TransparentUpgradeableProxy.deploy( + poolProcessorImpl.address, + proxyOwner.address, + [] + ); + await poolProcessorProxy.deployed(); + const poolProcessorContract = poolProcessorContractFactory.attach(poolProcessorProxy.address); + + await poolProcessorContract["initialize(address,address,address,address)"]( + poolContract.address, + sfHostAddress, + sfCFAAddress, + nftContract.address + ); + await poolContract["initialize(address,address)"]( + poolConfig.address, + poolProcessorContract.address + ); + await poolConfig.setPool(poolContract.address); + await hdtContract.setPool(poolContract.address); + + // Pool setup + await poolConfig.transferOwnership(poolOwner.address); + + // Config rewards and requirements for poolOwner and EA, make initial deposit, and enable pool + await poolConfig.connect(poolOwner).setPoolLiquidityCap(toUSDC(1_000_000_000)); + await poolConfig.connect(poolOwner).setPoolOwnerRewardsAndLiquidity(625, 10); + + let eaNFTTokenId; + // Mint EANFT to the ea + const tx = await eaNFTContract.mintNFT(evaluationAgent.address); + const receipt = await tx.wait(); + for (const evt of receipt.events) { + if (evt.event === "NFTGenerated") { + eaNFTTokenId = evt.args.tokenId; + } + } + + await poolConfig.connect(poolOwner).setEvaluationAgent(eaNFTTokenId, evaluationAgent.address); + let s = await poolConfig.getPoolSummary(); + + await poolConfig.connect(poolOwner).setEARewardsAndLiquidity(1875, 10); + + await poolConfig.connect(poolOwner).setPoolOwnerTreasury(poolOwnerTreasury.address); + await poolConfig.connect(poolOwner).addPoolOperator(poolOwner.address); + await poolConfig.connect(poolOwner).addPoolOperator(poolOperator.address); + + await poolContract.connect(poolOperator).addApprovedLender(poolOwnerTreasury.address); + await poolContract.connect(poolOperator).addApprovedLender(evaluationAgent.address); + await poolContract.connect(poolOperator).addApprovedLender(lender.address); + + await usdc.connect(poolOwnerTreasury).approve(poolContract.address, toUSDC(1_000_000)); + await poolContract.connect(poolOwnerTreasury).makeInitialDeposit(toUSDC(1_000_000)); + + await usdc.connect(evaluationAgent).approve(poolContract.address, toUSDC(2_000_000)); + await poolContract.connect(evaluationAgent).makeInitialDeposit(toUSDC(2_000_000)); + + await expect(poolContract.connect(poolOwner).enablePool()).to.emit( + poolContract, + "PoolEnabled" + ); + + await poolConfig.connect(poolOwner).setAPR(1217); + await poolConfig.connect(poolOwner).setMaxCreditLine(toUSDC(10_000_000)); + + await usdc.connect(lender).approve(poolContract.address, toUSDC(2_000_000)); + await poolContract.connect(lender).deposit(toUSDC(2_000_000)); + + return [feeManagerContract, hdtContract, poolConfig, poolContract, poolProcessorContract]; +} + +function calcCorrection(cr, crs, blockTS, amount) { + return amount + .mul(crs.aprInBps) + .mul(cr.dueDate.sub(blockTS)) + .div(3600 * 24 * 365) + .div(10000) + .mul(-1); +} + +function calcInterest(crs, amount) { + return amount.mul(crs.aprInBps).mul(crs.intervalInDays).div(365).div(10000); +} + +function calcNewEndTime(cr, si) { + if (cr.dueDate.sub(si.endTime).mul(si.flowrate).lte(cr.totalDue)) { + return cr.dueDate; + } else { + return si.endTime.add(cr.totalDue.div(si.flowrate).add(1)); + } +} + +describe("Superfluid Factoring", function () { + before(async function () { + // console.log("test..."); + await network.provider.request({ + method: "hardhat_reset", + params: [ + { + forking: { + jsonRpcUrl: chainUrl, + // blockNumber: 33667900, + }, + }, + ], + }); + + [ + defaultDeployer, + proxyOwner, + lender, + borrower, + treasury, + evaluationAgent, + poolOwner, + protocolOwner, + eaServiceAccount, + pdsServiceAccount, + payer, + poolOperator, + poolOwnerTreasury, + borrower1, + ] = await ethers.getSigners(); + usdc = await ethers.getContractAt("IERC20", usdcAddress); + sf = await ethers.getContractAt("ISuperfluid", sfHostAddress); + usdcx = await ethers.getContractAt("ISuperToken", sfUsdcxAddress); + cfa = await ethers.getContractAt("IConstantFlowAgreementV1", sfCFAAddress); + await mint(payer.address, toUSDC(1_000_000)); + // console.log(`payer ${payer.address} usdc balance: ${await usdc.balanceOf(payer.address)}`); + await usdc.connect(payer).approve(usdcx.address, toUSDC(1_000_000)); + + const sfRegisterContractFactory = await ethers.getContractFactory("MockSuperAppRegister"); + sfRegisterContract = await sfRegisterContractFactory.deploy(sfHostAddress); + await sfRegisterContract.deployed(); + + const nftContractFactory = await ethers.getContractFactory("TradableStream"); + nftContract = await nftContractFactory.deploy(sfHostAddress); + await nftContract.deployed(); + }); + + let streamAmount, + streamDays, + streamDuration, + collateralAmount, + loanAmount, + streamId, + nftVersion; + + async function prepare() { + [humaConfigContract, eaNFTContract] = await deployContracts( + poolOwner, + treasury, + protocolOwner, + eaServiceAccount, + pdsServiceAccount, + usdc + ); + + [ + feeManagerContract, + hdtContract, + poolConfigContract, + poolContract, + poolProcessorContract, + ] = await deployAndSetupPool( + poolOwner, + proxyOwner, + evaluationAgent, + lender, + humaConfigContract, + eaNFTContract, + poolOperator, + poolOwnerTreasury + ); + + await poolConfigContract.connect(poolOwner).setWithdrawalLockoutPeriod(90); + await poolConfigContract.connect(poolOwner).setPoolDefaultGracePeriod(60); + await poolConfigContract.connect(poolOwner).setAPR(0); + await poolConfigContract.connect(poolOwner).setMaxCreditLine(toUSDC(1_000_000)); + await humaConfigContract.connect(protocolOwner).setTreasuryFee(2000); + await poolConfigContract.connect(poolOwner).setPoolOwnerRewardsAndLiquidity(625, 0); + await poolConfigContract.connect(poolOwner).setEARewardsAndLiquidity(1875, 0); + await poolConfigContract.connect(poolOwner).setReceivableRequiredInBps(10000); + + await usdcx.connect(payer).upgrade(toDefaultToken(10_000)); + // console.log( + // `payer ${payer.address} usdcx balance: ${await usdcx.balanceOf(payer.address)}` + // ); + + streamAmount = 6000; + streamDays = 30; + streamDuration = streamDays * 24 * 60 * 60; + + let flowrate = toDefaultToken(streamAmount).div(BN.from(streamDuration)); + await createFlow(usdcx, payer, borrower, flowrate); + + // console.log(`authorize stream...`); + await authorizeFlow(usdcx, payer, nftContract); + + // console.log(`mint TradableStream...`); + collateralAmount = 1500; + flowrate = toDefaultToken(collateralAmount).div(BN.from(streamDuration)).add(BN.from(1)); + await nftContract + .connect(borrower) + .mint(usdcx.address, payer.address, flowrate, streamDuration); + streamId = 0; + + nftVersion = await nftContract.version(); + } + + beforeEach(async function () { + await loadFixture(prepare); + }); + + describe("approveCredit", function () { + it("Should approve stream with amount equals to or high than the receivable requirement", async function () { + await poolContract + .connect(eaServiceAccount) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + toUSDC(streamAmount), + streamDays, + 1, + 1217, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + toUSDC(streamAmount) + ); + + let res = await poolContract.receivableInfoMapping(borrower.address); + checkResults(res, [ + nftContract.address, + toUSDC(streamAmount), + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + ]); + res = await poolContract.creditRecordStaticMapping(borrower.address); + checkResults(res, [toUSDC(streamAmount), 1217, streamDays, 0]); + }); + }); + + describe("mintTo & drawdown", function () { + beforeEach(async function () { + await poolContract + .connect(eaServiceAccount) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + toUSDC(streamAmount), + streamDays, + 1, + 1217, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + toUSDC(streamAmount) + ); + }); + + it("Should revert when receivableAssets mismatched", async function () { + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + toUSDC(100), + ethers.constants.AddressZero, + "0x" + ) + ).to.be.revertedWithCustomError(poolProcessorContract, "receivableAssetMismatch"); + }); + + it("Should revert when borrower mismatched receiver", async function () { + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + nftContract.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(poolProcessorContract, "borrowerMismatch"); + }); + + it("Should revert when receivableParam mismatched", async function () { + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + ethers.constants.AddressZero, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(poolContract, "receivableAssetParamMismatch"); + }); + + it("Should revert when flowrate was invalid", async function () { + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + 0, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(poolProcessorContract, "invalidFlowrate"); + }); + + it("Should revert when duration was too long", async function () { + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration + 1, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(poolProcessorContract, "durationTooLong"); + }); + + it("Should revert when there was no enough receivable amount", async function () { + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate.div(2), + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(poolProcessorContract, "insufficientReceivableAmount"); + }); + + it("Should revert when allowance was too low", async function () { + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(poolProcessorContract, "allowanceTooLow"); + }); + + it("Should revert when authorization expired", async function () { + await usdc.connect(borrower).approve(poolProcessorContract.address, toUSDC(10_000)); + + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + let block = await ethers.provider.getBlock(); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + block.timestamp, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(nftContract, "AuthorizationExpired"); + }); + + it("Should revert when authorization was invalid", async function () { + await usdc.connect(borrower).approve(poolProcessorContract.address, toUSDC(10_000)); + + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration + 1, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + let block = await ethers.provider.getBlock(); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ).to.be.revertedWithCustomError(nftContract, "InvalidAuthorization"); + }); + + it("Should drawdown with authorization", async function () { + await usdc.connect(borrower).approve(poolProcessorContract.address, toUSDC(10_000)); + + const beforeAmount = await usdc.balanceOf(borrower.address); + const beforeProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const beforeBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + + const ts = Math.ceil(Date.now() / 1000) + 2; + await setNextBlockTimestamp(ts); + + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(streamDuration); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + // await poolProcessorContract.mintAndDrawdown( + // borrower.address, + // loanAmount, + // nftContract.address, + // calldata + // ); + + const streamId = 1; + const interest = loanAmount.mul(BN.from(streamDays * 1217)).div(BN.from(365 * 10000)); + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + await expect( + poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ) + ) + .to.emit(poolProcessorContract, "ReceivableFlowKey") + .withArgs(poolContract.address, borrower.address, streamId, flowKey) + .to.emit(poolProcessorContract, "DrawdownMadeWithReceivable") + .withArgs( + poolContract.address, + borrower.address, + loanAmount, + loanAmount.sub(interest), + nftContract.address, + streamId + ); + + const afterAmount = await usdc.balanceOf(borrower.address); + const afterProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const afterBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + const receivedAmount = afterAmount.sub(beforeAmount); + + expect(receivedAmount).to.equal(loanAmount.sub(interest)); + expect(await nftContract.ownerOf(streamId)).to.equal(poolProcessorContract.address); + expect(beforeBorrowerFlowrate.sub(afterBorrowerFlowrate)).to.equal( + afterProcessorFlowrate.sub(beforeProcessorFlowrate) + ); + + let res = await nftContract.getTradableStreamData(streamId); + flowrate = res[6]; + expect(afterProcessorFlowrate.sub(beforeProcessorFlowrate)).to.equal(flowrate); + + res = await poolProcessorContract.streamInfoMapping(streamId); + const dueDate = ts + streamDuration; + checkResults(res, [borrower.address, flowrate, ts, dueDate, 0, flowKey]); + const cr = await poolContract.creditRecordMapping(borrower.address); + const crs = await poolContract.creditRecordStaticMapping(borrower.address); + // printRecord(cr, crs); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + dueDate, + 0, + loanAmount, + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + }); + }); + + describe("multisend for drawdown", function () { + beforeEach(async function () { + await poolContract + .connect(eaServiceAccount) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + toUSDC(streamAmount), + streamDays, + 1, + 1217, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + toUSDC(streamAmount) + ); + }); + + it("Should multisend for drawdown", async function () { + const Multisend = await ethers.getContractFactory("Multisend"); + const multisend = await Multisend.deploy(); + await multisend.deployed(); + + const TestToken = await ethers.getContractFactory("TestToken"); + const testToken = await TestToken.deploy(); + await testToken.deployed(); + + let allowanceAmount = BN.from(10e10); + let nonce = await testToken.nonces(borrower.address); + let expiry = Math.ceil(Date.now() / 1000) + 300; + let signatureData = await borrower._signTypedData( + { + name: "TestToken", + version: "1", + chainId: HARDHAT_CHAIN_ID, + verifyingContract: testToken.address, + }, + { + Permit: [ + {name: "owner", type: "address"}, + {name: "spender", type: "address"}, + {name: "value", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "deadline", type: "uint256"}, + ], + }, + { + owner: borrower.address, + spender: nftContract.address, + value: allowanceAmount, + nonce: nonce, + deadline: expiry, + } + ); + let signature = ethers.utils.splitSignature(signatureData); + + let tos = []; + let datas = []; + tos.push(testToken.address); + datas.push( + testToken.interface.encodeFunctionData("permit", [ + borrower.address, + nftContract.address, + allowanceAmount, + expiry, + signature.v, + signature.r, + signature.s, + ]) + ); + + await usdc.connect(borrower).approve(poolProcessorContract.address, toUSDC(10_000)); + + const beforeAmount = await usdc.balanceOf(borrower.address); + const beforeProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const beforeBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + + const ts = Math.ceil(Date.now() / 1000) + 2; + await setNextBlockTimestamp(ts); + + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(BN.from(streamDuration)); + nonce = await nftContract.nonces(borrower.address); + expiry = Math.ceil(Date.now() / 1000) + 300; + + signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + signature = ethers.utils.splitSignature(signatureData); + + calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + tos.push(poolProcessorContract.address); + datas.push( + poolProcessorContract.interface.encodeFunctionData("mintAndDrawdown", [ + borrower.address, + loanAmount, + nftContract.address, + calldata, + ]) + ); + + await multisend.multisend(tos, datas); + + const afterAmount = await usdc.balanceOf(borrower.address); + const afterProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const afterBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + + const interest = loanAmount.mul(BN.from(streamDays * 1217)).div(BN.from(365 * 10000)); + const receivedAmount = afterAmount.sub(beforeAmount); + + const streamId = 1; + + expect(receivedAmount).to.equal(loanAmount.sub(interest)); + expect(await nftContract.ownerOf(streamId)).to.equal(poolProcessorContract.address); + expect(beforeBorrowerFlowrate.sub(afterBorrowerFlowrate)).to.equal( + afterProcessorFlowrate.sub(beforeProcessorFlowrate) + ); + + let res = await nftContract.getTradableStreamData(streamId); + flowrate = res[6]; + expect(afterProcessorFlowrate.sub(beforeProcessorFlowrate)).to.equal(flowrate); + + res = await poolProcessorContract.streamInfoMapping(streamId); + const dueDate = ts + streamDuration; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + checkResults(res, [borrower.address, flowrate, ts, dueDate, 0, flowKey]); + const cr = await poolContract.creditRecordMapping(borrower.address); + const crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + dueDate, + 0, + loanAmount, + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + expect(await testToken.allowance(borrower.address, nftContract.address)).to.equal( + allowanceAmount + ); + }); + }); + + describe("settlement", function () { + beforeEach(async function () { + await poolContract + .connect(eaServiceAccount) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + toUSDC(streamAmount), + streamDays, + 1, + 1217, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + toUSDC(streamAmount) + ); + await usdc.connect(borrower).approve(poolProcessorContract.address, toUSDC(10_000)); + // const ts = Math.ceil(Date.now() / 1000) + 2; + // await setNextBlockTimestamp(ts); + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(BN.from(streamDuration)); + // console.log(`loanAmount: ${loanAmount}`); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + await poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ); + }); + + it("Should revert when receivableAssets mismatched", async function () { + await expect( + poolProcessorContract.settlement(ethers.constants.AddressZero, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "receivableAssetMismatch"); + }); + + it("Should revert when receivableId didn't exist", async function () { + await expect( + poolProcessorContract.settlement(nftContract.address, 99) + ).to.be.revertedWithCustomError(poolProcessorContract, "receivableIdMismatch"); + }); + + it("Should revert when settlement was called too soon", async function () { + const streamId = 1; + await expect( + poolProcessorContract.settlement(nftContract.address, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "settlementTooSoon"); + }); + + it("Should settlement", async function () { + let cr = await poolContract.creditRecordMapping(borrower.address); + let crs = await poolContract.creditRecordStaticMapping(borrower.address); + // printRecord(cr, crs); + const expiration = 10000; + const nts = cr.dueDate.toNumber() + expiration; + let block = await ethers.provider.getBlock(); + const beforeBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + const beforeReceivedAmount = BN.from(nts) + .sub(block.timestamp) + .mul(beforeBorrowerFlowrate); + await setNextBlockTimestamp(nts); + const streamId = 1; + let res = await nftContract.getTradableStreamData(streamId); + const flowrate = res[6]; + const si = await poolProcessorContract.streamInfoMapping(streamId); + const beforeBorrowAmount = await usdc.balanceOf(borrower.address); + const beforePoolAmount = await usdc.balanceOf(poolContract.address); + const beforeBorrowXAmount = await usdcx.balanceOf(borrower.address); + const beforeProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + await expect(poolProcessorContract.settlement(nftContract.address, streamId)) + .to.emit(poolProcessorContract, "SettlementMade") + .withArgs( + poolContract.address, + borrower.address, + si.flowKey, + nftContract.address, + streamId + ); + const afterBorrowAmount = await usdc.balanceOf(borrower.address); + const afterPoolAmount = await usdc.balanceOf(poolContract.address); + const afterBorrowXAmount = await usdcx.balanceOf(borrower.address); + const afterProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const afterBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + // console.log( + // `afterBorrowAmount: ${afterBorrowAmount}, beforeBorrowAmount: ${beforeBorrowAmount}` + // ); + expect(afterBorrowAmount.sub(beforeBorrowAmount)).to.equal(0); + expect(afterPoolAmount.sub(beforePoolAmount)).to.equal(loanAmount); + expect(beforeProcessorFlowrate.sub(afterProcessorFlowrate)).to.equal( + afterBorrowerFlowrate.sub(beforeBorrowerFlowrate) + ); + expect(afterBorrowerFlowrate.sub(beforeBorrowerFlowrate)).to.equal(flowrate); + await expect(nftContract.ownerOf(streamId)).to.be.revertedWith( + "ERC721: invalid token ID" + ); + expect(afterBorrowXAmount.sub(beforeBorrowXAmount).sub(beforeReceivedAmount)).to.equal( + si.flowrate.mul(BN.from(expiration)) + ); + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + // printRecord(cr, crs); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + "SKIP", + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + checkResults(await poolContract.receivableInfoMapping(borrower.address), [ + ethers.constants.AddressZero, + 0, + 0, + ]); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + expect(await poolProcessorContract.flowEndMapping(flowKey)).to.equal(0); + }); + + it("Should settlement after made payment manually", async function () { + let amount = toUSDC(200); + await usdc.connect(borrower).approve(poolContract.address, amount); + + let beforeBorrowAmount = await usdc.balanceOf(borrower.address); + let beforePoolAmount = await usdc.balanceOf(poolContract.address); + // console.log( + // `beforeBorrowAmount: ${beforeBorrowAmount}, beforePoolAmount: ${beforePoolAmount}` + // ); + await poolContract.connect(borrower).makePayment(borrower.address, amount); + let afterBorrowAmount = await usdc.balanceOf(borrower.address); + let afterPoolAmount = await usdc.balanceOf(poolContract.address); + + expect(beforeBorrowAmount.sub(afterBorrowAmount)).to.equal(amount); + expect(afterPoolAmount.sub(beforePoolAmount)).to.equal(amount); + + let block = await ethers.provider.getBlock(); + let cr = await poolContract.creditRecordMapping(borrower.address); + let crs = await poolContract.creditRecordStaticMapping(borrower.address); + let correction = calcCorrection(cr, crs, block.timestamp, amount); + + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(amount), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + const expiration = 10000; + const nts = cr.dueDate.toNumber() + expiration; + block = await ethers.provider.getBlock(); + const beforeBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + const beforeReceivedAmount = BN.from(nts) + .sub(block.timestamp) + .mul(beforeBorrowerFlowrate); + await setNextBlockTimestamp(nts); + + const streamId = 1; + let res = await nftContract.getTradableStreamData(streamId); + const flowrate = res[6]; + const si = await poolProcessorContract.streamInfoMapping(streamId); + + beforeBorrowAmount = await usdc.balanceOf(borrower.address); + beforePoolAmount = await usdc.balanceOf(poolContract.address); + const beforeBorrowXAmount = await usdcx.balanceOf(borrower.address); + const beforeProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowAmount = await usdc.balanceOf(borrower.address); + afterPoolAmount = await usdc.balanceOf(poolContract.address); + const afterBorrowXAmount = await usdcx.balanceOf(borrower.address); + const afterProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const afterBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + + expect(afterBorrowAmount.sub(beforeBorrowAmount)).to.equal(amount.sub(correction)); + expect(afterPoolAmount.sub(beforePoolAmount)).to.equal( + loanAmount.sub(amount).add(correction) + ); + expect(beforeProcessorFlowrate.sub(afterProcessorFlowrate)).to.equal( + afterBorrowerFlowrate.sub(beforeBorrowerFlowrate) + ); + expect(afterBorrowerFlowrate.sub(beforeBorrowerFlowrate)).to.equal(flowrate); + + await expect(nftContract.ownerOf(streamId)).to.be.revertedWith( + "ERC721: invalid token ID" + ); + + expect(afterBorrowXAmount.sub(beforeBorrowXAmount).sub(beforeReceivedAmount)).to.equal( + si.flowrate.mul(BN.from(expiration)) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + checkResults(await poolContract.receivableInfoMapping(borrower.address), [ + ethers.constants.AddressZero, + 0, + 0, + ]); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + }); + + it("Should settlement after paid off manually", async function () { + await mint(borrower.address, toUSDC(10000)); + + let excessAmount = toUSDC(100); + let amount = loanAmount.add(excessAmount); + await usdc.connect(borrower).approve(poolContract.address, amount); + + let cr = await poolContract.creditRecordMapping(borrower.address); + + let beforeBorrowAmount = await usdc.balanceOf(borrower.address); + let beforePoolAmount = await usdc.balanceOf(poolContract.address); + let amountUsedbyCorrection = cr.totalDue; + await poolContract.connect(borrower).makePayment(borrower.address, amount); + let afterBorrowAmount = await usdc.balanceOf(borrower.address); + let afterPoolAmount = await usdc.balanceOf(poolContract.address); + + let block = await ethers.provider.getBlock(); + let crs = await poolContract.creditRecordStaticMapping(borrower.address); + let correction = calcCorrection(cr, crs, block.timestamp, amountUsedbyCorrection); + cr = await poolContract.creditRecordMapping(borrower.address); + + expect(beforeBorrowAmount.sub(afterBorrowAmount)).to.equal(loanAmount.add(correction)); + expect(afterPoolAmount.sub(beforePoolAmount)).to.equal(loanAmount.add(correction)); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + const expiration = 1000; + const nts = cr.dueDate.toNumber() + expiration; + block = await ethers.provider.getBlock(); + const beforeBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + const beforeReceivedAmount = BN.from(nts) + .sub(block.timestamp) + .mul(beforeBorrowerFlowrate); + await setNextBlockTimestamp(nts); + + const streamId = 1; + let res = await nftContract.getTradableStreamData(streamId); + const flowrate = res[6]; + const si = await poolProcessorContract.streamInfoMapping(streamId); + + beforeBorrowAmount = await usdc.balanceOf(borrower.address); + beforePoolAmount = await usdc.balanceOf(poolContract.address); + const beforeBorrowXAmount = await usdcx.balanceOf(borrower.address); + const beforeProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + await expect(poolProcessorContract.settlement(nftContract.address, streamId)) + .to.emit(poolProcessorContract, "ReceivableCleared") + .withArgs( + poolContract.address, + borrower.address, + si.flowKey, + nftContract.address, + streamId + ); + afterBorrowAmount = await usdc.balanceOf(borrower.address); + afterPoolAmount = await usdc.balanceOf(poolContract.address); + const afterBorrowXAmount = await usdcx.balanceOf(borrower.address); + const afterProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const afterBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + + expect(afterBorrowAmount.sub(beforeBorrowAmount)).to.equal(loanAmount); + expect(afterPoolAmount.sub(beforePoolAmount)).to.equal(0); + expect(beforeProcessorFlowrate.sub(afterProcessorFlowrate)).to.equal( + afterBorrowerFlowrate.sub(beforeBorrowerFlowrate) + ); + expect(afterBorrowerFlowrate.sub(beforeBorrowerFlowrate)).to.equal(flowrate); + + await expect(nftContract.ownerOf(streamId)).to.be.revertedWith( + "ERC721: invalid token ID" + ); + expect(afterBorrowXAmount.sub(beforeBorrowXAmount).sub(beforeReceivedAmount)).to.equal( + si.flowrate.mul(BN.from(expiration)) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + checkResults(await poolContract.receivableInfoMapping(borrower.address), [ + ethers.constants.AddressZero, + 0, + 0, + ]); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + }); + }); + + describe("SuperApp", function () { + beforeEach(async function () { + await sfRegisterContract.register(poolProcessorContract.address); + + await poolContract + .connect(eaServiceAccount) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + toUSDC(streamAmount), + streamDays, + 1, + 1217, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + toUSDC(streamAmount) + ); + await usdc.connect(borrower).approve(poolProcessorContract.address, toUSDC(10_000)); + + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(BN.from(streamDuration)); + // console.log(`loanAmount: ${loanAmount}`); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + await poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ); + }); + + describe("flow is terminated", function () { + it("Should terminate flow successfully", async function () { + let block = await ethers.provider.getBlock(); + nts = block.timestamp + 10; + await setNextBlockTimestamp(nts); + + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + + const calldata = genDeleteFlowCalldata(usdcx, payer, poolProcessorContract); + await expect(sf.connect(payer).callAgreement(cfa.address, calldata, "0x")) + .to.emit(poolProcessorContract, "FlowIsTerminated") + .withArgs(flowKey, nts); + + expect(await poolProcessorContract.flowEndMapping(flowKey)).to.equal(nts); + + await expect(deleteFlow(usdcx, payer, poolProcessorContract)).to.be.reverted; + }); + + describe("onTerminatedFlow", function () { + it("Should revert when receivableId mismatched", async function () { + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + const streamId = 2; + await expect( + poolProcessorContract.onTerminatedFlow(flowKey, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "receivableIdMismatch"); + }); + + it("Should revert when flowKey mismatched", async function () { + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + const streamId = 1; + await expect( + poolProcessorContract.onTerminatedFlow(flowKey, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "flowKeyMismatch"); + }); + + it("Should revert when flow is not terminated", async function () { + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + const streamId = 1; + await expect( + poolProcessorContract.onTerminatedFlow(flowKey, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "flowIsNotTerminated"); + }); + + it("Should send NotGettingEnoughAllowance event", async function () { + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(50); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + const streamId = 1; + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await expect(poolProcessorContract.onTerminatedFlow(flowKey, streamId)) + .to.emit(poolProcessorContract, "NotGettingEnoughAllowance") + .withArgs( + poolContract.address, + borrower.address, + nftContract.address, + streamId + ); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + await expect( + poolProcessorContract.onTerminatedFlow(flowKey, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "flowIsNotTerminated"); + }); + + it("Should send ReadyToSettlement event", async function () { + let balance = await usdc.balanceOf(borrower.address); + if (balance.lt(loanAmount)) { + await mint(borrower.address, loanAmount); + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + + let block = await ethers.provider.getBlock(); + let nts1 = block.timestamp + 10; + await setNextBlockTimestamp(nts1); + const streamId = 1; + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await expect(poolProcessorContract.onTerminatedFlow(flowKey, streamId)) + .to.emit(poolProcessorContract, "ReadyToSettlement") + .withArgs( + poolContract.address, + borrower.address, + nftContract.address, + streamId, + nts1 + ); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + let remainingBal = loanAmount.sub(afterSI.receivedFlowAmount); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let correction = calcCorrection(cr, crs, nts1, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + await expect( + poolProcessorContract.onTerminatedFlow(flowKey, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "flowIsNotTerminated"); + }); + + it("Should call onTerminatedFlow for multiple borrowers after flow is terminated", async function () { + // mint NFT2 to borower1 + let flowrate = toDefaultToken(streamAmount).div(BN.from(streamDuration)); + await createFlow(usdcx, payer, borrower1, flowrate); + + await poolContract + .connect(eaServiceAccount) + [ + "approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)" + ]( + borrower1.address, + toUSDC(streamAmount), + streamDays, + 1, + 1217, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower1.address] + ), + toUSDC(streamAmount) + ); + await usdc + .connect(borrower1) + .approve(poolProcessorContract.address, toUSDC(10_000)); + + const ts = Math.ceil(Date.now() / 1000) + 2; + await setNextBlockTimestamp(ts); + flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(BN.from(streamDuration)); + const nonce = await nftContract.nonces(borrower1.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + const signatureData = await borrower1._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower1.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower1.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + const beforeAmount = await usdc.balanceOf(borrower1.address); + const beforeProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const beforeBorrowerFlowrate = await cfa.getNetFlow( + usdcx.address, + borrower1.address + ); + let streamId = 2; + const interest = loanAmount + .mul(BN.from(streamDays * 1217)) + .div(BN.from(365 * 10000)); + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + await poolProcessorContract.mintAndDrawdown( + borrower1.address, + loanAmount, + nftContract.address, + calldata + ); + const afterAmount = await usdc.balanceOf(borrower1.address); + const afterProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const afterBorrowerFlowrate = await cfa.getNetFlow( + usdcx.address, + borrower1.address + ); + const receivedAmount = afterAmount.sub(beforeAmount); + + expect(receivedAmount).to.equal(loanAmount.sub(interest)); + expect(await nftContract.ownerOf(streamId)).to.equal( + poolProcessorContract.address + ); + expect(beforeBorrowerFlowrate.sub(afterBorrowerFlowrate)).to.equal( + afterProcessorFlowrate.sub(beforeProcessorFlowrate) + ); + expect(beforeProcessorFlowrate).to.equal(flowrate); + expect(afterProcessorFlowrate).to.equal(flowrate.mul(2)); + + let res = await nftContract.getTradableStreamData(streamId); + flowrate = res[6]; + expect(afterProcessorFlowrate.sub(beforeProcessorFlowrate)).to.equal(flowrate); + + res = await poolProcessorContract.streamInfoMapping(streamId); + const dueDate = ts + streamDuration; + checkResults(res, [borrower1.address, flowrate, ts, dueDate, 0, flowKey]); + let cr = await poolContract.creditRecordMapping(borrower1.address); + let crs = await poolContract.creditRecordStaticMapping(borrower1.address); + // printRecord(cr, crs); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + dueDate, + 0, + loanAmount, + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // terminate flow + let block = await ethers.provider.getBlock(); + let nts = block.timestamp + 3 * 24 * 3600; + await setNextBlockTimestamp(nts); + await deleteFlow(usdcx, payer, poolProcessorContract); + + // prepare eonough balance and call onTerminatedFlow for borrower + let balance = await usdc.balanceOf(borrower.address); + if (balance.lt(loanAmount)) { + await mint(borrower.address, loanAmount); + } + + streamId = 1; + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + let remainingBal = loanAmount.sub(afterSI.receivedFlowAmount); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // prepare eonough balance and call onTerminatedFlow for borrower1 + balance = await usdc.balanceOf(borrower1.address); + if (balance.lt(loanAmount)) { + await mint(borrower1.address, loanAmount); + } + + streamId = 2; + beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + beforeBorrowerBal = await usdc.balanceOf(borrower1.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower1.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + remainingBal = loanAmount.sub(afterSI.receivedFlowAmount); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower1.address); + crs = await poolContract.creditRecordStaticMapping(borrower1.address); + block = await ethers.provider.getBlock(); + correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + }); + }); + + describe("tryTransferAllowance", function () { + it("Should revert when receivableAssets mismatched", async function () { + await expect( + poolProcessorContract.tryTransferAllowance( + ethers.constants.AddressZero, + streamId + ) + ).to.be.revertedWithCustomError( + poolProcessorContract, + "receivableAssetMismatch" + ); + }); + + it("Should revert when flow rate is greater than 0", async function () { + const streamId = 1; + await expect( + poolProcessorContract.tryTransferAllowance(nftContract.address, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "invalidFlowrate"); + }); + + it("Should revert when credit line state is not GoodStanding", async function () { + // delete flow + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(80); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + const streamId = 1; + await expect(poolProcessorContract.onTerminatedFlow(flowKey, streamId)) + .to.emit(poolProcessorContract, "NotGettingEnoughAllowance") + .withArgs( + poolContract.address, + borrower.address, + nftContract.address, + streamId + ); + + // call settlement to change the credit line state to delayed + + const expiration = 1000; + nts = cr.dueDate.toNumber() + expiration; + await setNextBlockTimestamp(nts); + await poolProcessorContract.settlement(nftContract.address, streamId); + + // revert + await expect( + poolProcessorContract.tryTransferAllowance(nftContract.address, streamId) + ).to.be.revertedWithCustomError( + poolProcessorContract, + "creditLineNotInGoodStandingState" + ); + }); + + it("Should tryTransferAllowance before settlement is called", async function () { + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(100); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const streamId = 1; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + let crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + await mint(borrower.address, toUSDC(streamAmount)); + + block = await ethers.provider.getBlock(); + nts = block.timestamp + 600; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await expect( + poolProcessorContract.tryTransferAllowance(nftContract.address, streamId) + ) + .to.emit(poolProcessorContract, "ReadyToSettlement") + .withArgs( + poolContract.address, + borrower.address, + nftContract.address, + streamId, + nts + ); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + let received = loanAmount.sub(remainingBal).sub(afterSI.receivedFlowAmount); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal(received); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(received); + correction = correction.add(calcCorrection(cr, crs, nts, received)); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + afterSI.receivedFlowAmount, + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + block = await ethers.provider.getBlock(); + correction = correction.add( + calcCorrection( + cr, + crs, + block.timestamp, + cr.totalDue.sub(cr.feesAndInterestDue) + ) + ); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal( + afterSI.receivedFlowAmount.add(correction) + ); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(correction); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + + await expect( + poolProcessorContract.settlement(nftContract.address, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "receivableIdMismatch"); + }); + + it("Should call tryTransferAllowance for multiple borrowers after flow is terminated", async function () { + // mint NFT2 to borrower1 + let flowrate = toDefaultToken(streamAmount).div(BN.from(streamDuration)); + await createFlow(usdcx, payer, borrower1, flowrate); + + await poolContract + .connect(eaServiceAccount) + [ + "approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)" + ]( + borrower1.address, + toUSDC(streamAmount), + streamDays, + 1, + 1217, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower1.address] + ), + toUSDC(streamAmount) + ); + await usdc + .connect(borrower1) + .approve(poolProcessorContract.address, toUSDC(10_000)); + + const ts = Math.ceil(Date.now() / 1000) + 2; + await setNextBlockTimestamp(ts); + flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(BN.from(streamDuration)); + const nonce = await nftContract.nonces(borrower1.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + const signatureData = await borrower1._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower1.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower1.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + + await poolProcessorContract.mintAndDrawdown( + borrower1.address, + loanAmount, + nftContract.address, + calldata + ); + + // terminate flow + let block = await ethers.provider.getBlock(); + let nts = block.timestamp + 2 * 24 * 3600; + await setNextBlockTimestamp(nts); + await deleteFlow(usdcx, payer, poolProcessorContract); + + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + + // leave some balance and call onTerminatedFlow of borrower + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(83); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let streamId = 1; + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + let cr = await poolContract.creditRecordMapping(borrower.address); + let correction = cr.correction; + + // prepare enough balance and call tryTransferAllowance of borrower + await mint(borrower.address, toUSDC(streamAmount)); + + block = await ethers.provider.getBlock(); + nts = block.timestamp + 600; + await setNextBlockTimestamp(nts); + + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.tryTransferAllowance( + nftContract.address, + streamId + ); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + + let received = loanAmount.sub(remainingBal).sub(afterSI.receivedFlowAmount); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal(received); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(received); + cr = await poolContract.creditRecordMapping(borrower.address); + let crs = await poolContract.creditRecordStaticMapping(borrower.address); + correction = correction.add(calcCorrection(cr, crs, nts, received)); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + afterSI.receivedFlowAmount, + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // call settle of borrower + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + block = await ethers.provider.getBlock(); + correction = correction.add( + calcCorrection( + cr, + crs, + block.timestamp, + cr.totalDue.sub(cr.feesAndInterestDue) + ) + ); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal( + afterSI.receivedFlowAmount.add(correction) + ); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(correction); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + + // leave some balance and call onTerminatedFlow of borrower1 + balance = await usdc.balanceOf(borrower1.address); + remainingBal = toUSDC(39); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower1) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + streamId = 2; + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + afterSI = await poolProcessorContract.streamInfoMapping(streamId); + cr = await poolContract.creditRecordMapping(borrower1.address); + correction = cr.correction; + + // prepare enough balance and call tryTransferAllowance of borrower1 + await mint(borrower1.address, toUSDC(streamAmount)); + + block = await ethers.provider.getBlock(); + nts = block.timestamp + 600; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower1.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.tryTransferAllowance( + nftContract.address, + streamId + ); + afterBorrowerBal = await usdc.balanceOf(borrower1.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + received = loanAmount.sub(remainingBal).sub(afterSI.receivedFlowAmount); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal(received); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(received); + cr = await poolContract.creditRecordMapping(borrower1.address); + crs = await poolContract.creditRecordStaticMapping(borrower1.address); + correction = correction.add(calcCorrection(cr, crs, nts, received)); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + afterSI.receivedFlowAmount, + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // call settle of borrower1 + beforeBorrowerBal = await usdc.balanceOf(borrower1.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower1.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + block = await ethers.provider.getBlock(); + correction = correction.add( + calcCorrection( + cr, + crs, + block.timestamp, + cr.totalDue.sub(cr.feesAndInterestDue) + ) + ); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal( + afterSI.receivedFlowAmount.add(correction) + ); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(correction); + + cr = await poolContract.creditRecordMapping(borrower1.address); + crs = await poolContract.creditRecordStaticMapping(borrower1.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + }); + }); + + describe("settlement", function () { + it("Should settlement and cr.state is delayed when flow was terminated during the loan period, and no enough allowance", async function () { + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(50); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const streamId = 1; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + const expiration = 1000; + nts = cr.dueDate.toNumber() + expiration; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + cr = await poolContract.creditRecordMapping(borrower.address); + let unbilled = cr.totalDue; + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(0); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(afterSI.receivedFlowAmount); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + unbilled = unbilled.sub(afterSI.receivedFlowAmount).add(correction); + let interest = calcInterest(crs, unbilled); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + unbilled.add(interest), + interest, + 1, + 0, + 1217, + streamDays, + 4, + 0 + ); + }); + + it("Should settlement when flow was terminated during the loan period, and have enough allowance when payoff", async function () { + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(100); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const streamId = 1; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + await mint(borrower.address, toUSDC(streamAmount)); + + const expiration = 1000; + nts = cr.dueDate.toNumber() + expiration; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal( + loanAmount.sub(remainingBal).add(correction) + ); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal( + loanAmount + .sub(remainingBal) + .sub(afterSI.receivedFlowAmount) + .add(correction) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + }); + + it("Should settlement when flow was terminated during the loan period, and have enough allowance when terminate flow", async function () { + let balance = await usdc.balanceOf(borrower.address); + if (balance.lt(loanAmount)) { + await mint(borrower.address, loanAmount); + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const streamId = 1; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + let remainingBal = loanAmount.sub(afterSI.receivedFlowAmount); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + beforeBorrowerBal = afterBorrowerBal; + beforePoolBal = afterPoolBal; + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + block = await ethers.provider.getBlock(); + correction = correction.add( + calcCorrection( + cr, + crs, + block.timestamp, + cr.totalDue.sub(cr.feesAndInterestDue) + ) + ); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal( + loanAmount.sub(remainingBal).add(correction) + ); + expect(afterBorrowerBal.sub(beforeBorrowerBal)).to.equal(correction.mul(-1)); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + }); + + it("Should call settlement repeatedly", async function () { + // delete flow + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(80); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const streamId = 1; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // call settlement and revert + + await expect( + poolProcessorContract.settlement(nftContract.address, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "settlementTooSoon"); + + // call tryTransferAllowance to transfer some allowance from borrower + + let received = toUSDC(50); + await mint(borrower.address, received); + + block = await ethers.provider.getBlock(); + nts = block.timestamp + 600; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.tryTransferAllowance( + nftContract.address, + streamId + ); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal(received); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(received); + correction = correction.add(calcCorrection(cr, crs, nts, received)); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal).sub(received), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // call settlement to change the credit line state to delayed + + const expiration = 1000; + nts = cr.dueDate.toNumber() + expiration; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal(afterSI.receivedFlowAmount); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(0); + + let unbilled = loanAmount + .sub(remainingBal) + .sub(received) + .sub(afterSI.receivedFlowAmount) + .add(correction); + let interest = calcInterest(crs, unbilled); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + unbilled.add(interest), + interest, + 1, + 0, + 1217, + streamDays, + 4, + 0 + ); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + borrower.address, + afterSI.flowrate, + afterSI.endTime, + afterSI.endTime, + 0, + flowKey, + ]); + + // call settlment and nothing happened + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(beforeBorrowerBal).to.equal(afterBorrowerBal); + expect(beforePoolBal).to.equal(afterPoolBal); + + // call settlement to pay off the delayed credit line + + await mint(borrower.address, loanAmount); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + block = await ethers.provider.getBlock(); + correction = calcCorrection( + cr, + crs, + block.timestamp, + cr.totalDue.sub(cr.feesAndInterestDue) + ); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(cr.totalDue.add(correction)); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal( + cr.totalDue.add(correction) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + + // call settlement again and reverted + + await expect( + poolProcessorContract.settlement(nftContract.address, streamId) + ).to.be.revertedWithCustomError(poolProcessorContract, "receivableIdMismatch"); + }); + + it("Should call settlement to pay off a credit which totalDue is 0", async function () { + // delete flow + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(80); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const streamId = 1; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + const calldata = genDeleteFlowCalldata(usdcx, payer, poolProcessorContract); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // call tryTransferAllowance to transfer some allowance from borrower + + let received = toUSDC(50); + await mint(borrower.address, received); + + block = await ethers.provider.getBlock(); + nts = block.timestamp + 600; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.tryTransferAllowance( + nftContract.address, + streamId + ); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal(received); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(received); + correction = correction.add(calcCorrection(cr, crs, nts, received)); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal).sub(received), + 0, + 0, + 0, + 1217, + streamDays, + 3, + 0 + ); + + // call settlement to change the credit line state to delayed + + const expiration = 1000; + nts = cr.dueDate.toNumber() + expiration; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal(afterSI.receivedFlowAmount); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(0); + + let unbilled = loanAmount + .sub(remainingBal) + .sub(received) + .sub(afterSI.receivedFlowAmount) + .add(correction); + let interest = calcInterest(crs, unbilled); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + unbilled.add(interest), + interest, + 1, + 0, + 1217, + streamDays, + 4, + 0 + ); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + borrower.address, + afterSI.flowrate, + afterSI.endTime, + afterSI.endTime, + 0, + flowKey, + ]); + + // call makePayment to pay off the delayed credit line + + await mint(borrower.address, loanAmount); + await usdc.connect(borrower).approve(poolContract.address, loanAmount); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolContract.connect(borrower).makePayment(borrower.address, loanAmount); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + block = await ethers.provider.getBlock(); + correction = calcCorrection( + cr, + crs, + block.timestamp, + cr.totalDue.sub(cr.feesAndInterestDue) + ); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(cr.totalDue.add(correction)); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal( + cr.totalDue.add(correction) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + borrower.address, + afterSI.flowrate, + afterSI.endTime, + afterSI.endTime, + 0, + flowKey, + ]); + + await nftContract.ownerOf(streamId); + + // call settlement to delete NFT and streamInfo + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(beforeBorrowerBal).to.equal(afterBorrowerBal); + expect(beforePoolBal).to.equal(afterPoolBal); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 1217, + streamDays, + 0, + 0 + ); + + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + + await expect(nftContract.ownerOf(streamId)).to.be.revertedWith( + "ERC721: invalid token ID" + ); + }); + }); + }); + + it("Should revert when flow was decreased during the loan period", async function () { + const newFlowrate = loanAmount.div(BN.from(streamDuration)).div(4); + const calldata = genUpdateFlowCalldata(usdcx, poolProcessorContract, newFlowrate); + await expect( + sf.connect(payer).callAgreement(cfa.address, calldata, "0x") + ).to.be.revertedWithCustomError(poolProcessorContract, "invalidSuperfluidAction"); + }); + + it("Should revert when flow was increased during the loan period", async function () { + const newFlowrate = loanAmount.div(BN.from(streamDuration)).mul(2); + const calldata = genUpdateFlowCalldata(usdcx, poolProcessorContract, newFlowrate); + await expect( + sf.connect(payer).callAgreement(cfa.address, calldata, "0x") + ).to.be.revertedWithCustomError(poolProcessorContract, "invalidSuperfluidAction"); + }); + + it("Should revert when flow was created to processor from outside", async function () { + await deleteFlow(usdcx, payer, poolProcessorContract); + + const calldata = genCreateFlowCalldata(usdcx, poolProcessorContract, 1); + await expect( + sf.connect(payer).callAgreement(cfa.address, calldata, "0x") + ).to.be.revertedWithCustomError(poolProcessorContract, "invalidSuperfluidAction"); + }); + + // Comments out this test because current version doesn't support to increase/decrease flow rate. + + // it.skip("Should settlement and duration is increased when flow was decreased during the loan period, and no enough allowance", async function () { + // let balance = await usdc.balanceOf(borrower.address); + // let remainingBal = toUSDC(50); + // if (balance.gt(remainingBal)) { + // await usdc + // .connect(borrower) + // .transfer(defaultDeployer.address, balance.sub(remainingBal)); + // } else { + // remainingBal = balance; + // } + + // let cr = await poolContract.creditRecordMapping(borrower.address); + // const remainingTime = 3600 * 24 * 7; + // let nts = cr.dueDate.toNumber() - remainingTime; + // await setNextBlockTimestamp(nts); + + // const streamId = 1; + // let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + // let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + // let beforePoolBal = await usdc.balanceOf(poolContract.address); + // const newFlowrate = loanAmount.div(BN.from(streamDuration)).div(4); + // const calldata = genUpdateFlowCalldata(usdcx, poolProcessorContract, newFlowrate); + // await sf.connect(payer).callAgreement(cfa.address, calldata, "0x"); + // let afterBorrowerBal = await usdc.balanceOf(borrower.address); + // let afterPoolBal = await usdc.balanceOf(poolContract.address); + // let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + // expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + // expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + // expect(afterSI.lastStartTime).to.equal(nts); + // expect(afterSI.flowrate).to.equal(newFlowrate); + // expect(afterSI.endTime).to.equal(beforeSI.endTime); + // expect(afterSI.receivedFlowAmount).to.equal( + // BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + // ); + + // cr = await poolContract.creditRecordMapping(borrower.address); + // let crs = await poolContract.creditRecordStaticMapping(borrower.address); + // let correction = calcCorrection(cr, crs, nts, remainingBal); + // checkRecord( + // cr, + // crs, + // toUSDC(streamAmount), + // 0, + // "SKIP", + // correction, + // loanAmount.sub(remainingBal), + // 0, + // 0, + // 0, + // 1217, + // streamDays, + // 3, + // 0 + // ); + // let beforeNTS = nts; + // const expiration = 1000; + // nts = cr.dueDate.toNumber() + expiration; + // await setNextBlockTimestamp(nts); + + // beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + // beforeBorrowerBal = await usdc.balanceOf(borrower.address); + // beforePoolBal = await usdc.balanceOf(poolContract.address); + // await poolProcessorContract.settlement(nftContract.address, streamId); + // afterBorrowerBal = await usdc.balanceOf(borrower.address); + // afterPoolBal = await usdc.balanceOf(poolContract.address); + // afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + // let received = BN.from(beforeSI.endTime) + // .sub(beforeNTS) + // .mul(newFlowrate) + // .add(beforeSI.receivedFlowAmount); + // expect(afterPoolBal.sub(beforePoolBal)).to.equal(received); + // expect(afterBorrowerBal).to.equal(beforeBorrowerBal); + + // cr = await poolContract.creditRecordMapping(borrower.address); + // crs = await poolContract.creditRecordStaticMapping(borrower.address); + // printRecord(cr, crs); + // let unbilled = loanAmount.sub(remainingBal).sub(received).add(correction); + // let interest = calcInterest(crs, unbilled); + // checkRecord( + // cr, + // crs, + // toUSDC(streamAmount), + // 0, + // "SKIP", + // 0, + // unbilled.add(interest), + // interest, + // 1, + // 0, + // 1217, + // streamDays, + // 4, + // 0 + // ); + // let newEndTime = calcNewEndTime(cr, beforeSI); + // checkResults(afterSI, [ + // borrower.address, + // beforeSI.endTime, + // newEndTime, + // beforeSI.flowrate, + // 0, + // 0, + // ]); + // expect(await nftContract.maturesAt(streamId)).to.equal(afterSI.endTime); + + // nts = cr.dueDate.toNumber() + expiration; + // await setNextBlockTimestamp(nts); + + // beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + // beforeBorrowerBal = await usdc.balanceOf(borrower.address); + // beforePoolBal = await usdc.balanceOf(poolContract.address); + // await poolProcessorContract.settlement(nftContract.address, streamId); + // afterBorrowerBal = await usdc.balanceOf(borrower.address); + // afterPoolBal = await usdc.balanceOf(poolContract.address); + // afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + // received = BN.from(beforeSI.endTime) + // .sub(beforeSI.lastStartTime) + // .mul(beforeSI.flowrate); + // expect(afterPoolBal.sub(beforePoolBal)).to.equal(received); + // expect(afterBorrowerBal).to.equal(beforeBorrowerBal); + + // interest = calcInterest(crs, cr.totalDue); + // let totalDue = cr.totalDue.add(interest).sub(received); + + // cr = await poolContract.creditRecordMapping(borrower.address); + // crs = await poolContract.creditRecordStaticMapping(borrower.address); + // correction = calcCorrection(cr, crs, nts, received.sub(interest)); + // printRecord(cr, crs); + // checkRecord( + // cr, + // crs, + // toUSDC(streamAmount), + // 0, + // "SKIP", + // correction, + // totalDue, + // 0, + // 2, + // 0, + // 1217, + // streamDays, + // 4, + // 0 + // ); + // newEndTime = calcNewEndTime(cr, beforeSI); + // checkResults(afterSI, [ + // borrower.address, + // beforeSI.endTime, + // newEndTime, + // beforeSI.flowrate, + // 0, + // 0, + // ]); + // expect(await nftContract.maturesAt(streamId)).to.equal(afterSI.endTime); + + // nts = afterSI.endTime.toNumber() + expiration; + // await setNextBlockTimestamp(nts); + + // beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + // beforeBorrowerBal = await usdc.balanceOf(borrower.address); + // beforePoolBal = await usdc.balanceOf(poolContract.address); + // await poolProcessorContract.settlement(nftContract.address, streamId); + // afterBorrowerBal = await usdc.balanceOf(borrower.address); + // afterPoolBal = await usdc.balanceOf(poolContract.address); + // afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + // received = BN.from(beforeSI.endTime) + // .sub(beforeSI.lastStartTime) + // .mul(beforeSI.flowrate); + // correction = calcCorrection(cr, crs, nts, cr.totalDue.sub(cr.feesAndInterestDue)); + + // console.log(`cr.correction: ${cr.correction}, received: ${received}`); + + // // TODO fix the following expects + // expect(afterPoolBal.sub(beforePoolBal)).to.equal( + // received.add(cr.correction).add(correction) + // ); + // expect(afterBorrowerBal.add(cr.correction)).to.equal(beforeBorrowerBal); + + // cr = await poolContract.creditRecordMapping(borrower.address); + // crs = await poolContract.creditRecordStaticMapping(borrower.address); + // printRecord(cr, crs); + // }); + }); + + describe("Use front loading fee instead of interest apr", function () { + beforeEach(async function () { + const frontLoadingFeeBps = 100; + await feeManagerContract.connect(poolOwner).setFees(0, frontLoadingFeeBps, 0, 0, 0); + let result = await feeManagerContract.getFees(); + // console.log("fees: " + result); + + await poolContract + .connect(eaServiceAccount) + ["approveCredit(address,uint256,uint256,uint256,uint256,address,uint256,uint256)"]( + borrower.address, + toUSDC(streamAmount), + streamDays, + 1, + 0, + nftContract.address, + ethers.utils.solidityKeccak256( + ["address", "address", "address"], + [usdcx.address, payer.address, borrower.address] + ), + toUSDC(streamAmount) + ); + await usdc.connect(borrower).approve(poolProcessorContract.address, toUSDC(10_000)); + + const beforeAmount = await usdc.balanceOf(borrower.address); + + let flowrate = toDefaultToken(collateralAmount) + .div(BN.from(streamDuration)) + .add(BN.from(1)); + loanAmount = flowrate.mul(BN.from(streamDuration)); + const nonce = await nftContract.nonces(borrower.address); + const expiry = Math.ceil(Date.now() / 1000) + 300; + const signatureData = await borrower._signTypedData( + { + name: "TradableStream", + version: nftVersion, + chainId: HARDHAT_CHAIN_ID, + verifyingContract: nftContract.address, + }, + { + MintToWithAuthorization: [ + {name: "receiver", type: "address"}, + {name: "token", type: "address"}, + {name: "origin", type: "address"}, + {name: "owner", type: "address"}, + {name: "flowrate", type: "int96"}, + {name: "durationInSeconds", type: "uint256"}, + {name: "nonce", type: "uint256"}, + {name: "expiry", type: "uint256"}, + ], + }, + { + receiver: borrower.address, + token: usdcx.address, + origin: payer.address, + owner: poolProcessorContract.address, + flowrate: flowrate, + durationInSeconds: streamDuration, + nonce: nonce, + expiry: expiry, + } + ); + const signature = ethers.utils.splitSignature(signatureData); + const calldata = ethers.utils.defaultAbiCoder.encode( + [ + "address", + "address", + "address", + "int96", + "uint256", + "uint256", + "uint8", + "bytes32", + "bytes32", + ], + [ + borrower.address, + usdcx.address, + payer.address, + flowrate, + streamDuration, + expiry, + signature.v, + signature.r, + signature.s, + ] + ); + await poolProcessorContract.mintAndDrawdown( + borrower.address, + loanAmount, + nftContract.address, + calldata + ); + + const afterAmount = await usdc.balanceOf(borrower.address); + const receivedAmount = afterAmount.sub(beforeAmount); + const fee = loanAmount.mul(BN.from(frontLoadingFeeBps)).div(BN.from(10000)); + + expect(receivedAmount).to.equal(loanAmount.sub(fee)); + }); + + it("Should pay off correctly", async function () { + let cr = await poolContract.creditRecordMapping(borrower.address); + let crs = await poolContract.creditRecordStaticMapping(borrower.address); + // printRecord(cr, crs); + + const expiration = 10000; + const nts = cr.dueDate.toNumber() + expiration; + let block = await ethers.provider.getBlock(); + const beforeBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + const beforeReceivedAmount = BN.from(nts) + .sub(block.timestamp) + .mul(beforeBorrowerFlowrate); + await setNextBlockTimestamp(nts); + const streamId = 1; + let res = await nftContract.getTradableStreamData(streamId); + const flowrate = res[6]; + const si = await poolProcessorContract.streamInfoMapping(streamId); + const beforeBorrowAmount = await usdc.balanceOf(borrower.address); + const beforePoolAmount = await usdc.balanceOf(poolContract.address); + const beforeBorrowXAmount = await usdcx.balanceOf(borrower.address); + const beforeProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + await expect(poolProcessorContract.settlement(nftContract.address, streamId)) + .to.emit(poolProcessorContract, "SettlementMade") + .withArgs( + poolContract.address, + borrower.address, + si.flowKey, + nftContract.address, + streamId + ); + const afterBorrowAmount = await usdc.balanceOf(borrower.address); + const afterPoolAmount = await usdc.balanceOf(poolContract.address); + const afterBorrowXAmount = await usdcx.balanceOf(borrower.address); + const afterProcessorFlowrate = await cfa.getNetFlow( + usdcx.address, + poolProcessorContract.address + ); + const afterBorrowerFlowrate = await cfa.getNetFlow(usdcx.address, borrower.address); + // console.log( + // `afterBorrowAmount: ${afterBorrowAmount}, beforeBorrowAmount: ${beforeBorrowAmount}` + // ); + expect(afterBorrowAmount.sub(beforeBorrowAmount)).to.equal(0); + expect(afterPoolAmount.sub(beforePoolAmount)).to.equal(loanAmount); + expect(beforeProcessorFlowrate.sub(afterProcessorFlowrate)).to.equal( + afterBorrowerFlowrate.sub(beforeBorrowerFlowrate) + ); + expect(afterBorrowerFlowrate.sub(beforeBorrowerFlowrate)).to.equal(flowrate); + await expect(nftContract.ownerOf(streamId)).to.be.revertedWith( + "ERC721: invalid token ID" + ); + expect(afterBorrowXAmount.sub(beforeBorrowXAmount).sub(beforeReceivedAmount)).to.equal( + si.flowrate.mul(BN.from(expiration)) + ); + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + // printRecord(cr, crs); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + "SKIP", + 0, + 0, + 0, + 0, + 0, + streamDays, + 0, + 0 + ); + checkResults(await poolContract.receivableInfoMapping(borrower.address), [ + ethers.constants.AddressZero, + 0, + 0, + ]); + checkResults(await poolProcessorContract.streamInfoMapping(streamId), [ + ethers.constants.AddressZero, + 0, + 0, + 0, + 0, + ethers.constants.HashZero, + ]); + + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + expect(await poolProcessorContract.flowEndMapping(flowKey)).to.equal(0); + }); + + it("Should pay off correctly if the flow was terminated", async function () { + await sfRegisterContract.register(poolProcessorContract.address); + + let balance = await usdc.balanceOf(borrower.address); + let remainingBal = toUSDC(10); + if (balance.gt(remainingBal)) { + await usdc + .connect(borrower) + .transfer(defaultDeployer.address, balance.sub(remainingBal)); + } else { + remainingBal = balance; + } + + let cr = await poolContract.creditRecordMapping(borrower.address); + const remainingTime = 3600 * 24 * 7; + let nts = cr.dueDate.toNumber() - remainingTime; + await setNextBlockTimestamp(nts); + + await deleteFlow(usdcx, payer, poolProcessorContract); + + const streamId = 1; + const flowId = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + ["address", "address"], + [payer.address, poolProcessorContract.address] + ) + ); + const flowKey = ethers.utils.solidityKeccak256( + ["address", "bytes32"], + [usdcx.address, flowId] + ); + let beforeSI = await poolProcessorContract.streamInfoMapping(streamId); + let beforeBorrowerBal = await usdc.balanceOf(borrower.address); + let beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.onTerminatedFlow(flowKey, streamId); + let afterBorrowerBal = await usdc.balanceOf(borrower.address); + let afterPoolBal = await usdc.balanceOf(poolContract.address); + let afterSI = await poolProcessorContract.streamInfoMapping(streamId); + + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal(remainingBal); + expect(afterPoolBal.sub(beforePoolBal)).to.equal(remainingBal); + expect(afterSI.lastStartTime).to.equal(nts); + expect(afterSI.flowrate).to.equal(0); + expect(afterSI.endTime).to.equal(beforeSI.endTime); + expect(afterSI.receivedFlowAmount).to.equal( + BN.from(nts).sub(beforeSI.lastStartTime).mul(beforeSI.flowrate) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + let block = await ethers.provider.getBlock(); + let correction = calcCorrection(cr, crs, block.timestamp, remainingBal); + // console.log("correction: " + correction); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + correction, + loanAmount.sub(remainingBal), + 0, + 0, + 0, + 0, + streamDays, + 3, + 0 + ); + + await mint(borrower.address, toUSDC(streamAmount)); + + const expiration = 1000; + nts = cr.dueDate.toNumber() + expiration; + await setNextBlockTimestamp(nts); + + beforeBorrowerBal = await usdc.balanceOf(borrower.address); + beforePoolBal = await usdc.balanceOf(poolContract.address); + await poolProcessorContract.settlement(nftContract.address, streamId); + afterBorrowerBal = await usdc.balanceOf(borrower.address); + afterPoolBal = await usdc.balanceOf(poolContract.address); + + expect(afterPoolBal.sub(beforePoolBal)).to.equal( + loanAmount.sub(remainingBal).add(correction) + ); + expect(beforeBorrowerBal.sub(afterBorrowerBal)).to.equal( + loanAmount.sub(remainingBal).sub(afterSI.receivedFlowAmount).add(correction) + ); + + cr = await poolContract.creditRecordMapping(borrower.address); + crs = await poolContract.creditRecordStaticMapping(borrower.address); + checkRecord( + cr, + crs, + toUSDC(streamAmount), + 0, + "SKIP", + 0, + 0, + 0, + 0, + 0, + 0, + streamDays, + 0, + 0 + ); + }); + }); +}); diff --git a/yarn.lock b/yarn.lock index 5f0edc3a..52288420 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,12 +23,101 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/runtime@^7.4.4": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== + dependencies: + regenerator-runtime "^0.13.11" + "@colors/colors@1.5.0": version "1.5.0" resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.7.0": +"@decentral.ee/web3-helpers@0.5.3": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@decentral.ee/web3-helpers/-/web3-helpers-0.5.3.tgz#710aa9e90b186c5f7267150c4c5f3894fb52a2b4" + integrity sha512-6ZS2zpAUdWXhyZ8U7A4HzianIk3v5n051+QEezNdF3uOI7hJ7ty/MjNhxL3QqfiR+4cxKEz20UiAyZkU6/e2jA== + dependencies: + web3-utils "^1.3.4" + +"@ensdomains/address-encoder@^0.1.7": + version "0.1.9" + resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d" + integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg== + dependencies: + bech32 "^1.1.3" + blakejs "^1.1.0" + bn.js "^4.11.8" + bs58 "^4.0.1" + crypto-addr-codec "^0.1.7" + nano-base32 "^1.0.1" + ripemd160 "^2.0.2" + +"@ensdomains/ens@0.4.5": + version "0.4.5" + resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" + integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== + dependencies: + bluebird "^3.5.2" + eth-ens-namehash "^2.0.8" + solc "^0.4.20" + testrpc "0.0.1" + web3-utils "^1.0.0-beta.31" + +"@ensdomains/ensjs@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460" + integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog== + dependencies: + "@babel/runtime" "^7.4.4" + "@ensdomains/address-encoder" "^0.1.7" + "@ensdomains/ens" "0.4.5" + "@ensdomains/resolver" "0.2.4" + content-hash "^2.5.2" + eth-ens-namehash "^2.0.8" + ethers "^5.0.13" + js-sha3 "^0.8.0" + +"@ensdomains/resolver@0.2.4": + version "0.2.4" + resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" + integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== + +"@ethereumjs/common@2.5.0": + version "2.5.0" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268" + integrity sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.1" + +"@ethereumjs/common@^2.5.0", "@ethereumjs/common@^2.6.4": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" + integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== + dependencies: + crc-32 "^1.2.0" + ethereumjs-util "^7.1.5" + +"@ethereumjs/tx@3.3.2": + version "3.3.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.2.tgz#348d4624bf248aaab6c44fec2ae67265efe3db00" + integrity sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog== + dependencies: + "@ethereumjs/common" "^2.5.0" + ethereumjs-util "^7.1.2" + +"@ethereumjs/tx@^3.3.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.5.2.tgz#197b9b6299582ad84f9527ca961466fce2296c1c" + integrity sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw== + dependencies: + "@ethereumjs/common" "^2.6.4" + ethereumjs-util "^7.1.5" + +"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.5.0", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== @@ -204,6 +293,13 @@ dependencies: "@ethersproject/logger" "^5.7.0" +"@ethersproject/networks@5.7.1": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + "@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" @@ -245,6 +341,32 @@ bech32 "1.1.4" ws "7.4.6" +"@ethersproject/providers@5.7.2": + version "5.7.2" + resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" + integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/basex" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/random" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/sha2" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + bech32 "1.1.4" + ws "7.4.6" + "@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" @@ -303,7 +425,7 @@ "@ethersproject/constants" "^5.7.0" "@ethersproject/logger" "^5.7.0" -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": +"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== @@ -359,6 +481,17 @@ "@ethersproject/properties" "^5.7.0" "@ethersproject/strings" "^5.7.0" +"@ethersproject/web@5.7.1": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" @@ -556,6 +689,13 @@ deep-eql "^4.0.1" ordinal "^1.0.3" +"@nomicfoundation/hardhat-network-helpers@^1.0.7": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@nomicfoundation/hardhat-network-helpers/-/hardhat-network-helpers-1.0.8.tgz#e4fe1be93e8a65508c46d73c41fa26c7e9f84931" + integrity sha512-MNqQbzUJZnCMIYvlniC3U+kcavz/PhhQSsY90tbEtUyMj/IQqsLwIRZa4ctjABh3Bz0KCh9OXUZ7Yk/d9hr45Q== + dependencies: + ethereumjs-util "^7.1.4" + "@nomicfoundation/solidity-analyzer-darwin-arm64@0.0.3": version "0.0.3" resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.0.3.tgz#1d49e4ac028831a3011a9f3dca60bd1963185342" @@ -648,6 +788,11 @@ resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.3.tgz#6b076a7b751811b90fe3a172a7faeaa603e13a3f" integrity sha512-SXDRl7HKpl2WDoJpn7CK/M9U4Z8gNXDHHChAKh0Iz+Wew3wu6CmFYBeie3je8V0GSXZAIYYwUktSrnW/kwVPtg== +"@openzeppelin/contracts@4.8.0": + version "4.8.0" + resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.8.0.tgz#6854c37df205dd2c056bdfa1b853f5d732109109" + integrity sha512-AGuwhRRL+NaKx73WKRNzeCxOCOCxpaqF+kp8TJ89QzAipSwZy/NoflkWaL9bywXFRhIzXt8j38sfF7KBKCPWLw== + "@openzeppelin/contracts@^4.7.3": version "4.7.3" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.7.3.tgz#939534757a81f8d69cc854c7692805684ff3111e" @@ -766,6 +911,16 @@ "@sentry/types" "5.30.0" tslib "^1.9.3" +"@sindresorhus/is@^0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" + integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== + +"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + "@solidity-parser/parser@^0.14.0", "@solidity-parser/parser@^0.14.1", "@solidity-parser/parser@^0.14.3": version "0.14.3" resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.3.tgz#0d627427b35a40d8521aaa933cc3df7d07bfa36f" @@ -773,6 +928,54 @@ dependencies: antlr4ts "^0.5.0-alpha.4" +"@superfluid-finance/ethereum-contracts@^1.5.0": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@superfluid-finance/ethereum-contracts/-/ethereum-contracts-1.5.2.tgz#b82cd2e91c7a48c24072fc692496c5bfbb321fc2" + integrity sha512-3zFlobqB4x9LM77Fp8cxrD8AR4E1FYSjTJv1POdqACOgBFnRWASeI+nfQlIoRqaEWG6PJUauKhJKtHrw2I1Bpg== + dependencies: + "@decentral.ee/web3-helpers" "0.5.3" + "@openzeppelin/contracts" "4.8.0" + "@superfluid-finance/js-sdk" "0.6.3" + "@truffle/contract" "4.5.23" + ethereumjs-tx "2.1.2" + ethereumjs-util "7.1.5" + stack-trace "0.0.10" + +"@superfluid-finance/js-sdk@0.6.3": + version "0.6.3" + resolved "https://registry.yarnpkg.com/@superfluid-finance/js-sdk/-/js-sdk-0.6.3.tgz#af2ba3ad3ec927c07567f40b9c5b584ab10e9b6d" + integrity sha512-bSeV//KLAyseYwFVMGwrZmmS0iIZWx5FLGEEjXfi0oS42NFomD0MEt+iRyF7o/Jx6/8bfHGMH9I4s8LAWR27bQ== + dependencies: + "@superfluid-finance/metadata" "git+https://github.com/superfluid-finance/metadata.git" + "@truffle/contract" "4.5.23" + auto-bind "^4.0.0" + node-fetch "^2.6.7" + +"@superfluid-finance/metadata@git+https://github.com/superfluid-finance/metadata.git": + version "1.1.2" + resolved "git+https://github.com/superfluid-finance/metadata.git#2faa6fdf44616d5aaef0e1480535729bfe78d5e7" + +"@szmarczak/http-timer@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" + integrity sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA== + dependencies: + defer-to-connect "^1.0.1" + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@szmarczak/http-timer@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" + integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== + dependencies: + defer-to-connect "^2.0.1" + "@tenderly/hardhat-tenderly@^1.1.6": version "1.1.6" resolved "https://registry.yarnpkg.com/@tenderly/hardhat-tenderly/-/hardhat-tenderly-1.1.6.tgz#b706c7c337ebae7ecd314df3e8ee3d244ed1de08" @@ -786,6 +989,117 @@ hardhat-deploy "^0.11.10" js-yaml "^3.14.0" +"@truffle/abi-utils@^0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-0.3.9.tgz#c476f5cfe01072b513b3e93fd7bea05cf7bd9d96" + integrity sha512-G5dqgwRHx5zwlXjz3QT8OJVfB2cOqWwD6DwKso0KttUt/zejhCjnkKq72rSgyeLMkz7wBB9ERLOsupLBILM8MA== + dependencies: + change-case "3.0.2" + fast-check "3.1.1" + web3-utils "1.8.2" + +"@truffle/blockchain-utils@^0.1.4": + version "0.1.7" + resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.1.7.tgz#cf7923a3ae5b591ae4c2a5ee45994a310ccaf1ee" + integrity sha512-1nibqGjEHC7KAyDThEFvbm2+EO8zAHee/VjCtxkYBE3ySwP50joh0QCEBjy7K/9z+icpMoDucfxmgaKToBFUgQ== + +"@truffle/codec@^0.14.16": + version "0.14.16" + resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.14.16.tgz#eebfb169e46709d6cee53f069a53fc1dff410eaa" + integrity sha512-a9UY3n/FnkKN3Q4zOuMFOOcLWb80mdknj+voim4vvXYtJm1aAZQZE5sG9aLnMBTl4TiGLzUtfNDVYY7WgWgDag== + dependencies: + "@truffle/abi-utils" "^0.3.9" + "@truffle/compile-common" "^0.9.4" + big.js "^6.0.3" + bn.js "^5.1.3" + cbor "^5.2.0" + debug "^4.3.1" + lodash "^4.17.21" + semver "7.3.7" + utf8 "^3.0.0" + web3-utils "1.8.2" + +"@truffle/compile-common@^0.9.4": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.9.4.tgz#064208cda70491692b538f717809bb904a122c20" + integrity sha512-mnqJB/hLiPHNf+WKwt/2MH6lv34xSG/SFCib7+ckAklutUqVLeFo8EwQxinuHNkU7LY0C+YgZXhK1WTCO5YRJQ== + dependencies: + "@truffle/error" "^0.2.0" + colors "1.4.0" + +"@truffle/contract-schema@^3.4.9": + version "3.4.13" + resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.4.13.tgz#48447673f29380830f5821e8139ceefbbd545aac" + integrity sha512-emG7upuryYFrsPDbHqeASPWXL824M1tinhQwSPG0phSoa3g+RX9fUNNN/VPmF3tSkXLWUMhRnb7ehxnaCuRbZg== + dependencies: + ajv "^6.10.0" + debug "^4.3.1" + +"@truffle/contract@4.5.23": + version "4.5.23" + resolved "https://registry.yarnpkg.com/@truffle/contract/-/contract-4.5.23.tgz#8540f0c2d4ebc4782f1d4647016213fa4cac0107" + integrity sha512-ni/RzBdDFo60jaCb8ETCPBfPHRr1WVH5Y27EKmfEyrNg8TC7WZ28SQylMBkwdrgLjqAyPw3Pq7Y5us1f9tcyMQ== + dependencies: + "@ensdomains/ensjs" "^2.1.0" + "@truffle/blockchain-utils" "^0.1.4" + "@truffle/contract-schema" "^3.4.9" + "@truffle/debug-utils" "^6.0.33" + "@truffle/error" "^0.1.1" + "@truffle/interface-adapter" "^0.5.21" + bignumber.js "^7.2.1" + debug "^4.3.1" + ethers "^4.0.32" + web3 "1.7.4" + web3-core-helpers "1.7.4" + web3-core-promievent "1.7.4" + web3-eth-abi "1.7.4" + web3-utils "1.7.4" + +"@truffle/debug-utils@^6.0.33": + version "6.0.47" + resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.47.tgz#975f95be8d8a8eb11b35c7a8255b0a12ceaa51ba" + integrity sha512-bUjdzLPdEKtoUCDzaXkrOoi+PbyAJlMBzGequBK8tirT7xL9bCP2Pd/WxvnmRd7AnfroxGNvXwVXWTItW5SMWQ== + dependencies: + "@truffle/codec" "^0.14.16" + "@trufflesuite/chromafi" "^3.0.0" + bn.js "^5.1.3" + chalk "^2.4.2" + debug "^4.3.1" + highlightjs-solidity "^2.0.6" + +"@truffle/error@^0.1.1": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.1.1.tgz#e52026ac8ca7180d83443dca73c03e07ace2a301" + integrity sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA== + +"@truffle/error@^0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.2.0.tgz#65de6f03f5c041f883cc87677eecf8231428f1ab" + integrity sha512-Fe0/z4WWb7IP2gBnv3l6zqP87Y0kSMs7oiSLakKJq17q3GUunrHSdioKuNspdggxkXIBhEQLhi8C+LJdwmHKWQ== + +"@truffle/interface-adapter@^0.5.21": + version "0.5.31" + resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.31.tgz#9e62e9ed1c1c07d50d9e1dcffd6ef24efc1230e7" + integrity sha512-f5mOqbptQUUgHhBrBvWie4EUAUqHLN/wCBjFoP2N/QNcyvwGfdC3TSck9kjwIIFIgYgQQyAxQDGBQcjHryvxzg== + dependencies: + bn.js "^5.1.3" + ethers "^4.0.32" + web3 "1.8.2" + +"@trufflesuite/chromafi@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz#f6956408c1af6a38a6ed1657783ce59504a1eb8b" + integrity sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ== + dependencies: + camelcase "^4.1.0" + chalk "^2.3.2" + cheerio "^1.0.0-rc.2" + detect-indent "^5.0.0" + highlight.js "^10.4.1" + lodash.merge "^4.6.2" + strip-ansi "^4.0.0" + strip-indent "^2.0.0" + "@types/async-eventemitter@^0.2.1": version "0.2.1" resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz#f8e6280e87e8c60b2b938624b0a3530fb3e24712" @@ -805,6 +1119,16 @@ dependencies: "@types/node" "*" +"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2": + version "6.0.3" + resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + "@types/chai-as-promised@^7.1.3": version "7.1.5" resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" @@ -839,6 +1163,18 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-cache-semantics@*": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" + integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== + +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + "@types/lru-cache@^5.1.0": version "5.1.1" resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" @@ -859,6 +1195,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== +"@types/node@^12.12.6": + version "12.20.55" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" + integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== + "@types/node@^8.0.0": version "8.10.66" resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" @@ -876,6 +1217,13 @@ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== +"@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/secp256k1@^4.0.1": version "4.0.3" resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" @@ -905,6 +1253,11 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" +abortcontroller-polyfill@^1.7.3: + version "1.7.5" + resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" + integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== + abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" @@ -918,6 +1271,14 @@ abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: module-error "^1.0.1" queue-microtask "^1.2.3" +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + acorn-jsx@^5.0.0: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" @@ -958,7 +1319,7 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ajv@^6.10.2, ajv@^6.12.3, ajv@^6.6.1, ajv@^6.9.1: +ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.3, ajv@^6.6.1, ajv@^6.9.1: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1010,6 +1371,11 @@ ansi-escapes@^4.3.0: dependencies: type-fest "^0.21.3" +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + ansi-regex@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" @@ -1069,6 +1435,11 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -1095,6 +1466,16 @@ asap@~2.0.6: resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + asn1@~0.2.3: version "0.2.6" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" @@ -1134,6 +1515,11 @@ async-eventemitter@^0.2.4: dependencies: async "^2.4.0" +async-limiter@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" + integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== + async@1.x: version "1.5.2" resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" @@ -1156,6 +1542,16 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +auto-bind@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/auto-bind/-/auto-bind-4.0.0.tgz#e3589fc6c2da8f7ca43ba9f84fa52a744fc997fb" + integrity sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ== + +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + aws-sign2@~0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" @@ -1178,7 +1574,7 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base-x@^3.0.2: +base-x@^3.0.2, base-x@^3.0.8: version "3.0.9" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== @@ -1197,11 +1593,21 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" -bech32@1.1.4: +bech32@1.1.4, bech32@^1.1.3: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== +big-integer@1.6.36: + version "1.6.36" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" + integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== + +big.js@^6.0.3: + version "6.2.1" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" + integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== + bigint-crypto-utils@^3.0.23: version "3.1.4" resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.4.tgz#b00aa00eb792b14f2f71ead916105c17aac98a4c" @@ -1214,6 +1620,16 @@ bigint-mod-arith@^3.1.0: resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.0.tgz#ee7186ff512248e245f8c6ed0aa5c0ccf0c116b4" integrity sha512-vpiKCiv9B1nK8HhFOU7PMC4k9nrufQxeivgCj5yOH2ZMLD+UPwc/RfNgBCX+v8C6t0sF4q7mEZgZij6k53zpWA== +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== + +bignumber.js@^9.0.0: + version "9.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" + integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + bignumber.js@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.0.tgz#8d340146107fe3a6cb8d40699643c302e8773b62" @@ -1229,21 +1645,67 @@ blakejs@^1.1.0: resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== +bluebird@^3.5.0, bluebird@^3.5.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + bn.js@4.11.6: version "4.11.6" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== -bn.js@^4.11.0, bn.js@^4.11.8, bn.js@^4.11.9: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9: version "4.12.0" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== -bn.js@^5.1.2, bn.js@^5.2.0, bn.js@^5.2.1: +bn.js@^5.0.0, bn.js@^5.1.1, bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1: version "5.2.1" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== +body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + +body-parser@^1.16.0: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== + dependencies: + bytes "3.1.2" + content-type "~1.0.5" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.2" + type-is "~1.6.18" + unpipe "1.0.0" + +boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1266,7 +1728,7 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -brorand@^1.1.0: +brorand@^1.0.1, brorand@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== @@ -1286,7 +1748,7 @@ browser-stdout@1.3.1: resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== -browserify-aes@^1.2.0: +browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== @@ -1298,7 +1760,49 @@ browserify-aes@^1.2.0: inherits "^2.0.1" safe-buffer "^5.0.1" -bs58@^4.0.0: +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== @@ -1319,12 +1823,17 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== +buffer-to-arraybuffer@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" + integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== -buffer@^6.0.3: +buffer@6.0.3, buffer@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== @@ -1332,11 +1841,62 @@ buffer@^6.0.3: base64-js "^1.3.1" ieee754 "^1.2.1" +buffer@^5.0.5, buffer@^5.5.0, buffer@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + +bufferutil@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + dependencies: + node-gyp-build "^4.3.0" + bytes@3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-lookup@^6.0.4: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385" + integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww== + +cacheable-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" + integrity sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^3.0.0" + lowercase-keys "^2.0.0" + normalize-url "^4.1.0" + responselike "^1.0.2" + +cacheable-request@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" + integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + call-bind@^1.0.0, call-bind@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" @@ -1369,6 +1929,24 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +camel-case@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== + camelcase@^5.0.0: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" @@ -1389,7 +1967,7 @@ catering@^2.1.0, catering@^2.1.1: resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== -cbor@^5.0.2: +cbor@^5.0.2, cbor@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== @@ -1424,7 +2002,7 @@ chai@^4.3.6: pathval "^1.1.1" type-detect "^4.0.5" -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.2, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1441,6 +2019,30 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" +change-case@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.2.tgz#fd48746cce02f03f0a672577d1d3a8dc2eceb037" + integrity sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA== + dependencies: + camel-case "^3.0.0" + constant-case "^2.0.0" + dot-case "^2.1.0" + header-case "^1.0.0" + is-lower-case "^1.1.0" + is-upper-case "^1.1.0" + lower-case "^1.1.1" + lower-case-first "^1.0.0" + no-case "^2.3.2" + param-case "^2.1.0" + pascal-case "^2.0.0" + path-case "^2.1.0" + sentence-case "^2.1.0" + snake-case "^2.1.0" + swap-case "^1.1.0" + title-case "^2.1.0" + upper-case "^1.1.1" + upper-case-first "^1.1.0" + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -1456,6 +2058,31 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0-rc.2: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.0.1" + htmlparser2 "^8.0.1" + parse5 "^7.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + chokidar@3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" @@ -1486,11 +2113,27 @@ chokidar@3.5.3, chokidar@^3.4.0, chokidar@^3.5.2: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + ci-info@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== +cids@^0.7.1: + version "0.7.5" + resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" + integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== + dependencies: + buffer "^5.5.0" + class-is "^1.1.0" + multibase "~0.6.0" + multicodec "^1.0.0" + multihashes "~0.4.15" + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" @@ -1499,6 +2142,11 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +class-is@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" + integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== + classic-level@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" @@ -1546,6 +2194,15 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.1.tgz#b0433d0b4e9c847ef18868a4ef16fd5fc8271c48" integrity sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw== +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + cliui@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" @@ -1564,6 +2221,18 @@ cliui@^7.0.2: strip-ansi "^6.0.0" wrap-ansi "^7.0.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -1635,11 +2304,55 @@ concat-stream@^1.6.0, concat-stream@^1.6.2: readable-stream "^2.2.2" typedarray "^0.0.6" +constant-case@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46" + integrity sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ== + dependencies: + snake-case "^2.1.0" + upper-case "^1.1.1" + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + +content-hash@^2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" + integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== + dependencies: + cids "^0.7.1" + multicodec "^0.5.5" + multihashes "^0.4.15" + +content-type@~1.0.4, content-type@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + cookie@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookiejar@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" + integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -1650,6 +2363,14 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== +cors@^2.8.1: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + cosmiconfig@^5.0.7: version "5.2.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-5.2.1.tgz#040f726809c591e77a17c0a3626ca45b4f168b1a" @@ -1665,6 +2386,14 @@ crc-32@^1.2.0: resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" @@ -1676,7 +2405,7 @@ create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: ripemd160 "^2.0.1" sha.js "^2.4.0" -create-hmac@^1.1.4, create-hmac@^1.1.7: +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== @@ -1688,6 +2417,13 @@ create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-fetch@^3.1.4: + version "3.1.5" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" + integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== + dependencies: + node-fetch "2.6.7" + cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -1704,6 +2440,60 @@ cross-spawn@^6.0.5: resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== +crypto-addr-codec@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz#e16cea892730178fe25a38f6d15b680cab3124ae" + integrity sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg== + dependencies: + base-x "^3.0.8" + big-integer "1.6.36" + blakejs "^1.1.0" + bs58 "^4.0.1" + ripemd160-min "0.0.6" + safe-buffer "^5.2.0" + sha3 "^2.1.1" + +crypto-browserify@3.12.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" + +css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -1716,6 +2506,13 @@ death@^1.1.0: resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== +debug@2.6.9, debug@^2.2.0, debug@^2.6.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" @@ -1723,21 +2520,14 @@ debug@3.2.6: dependencies: ms "^2.1.1" -debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3: +debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" -debug@^2.6.0: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -decamelize@^1.2.0: +decamelize@^1.1.1, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== @@ -1747,6 +2537,25 @@ decamelize@^4.0.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== +decode-uri-component@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + +decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== + dependencies: + mimic-response "^1.0.0" + +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + deep-eql@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" @@ -1766,6 +2575,16 @@ deep-is@~0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +defer-to-connect@^1.0.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" + integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== + +defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" @@ -1794,6 +2613,24 @@ depd@2.0.0: resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== + detect-port@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" @@ -1812,6 +2649,15 @@ diff@5.0.0: resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + difflib@^0.2.4: version "0.2.4" resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" @@ -1833,11 +2679,58 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + +domutils@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" + integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.1" + +dot-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee" + integrity sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug== + dependencies: + no-case "^2.2.0" + dotenv@^16.0.2: version "16.0.2" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.2.tgz#0b0f8652c016a3858ef795024508cddc4bffc5bf" integrity sha512-JvpYKUmzQhYoIFgK2MOnF3bciIZoItIIoryihy0rIA+H4Jy0FmgyKYAHCTN98P5ybGSJcIFbh6QKeJdtZd1qhA== +duplexer3@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.5.tgz#0b5e4d7bad5de8901ea4440624c8e1d20099217e" + integrity sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA== + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -1846,7 +2739,12 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -elliptic@6.5.4, elliptic@^6.5.2, elliptic@^6.5.4: +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + +elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -1879,6 +2777,18 @@ encode-utf8@^1.0.2: resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== +encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + +end-of-stream@^1.1.0: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + enquirer@^2.3.0, enquirer@^2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" @@ -1886,12 +2796,17 @@ enquirer@^2.3.0, enquirer@^2.3.6: dependencies: ansi-colors "^4.1.1" +entities@^4.2.0, entities@^4.3.0, entities@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" + integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== -error-ex@^1.3.1: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== @@ -1941,11 +2856,47 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-promise@^4.2.8: + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -2083,6 +3034,19 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + +eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" + integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw== + dependencies: + idna-uts46-hx "^2.3.1" + js-sha3 "^0.5.7" + eth-gas-reporter@^0.2.25: version "0.2.25" resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566" @@ -2104,6 +3068,27 @@ eth-gas-reporter@^0.2.25: sha1 "^1.1.1" sync-request "^6.0.0" +eth-lib@0.2.8: + version "0.2.8" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" + integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + xhr-request-promise "^0.1.2" + +eth-lib@^0.1.26: + version "0.1.29" + resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" + integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + nano-json-stream-parser "^0.1.2" + servify "^0.1.12" + ws "^3.0.0" + xhr-request-promise "^0.1.2" + ethereum-bloom-filters@^1.0.6: version "1.0.10" resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" @@ -2150,6 +3135,30 @@ ethereumjs-abi@^0.6.8: bn.js "^4.11.8" ethereumjs-util "^6.0.0" +ethereumjs-common@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/ethereumjs-common/-/ethereumjs-common-1.5.2.tgz#2065dbe9214e850f2e955a80e650cb6999066979" + integrity sha512-hTfZjwGX52GS2jcVO6E2sx4YuFnf0Fhp5ylo4pEPhEffNln7vS59Hr5sLnp3/QCazFLluuBZ+FZ6J5HTp0EqCA== + +ethereumjs-tx@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereumjs-tx/-/ethereumjs-tx-2.1.2.tgz#5dfe7688bf177b45c9a23f86cf9104d47ea35fed" + integrity sha512-zZEK1onCeiORb0wyCXUvg94Ve5It/K6GD1K+26KfFKodiBiS6d9lfCXlUKGBBdQ+bv7Day+JK0tj1K+BeNFRAw== + dependencies: + ethereumjs-common "^1.5.0" + ethereumjs-util "^6.0.0" + +ethereumjs-util@7.1.5, ethereumjs-util@^7.0.10, ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: + version "7.1.5" + resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" + integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== + dependencies: + "@types/bn.js" "^5.1.0" + bn.js "^5.1.2" + create-hash "^1.1.2" + ethereum-cryptography "^0.1.3" + rlp "^2.2.4" + ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" @@ -2163,18 +3172,7 @@ ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: ethjs-util "0.1.6" rlp "^2.2.3" -ethereumjs-util@^7.0.3, ethereumjs-util@^7.1.0: - version "7.1.5" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" - integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== - dependencies: - "@types/bn.js" "^5.1.0" - bn.js "^5.1.2" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - rlp "^2.2.4" - -ethers@^4.0.40: +ethers@^4.0.32, ethers@^4.0.40: version "4.0.49" resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== @@ -2189,6 +3187,42 @@ ethers@^4.0.40: uuid "2.0.1" xmlhttprequest "1.8.0" +ethers@^5.0.13: + version "5.7.2" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" + integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== + dependencies: + "@ethersproject/abi" "5.7.0" + "@ethersproject/abstract-provider" "5.7.0" + "@ethersproject/abstract-signer" "5.7.0" + "@ethersproject/address" "5.7.0" + "@ethersproject/base64" "5.7.0" + "@ethersproject/basex" "5.7.0" + "@ethersproject/bignumber" "5.7.0" + "@ethersproject/bytes" "5.7.0" + "@ethersproject/constants" "5.7.0" + "@ethersproject/contracts" "5.7.0" + "@ethersproject/hash" "5.7.0" + "@ethersproject/hdnode" "5.7.0" + "@ethersproject/json-wallets" "5.7.0" + "@ethersproject/keccak256" "5.7.0" + "@ethersproject/logger" "5.7.0" + "@ethersproject/networks" "5.7.1" + "@ethersproject/pbkdf2" "5.7.0" + "@ethersproject/properties" "5.7.0" + "@ethersproject/providers" "5.7.2" + "@ethersproject/random" "5.7.0" + "@ethersproject/rlp" "5.7.0" + "@ethersproject/sha2" "5.7.0" + "@ethersproject/signing-key" "5.7.0" + "@ethersproject/solidity" "5.7.0" + "@ethersproject/strings" "5.7.0" + "@ethersproject/transactions" "5.7.0" + "@ethersproject/units" "5.7.0" + "@ethersproject/wallet" "5.7.0" + "@ethersproject/web" "5.7.1" + "@ethersproject/wordlists" "5.7.0" + ethers@^5.5.3, ethers@^5.6.8, ethers@^5.7.0: version "5.7.0" resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.0.tgz#0055da174b9e076b242b8282638bc94e04b39835" @@ -2246,7 +3280,12 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -evp_bytestokey@^1.0.3: +eventemitter3@4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== @@ -2254,6 +3293,50 @@ evp_bytestokey@^1.0.3: md5.js "^1.3.4" safe-buffer "^5.1.1" +express@^4.14.0: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" @@ -2278,6 +3361,13 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== +fast-check@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.1.tgz#72c5ae7022a4e86504762e773adfb8a5b0b01252" + integrity sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA== + dependencies: + pure-rand "^5.0.1" + fast-deep-equal@^3.1.1: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -2337,6 +3427,19 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + find-up@3.0.0, find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -2352,6 +3455,14 @@ find-up@5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" @@ -2397,11 +3508,23 @@ follow-redirects@^1.12.1, follow-redirects@^1.14.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== +form-data-encoder@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96" + integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== + form-data@^2.2.0: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -2429,6 +3552,11 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + fp-ts@1.19.3: version "1.19.3" resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" @@ -2439,6 +3567,11 @@ fp-ts@^1.0.0: resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== +fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + fs-extra@^0.30.0: version "0.30.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" @@ -2459,6 +3592,15 @@ fs-extra@^10.0.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + fs-extra@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" @@ -2487,6 +3629,13 @@ fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -2532,6 +3681,11 @@ functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== + get-caller-file@^2.0.1, get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" @@ -2551,11 +3705,39 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1, get-intrinsic@ has "^1.0.3" has-symbols "^1.0.3" +get-intrinsic@^1.1.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-port@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== +get-stream@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + +get-stream@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + get-symbol-description@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" @@ -2649,6 +3831,14 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" +global@~4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + globals@^11.7.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -2668,6 +3858,66 @@ globby@^10.0.1: merge2 "^1.2.3" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + +got@12.1.0: + version "12.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4" + integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig== + dependencies: + "@sindresorhus/is" "^4.6.0" + "@szmarczak/http-timer" "^5.0.1" + "@types/cacheable-request" "^6.0.2" + "@types/responselike" "^1.0.0" + cacheable-lookup "^6.0.4" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + form-data-encoder "1.7.1" + get-stream "^6.0.1" + http2-wrapper "^2.1.10" + lowercase-keys "^3.0.0" + p-cancelable "^3.0.0" + responselike "^2.0.0" + +got@9.6.0: + version "9.6.0" + resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" + integrity sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q== + dependencies: + "@sindresorhus/is" "^0.14.0" + "@szmarczak/http-timer" "^1.1.2" + cacheable-request "^6.0.0" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^4.1.0" + lowercase-keys "^1.0.1" + mimic-response "^1.0.1" + p-cancelable "^1.0.0" + to-readable-stream "^1.0.0" + url-parse-lax "^3.0.0" + +got@^11.8.5: + version "11.8.6" + resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0, graceful-fs@^4.2.4: version "4.2.10" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" @@ -2887,11 +4137,29 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== +header-case@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d" + integrity sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.3" + "heap@>= 0.2.0": version "0.2.7" resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== +highlight.js@^10.4.1: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + +highlightjs-solidity@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-2.0.6.tgz#e7a702a2b05e0a97f185e6ba39fd4846ad23a990" + integrity sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -2901,6 +4169,21 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +htmlparser2@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" + integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + domutils "^3.0.1" + entities "^4.3.0" + http-basic@^8.1.1: version "8.1.3" resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" @@ -2911,6 +4194,11 @@ http-basic@^8.1.1: http-response-object "^3.0.1" parse-cache-control "^1.0.1" +http-cache-semantics@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + http-errors@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" @@ -2922,6 +4210,11 @@ http-errors@2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-https@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" + integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg== + http-response-object@^3.0.1: version "3.0.2" resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" @@ -2938,6 +4231,22 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + +http2-wrapper@^2.1.10: + version "2.2.0" + resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3" + integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.2.0" + https-proxy-agent@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" @@ -2958,7 +4267,14 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -ieee754@^1.2.1: +idna-uts46-hx@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" + integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== + dependencies: + punycode "2.1.0" + +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -3060,6 +4376,11 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== + io-ts@1.10.4: version "1.10.4" resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" @@ -3067,6 +4388,19 @@ io-ts@1.10.4: dependencies: fp-ts "^1.0.0" +ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" @@ -3099,6 +4433,11 @@ is-buffer@^2.0.5, is-buffer@~2.0.3: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-callable@^1.1.4, is-callable@^1.2.4: version "1.2.4" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" @@ -3128,6 +4467,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -3138,6 +4484,18 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-function@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -3150,6 +4508,13 @@ is-hex-prefixed@1.0.0: resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== +is-lower-case@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393" + integrity sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA== + dependencies: + lower-case "^1.1.0" + is-negative-zero@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" @@ -3201,7 +4566,18 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: dependencies: has-symbols "^1.0.2" -is-typedarray@~1.0.0: +is-typed-array@^1.1.10, is-typed-array@^1.1.3: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== @@ -3211,6 +4587,18 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-upper-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" + integrity sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw== + dependencies: + upper-case "^1.1.0" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + is-weakref@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" @@ -3233,7 +4621,7 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== -js-sha3@0.5.7: +js-sha3@0.5.7, js-sha3@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== @@ -3276,6 +4664,16 @@ jsbn@~0.1.0: resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + integrity sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ== + +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" @@ -3353,6 +4751,20 @@ keccak@^3.0.0, keccak@^3.0.2: node-gyp-build "^4.2.0" readable-stream "^3.6.0" +keyv@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.1.0.tgz#ecc228486f69991e49e9476485a5be1e8fc5c4d9" + integrity sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA== + dependencies: + json-buffer "3.0.0" + +keyv@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" + integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -3365,6 +4777,13 @@ klaw@^1.0.0: optionalDependencies: graceful-fs "^4.1.9" +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== + dependencies: + invert-kv "^1.0.0" + level-supports@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" @@ -3394,6 +4813,17 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -3417,6 +4847,16 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lodash.assign@^4.0.3, lodash.assign@^4.0.6: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" + integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + lodash.truncate@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" @@ -3449,17 +4889,44 @@ loupe@^2.3.1: dependencies: get-func-name "^2.0.0" -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== +lower-case-first@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1" + integrity sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA== dependencies: - yallist "^3.0.2" + lower-case "^1.1.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== +lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA== + +lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + integrity sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA== + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lowercase-keys@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" + integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== dependencies: yallist "^4.0.0" @@ -3492,6 +4959,11 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + memory-level@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" @@ -3506,11 +4978,21 @@ memorystream@^0.3.1: resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + merge2@^1.2.3, merge2@^1.3.0: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + micromatch@^4.0.4: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" @@ -3519,23 +5001,53 @@ micromatch@^4.0.4: braces "^3.0.2" picomatch "^2.3.1" +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== -mime-types@^2.1.12, mime-types@~2.1.19: +mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: version "2.1.35" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== dependencies: mime-db "1.52.0" +mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mimic-response@^1.0.0, mimic-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== + dependencies: + dom-walk "^0.1.0" + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -3572,6 +5084,33 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mkdirp-promise@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" + integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w== + dependencies: + mkdirp "*" + +mkdirp@*: + version "2.1.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.5.tgz#78d7eaf15e069ba7b6b47d76dd94cfadf7a4062f" + integrity sha512-jbjfql+shJtAPrFoKxHOXip4xS+kul9W3OzfzzrqueWK2QMGon2bFH2opl6W9EagBThjEz+iysyi/swOoVfB/w== + mkdirp@0.5.5: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -3579,7 +5118,7 @@ mkdirp@0.5.5: dependencies: minimist "^1.2.5" -mkdirp@0.5.x, mkdirp@^0.5.1: +mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -3681,6 +5220,11 @@ mocha@^7.1.1: yargs-parser "13.1.2" yargs-unparser "1.6.0" +mock-fs@^4.1.0: + version "4.14.0" + resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" + integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== + module-error@^1.0.1, module-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" @@ -3706,6 +5250,46 @@ ms@2.1.3, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multibase@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" + integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multibase@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" + integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== + dependencies: + base-x "^3.0.8" + buffer "^5.5.0" + +multicodec@^0.5.5: + version "0.5.7" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" + integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== + dependencies: + varint "^5.0.0" + +multicodec@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" + integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== + dependencies: + buffer "^5.6.0" + varint "^5.0.0" + +multihashes@^0.4.15, multihashes@~0.4.15: + version "0.4.21" + resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" + integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== + dependencies: + buffer "^5.5.0" + multibase "^0.7.0" + varint "^5.0.0" + murmur-128@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/murmur-128/-/murmur-128-0.2.1.tgz#a9f6568781d2350ecb1bf80c14968cadbeaa4b4d" @@ -3720,6 +5304,16 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ== +nano-base32@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" + integrity sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw== + +nano-json-stream-parser@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" + integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== + nanoid@3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" @@ -3735,16 +5329,33 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + neo-async@^2.6.0: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +no-case@^2.2.0, no-case@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + node-addon-api@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" @@ -3765,6 +5376,20 @@ node-environment-flags@1.0.6: object.getownpropertydescriptors "^2.0.3" semver "^5.7.0" +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@^2.6.7: + version "2.6.9" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" + integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== + dependencies: + whatwg-url "^5.0.0" + node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.5.0.tgz#7a64eefa0b21112f89f58379da128ac177f20e40" @@ -3792,11 +5417,43 @@ nopt@3.x: dependencies: abbrev "1" +normalize-package-data@^2.3.2: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +normalize-url@^4.1.0: + version "4.5.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" + integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== + +normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + +nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== + number-to-bn@1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" @@ -3810,7 +5467,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.1.0: +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== @@ -3860,7 +5517,21 @@ obliterator@^2.0.0: resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== -once@1.x, once@^1.3.0: +oboe@2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" + integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA== + dependencies: + http-https "^1.0.0" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== @@ -3891,11 +5562,33 @@ ordinal@^1.0.3: resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== + dependencies: + lcid "^1.0.0" + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== +p-cancelable@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" + integrity sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw== + +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + +p-cancelable@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" + integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -3955,6 +5648,13 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +param-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" + integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w== + dependencies: + no-case "^2.2.0" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -3962,11 +5662,34 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + parse-cache-control@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg== +parse-headers@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" + integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -3975,6 +5698,48 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + +parse5@^7.0.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" + integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== + dependencies: + entities "^4.4.0" + +parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + +pascal-case@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e" + integrity sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ== + dependencies: + camel-case "^3.0.0" + upper-case-first "^1.1.0" + +path-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5" + integrity sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q== + dependencies: + no-case "^2.2.0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -4010,6 +5775,20 @@ path-starts-with@^2.0.0: resolved "https://registry.yarnpkg.com/path-starts-with/-/path-starts-with-2.0.0.tgz#ffd6d51926cd497022b44d392196033d5451892f" integrity sha512-3UHTHbJz5+NLkPafFR+2ycJOjoc4WV2e9qCZCnm71zHiWaFrm1XniLVTkZXvaRgxr1xFh9JsTdicpH2yM03nLA== +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" @@ -4020,7 +5799,7 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== -pbkdf2@^3.0.17: +pbkdf2@^3.0.17, pbkdf2@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== @@ -4041,16 +5820,38 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + integrity sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA== + prettier-plugin-solidity@^1.0.0-beta.24: version "1.0.0-beta.24" resolved "https://registry.yarnpkg.com/prettier-plugin-solidity/-/prettier-plugin-solidity-1.0.0-beta.24.tgz#67573ca87098c14f7ccff3639ddd8a4cab2a87eb" @@ -4078,6 +5879,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -4099,22 +5905,60 @@ proper-lockfile@^4.1.1: retry "^0.12.0" signal-exit "^3.0.2" +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + psl@^1.1.28: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +punycode@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" + integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== + punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +pure-rand@^5.0.1: + version "5.0.5" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-5.0.5.tgz#bda2a7f6a1fc0f284d78d78ca5902f26f2ad35cf" + integrity sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw== + qrcode-terminal@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/qrcode-terminal/-/qrcode-terminal-0.12.0.tgz#bb5b699ef7f9f0505092a3748be4464fe71b5819" integrity sha512-EXtzRZmC+YGmGlDFbXKxQiMZNwCLEO6BANKXG4iCtSIM0yqc/pappSx3RIKr4r0uh5JsBckOXeKrB3Iz7mdQpQ== -qs@^6.4.0, qs@^6.7.0, qs@^6.9.4: +qs@6.11.0, qs@^6.4.0, qs@^6.7.0, qs@^6.9.4: version "6.11.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== @@ -4126,19 +5970,46 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + queue-microtask@^1.2.2, queue-microtask@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.1.0: +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" -raw-body@^2.4.1: +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + +raw-body@2.5.1, raw-body@^2.4.1: version "2.5.1" resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== @@ -4148,6 +6019,33 @@ raw-body@^2.4.1: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + readable-stream@^2.2.2: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" @@ -4198,6 +6096,11 @@ recursive-readdir@^2.2.2: dependencies: minimatch "3.0.4" +regenerator-runtime@^0.13.11: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + regexp.prototype.flags@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" @@ -4242,7 +6145,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -request@^2.88.0: +request@^2.79.0, request@^2.88.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -4273,16 +6176,31 @@ require-directory@^2.1.1: resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== +require-from-string@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" + integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q== + require-from-string@^2.0.0, require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== + require-main-filename@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +resolve-alpn@^1.0.0, resolve-alpn@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-from@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" @@ -4305,7 +6223,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6: +resolve@^1.1.6, resolve@^1.10.0: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -4314,6 +6232,20 @@ resolve@^1.1.6: path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + integrity sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ== + dependencies: + lowercase-keys "^1.0.0" + +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -4346,7 +6278,12 @@ rimraf@^2.2.8, rimraf@^2.6.2: dependencies: glob "^7.1.3" -ripemd160@^2.0.0, ripemd160@^2.0.1: +ripemd160-min@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" + integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== + +ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== @@ -4392,7 +6329,7 @@ rxjs@^6.4.0: dependencies: tslib "^1.9.0" -safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -4432,7 +6369,7 @@ scrypt-js@2.0.4: resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== -scrypt-js@3.0.1, scrypt-js@^3.0.0: +scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== @@ -4446,22 +6383,49 @@ secp256k1@^4.0.1: node-addon-api "^2.0.0" node-gyp-build "^4.2.0" -semver@^5.5.0, semver@^5.5.1, semver@^5.7.0: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.5.1, semver@^5.7.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== +semver@7.3.7, semver@^7.3.4, semver@^7.3.7: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.3.4, semver@^7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: - lru-cache "^6.0.0" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + +sentence-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4" + integrity sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ== + dependencies: + no-case "^2.2.0" + upper-case-first "^1.1.2" serialize-javascript@6.0.0: version "6.0.0" @@ -4470,6 +6434,27 @@ serialize-javascript@6.0.0: dependencies: randombytes "^2.1.0" +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + +servify@^0.1.12: + version "0.1.12" + resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" + integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== + dependencies: + body-parser "^1.16.0" + cors "^2.8.1" + express "^4.14.0" + request "^2.79.0" + xhr "^2.3.3" + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -4506,6 +6491,13 @@ sha1@^1.1.1: charenc ">= 0.0.1" crypt ">= 0.0.1" +sha3@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" + integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== + dependencies: + buffer "6.0.3" + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -4541,6 +6533,20 @@ signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== +simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + +simple-get@^2.7.0: + version "2.8.2" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" + integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== + dependencies: + decompress-response "^3.3.0" + once "^1.3.1" + simple-concat "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -4564,6 +6570,13 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" +snake-case@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" + integrity sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q== + dependencies: + no-case "^2.2.0" + solc@0.7.3: version "0.7.3" resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" @@ -4579,6 +6592,17 @@ solc@0.7.3: semver "^5.5.0" tmp "0.0.33" +solc@^0.4.20: + version "0.4.26" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" + integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== + dependencies: + fs-extra "^0.30.0" + memorystream "^0.3.1" + require-from-string "^1.1.0" + semver "^5.3.0" + yargs "^4.7.1" + solhint@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.3.7.tgz#b5da4fedf7a0fee954cb613b6c55a5a2b0063aa7" @@ -4657,6 +6681,32 @@ source-map@~0.2.0: dependencies: amdefine ">=0.0.4" +spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.13" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.13.tgz#7189a474c46f8d47c7b0da4b987bb45e908bd2d5" + integrity sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -4677,6 +6727,11 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +stack-trace@0.0.10: + version "0.0.10" + resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" + integrity sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg== + stacktrace-parser@^0.1.10: version "0.1.10" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" @@ -4694,6 +6749,20 @@ stealthy-require@^1.1.1: resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + "string-width@^1.0.2 || 2", string-width@^2.1.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" @@ -4752,6 +6821,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" @@ -4773,6 +6849,13 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + strip-hex-prefix@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" @@ -4780,6 +6863,11 @@ strip-hex-prefix@1.0.0: dependencies: is-hex-prefixed "1.0.0" +strip-indent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" + integrity sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA== + strip-json-comments@2.0.1, strip-json-comments@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -4830,6 +6918,31 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swap-case@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3" + integrity sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ== + dependencies: + lower-case "^1.1.1" + upper-case "^1.1.1" + +swarm-js@^0.1.40: + version "0.1.42" + resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979" + integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ== + dependencies: + bluebird "^3.5.0" + buffer "^5.0.5" + eth-lib "^0.1.26" + fs-extra "^4.0.2" + got "^11.8.5" + mime-types "^2.1.16" + mkdirp-promise "^5.0.1" + mock-fs "^4.1.0" + setimmediate "^1.0.5" + tar "^4.0.2" + xhr-request "^1.0.1" + sync-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" @@ -4867,6 +6980,24 @@ table@^6.8.0: string-width "^4.2.3" strip-ansi "^6.0.1" +tar@^4.0.2: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + +testrpc@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" + integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -4894,6 +7025,19 @@ through@^2.3.6: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== + +title-case@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" + integrity sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q== + dependencies: + no-case "^2.2.0" + upper-case "^1.0.3" + tmp@0.0.33, tmp@^0.0.33: version "0.0.33" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" @@ -4901,6 +7045,11 @@ tmp@0.0.33, tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +to-readable-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" + integrity sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -4921,6 +7070,11 @@ tough-cookie@^2.3.3, tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -4975,6 +7129,31 @@ type-fest@^0.7.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== +type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typedarray@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" @@ -4990,6 +7169,11 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.0.tgz#55bd6e9d19ce5eef0d5ad17cd1f587d85b180a85" integrity sha512-aTeNPVmgIMPpm1cxXr2Q/nEbvkmV8yq66F3om7X3P/cvOXQ0TMQ64Wk63iyT1gPlmdmGzjGpyLh1f3y8MZWXGg== +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -5015,11 +7199,23 @@ universalify@^2.0.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== -unpipe@1.0.0: +unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== +upper-case-first@^1.1.0, upper-case-first@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" + integrity sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ== + dependencies: + upper-case "^1.1.1" + +upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -5027,7 +7223,26 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" -utf8@3.0.0: +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + integrity sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ== + dependencies: + prepend-http "^2.0.0" + +url-set-query@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" + integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== + +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +utf8@3.0.0, utf8@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== @@ -5037,11 +7252,32 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== +util@^0.12.0, util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + +utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + uuid@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== +uuid@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== + uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -5052,6 +7288,29 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== +uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +varint@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" + integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== + +vary@^1, vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -5061,6 +7320,437 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +web3-bzz@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.7.4.tgz#9419e606e38a9777443d4ce40506ebd796e06075" + integrity sha512-w9zRhyEqTK/yi0LGRHjZMcPCfP24LBjYXI/9YxFw9VqsIZ9/G0CRCnUt12lUx0A56LRAMpF7iQ8eA73aBcO29Q== + dependencies: + "@types/node" "^12.12.6" + got "9.6.0" + swarm-js "^0.1.40" + +web3-bzz@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.8.2.tgz#67ea1c775874056250eece551ded22905ed08784" + integrity sha512-1EEnxjPnFnvNWw3XeeKuTR8PBxYd0+XWzvaLK7OJC/Go9O8llLGxrxICbKV+8cgIE0sDRBxiYx02X+6OhoAQ9w== + dependencies: + "@types/node" "^12.12.6" + got "12.1.0" + swarm-js "^0.1.40" + +web3-core-helpers@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.7.4.tgz#f8f808928560d3e64e0c8d7bdd163aa4766bcf40" + integrity sha512-F8PH11qIkE/LpK4/h1fF/lGYgt4B6doeMi8rukeV/s4ivseZHHslv1L6aaijLX/g/j4PsFmR42byynBI/MIzFg== + dependencies: + web3-eth-iban "1.7.4" + web3-utils "1.7.4" + +web3-core-helpers@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.8.2.tgz#82066560f8085e6c7b93bcc8e88b441289ea9f9f" + integrity sha512-6B1eLlq9JFrfealZBomd1fmlq1o4A09vrCVQSa51ANoib/jllT3atZrRDr0zt1rfI7TSZTZBXdN/aTdeN99DWw== + dependencies: + web3-eth-iban "1.8.2" + web3-utils "1.8.2" + +web3-core-method@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.7.4.tgz#3873c6405e1a0a8a1efc1d7b28de8b7550b00c15" + integrity sha512-56K7pq+8lZRkxJyzf5MHQPI9/VL3IJLoy4L/+q8HRdZJ3CkB1DkXYaXGU2PeylG1GosGiSzgIfu1ljqS7CP9xQ== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.7.4" + web3-core-promievent "1.7.4" + web3-core-subscriptions "1.7.4" + web3-utils "1.7.4" + +web3-core-method@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.8.2.tgz#ba5ec68084e903f0516415010477618be017eac2" + integrity sha512-1qnr5mw5wVyULzLOrk4B+ryO3gfGjGd/fx8NR+J2xCGLf1e6OSjxT9vbfuQ3fErk/NjSTWWreieYWLMhaogcRA== + dependencies: + "@ethersproject/transactions" "^5.6.2" + web3-core-helpers "1.8.2" + web3-core-promievent "1.8.2" + web3-core-subscriptions "1.8.2" + web3-utils "1.8.2" + +web3-core-promievent@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.7.4.tgz#80a75633fdfe21fbaae2f1e38950edb2f134868c" + integrity sha512-o4uxwXKDldN7ER7VUvDfWsqTx9nQSP1aDssi1XYXeYC2xJbVo0n+z6ryKtmcoWoRdRj7uSpVzal3nEmlr480mA== + dependencies: + eventemitter3 "4.0.4" + +web3-core-promievent@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.8.2.tgz#e670d6b4453632e6ecfd9ad82da44f77ac1585c9" + integrity sha512-nvkJWDVgoOSsolJldN33tKW6bKKRJX3MCPDYMwP5SUFOA/mCzDEoI88N0JFofDTXkh1k7gOqp1pvwi9heuaxGg== + dependencies: + eventemitter3 "4.0.4" + +web3-core-requestmanager@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.7.4.tgz#2dc8a526dab8183dca3fef54658621801b1d0469" + integrity sha512-IuXdAm65BQtPL4aI6LZJJOrKAs0SM5IK2Cqo2/lMNvVMT9Kssq6qOk68Uf7EBDH0rPuINi+ReLP+uH+0g3AnPA== + dependencies: + util "^0.12.0" + web3-core-helpers "1.7.4" + web3-providers-http "1.7.4" + web3-providers-ipc "1.7.4" + web3-providers-ws "1.7.4" + +web3-core-requestmanager@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.8.2.tgz#dda95e83ca4808949612a41e54ecea557f78ef26" + integrity sha512-p1d090RYs5Mu7DK1yyc3GCBVZB/03rBtFhYFoS2EruGzOWs/5Q0grgtpwS/DScdRAm8wB8mYEBhY/RKJWF6B2g== + dependencies: + util "^0.12.5" + web3-core-helpers "1.8.2" + web3-providers-http "1.8.2" + web3-providers-ipc "1.8.2" + web3-providers-ws "1.8.2" + +web3-core-subscriptions@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.7.4.tgz#cfbd3fa71081a8c8c6f1a64577a1a80c5bd9826f" + integrity sha512-VJvKWaXRyxk2nFWumOR94ut9xvjzMrRtS38c4qj8WBIRSsugrZr5lqUwgndtj0qx4F+50JhnU++QEqUEAtKm3g== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.7.4" + +web3-core-subscriptions@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.8.2.tgz#0c8bd49439d83c6f0a03c70f00b24a915a70a5ed" + integrity sha512-vXQogHDmAIQcKpXvGiMddBUeP9lnKgYF64+yQJhPNE5PnWr1sAibXuIPV7mIPihpFr/n/DORRj6Wh1pUv9zaTw== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.8.2" + +web3-core@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.7.4.tgz#943fff99134baedafa7c65b4a0bbd424748429ff" + integrity sha512-L0DCPlIh9bgIED37tYbe7bsWrddoXYc897ANGvTJ6MFkSNGiMwDkTLWSgYd9Mf8qu8b4iuPqXZHMwIo4atoh7Q== + dependencies: + "@types/bn.js" "^5.1.0" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.7.4" + web3-core-method "1.7.4" + web3-core-requestmanager "1.7.4" + web3-utils "1.7.4" + +web3-core@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.8.2.tgz#333e93d7872b1a36efe758ed8b89a7acbdd962c2" + integrity sha512-DJTVEAYcNqxkqruJE+Rxp3CIv0y5AZMwPHQmOkz/cz+MM75SIzMTc0AUdXzGyTS8xMF8h3YWMQGgGEy8SBf1PQ== + dependencies: + "@types/bn.js" "^5.1.0" + "@types/node" "^12.12.6" + bignumber.js "^9.0.0" + web3-core-helpers "1.8.2" + web3-core-method "1.8.2" + web3-core-requestmanager "1.8.2" + web3-utils "1.8.2" + +web3-eth-abi@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.7.4.tgz#3fee967bafd67f06b99ceaddc47ab0970f2a614a" + integrity sha512-eMZr8zgTbqyL9MCTCAvb67RbVyN5ZX7DvA0jbLOqRWCiw+KlJKTGnymKO6jPE8n5yjk4w01e165Qb11hTDwHgg== + dependencies: + "@ethersproject/abi" "^5.6.3" + web3-utils "1.7.4" + +web3-eth-abi@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.8.2.tgz#16e1e9be40e2527404f041a4745111211488f31a" + integrity sha512-Om9g3kaRNjqiNPAgKwGT16y+ZwtBzRe4ZJFGjLiSs6v5I7TPNF+rRMWuKnR6jq0azQZDj6rblvKFMA49/k48Og== + dependencies: + "@ethersproject/abi" "^5.6.3" + web3-utils "1.8.2" + +web3-eth-accounts@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.7.4.tgz#7a24a4dfe947f7e9d1bae678529e591aa146167a" + integrity sha512-Y9vYLRKP7VU7Cgq6wG1jFaG2k3/eIuiTKAG8RAuQnb6Cd9k5BRqTm5uPIiSo0AP/u11jDomZ8j7+WEgkU9+Btw== + dependencies: + "@ethereumjs/common" "^2.5.0" + "@ethereumjs/tx" "^3.3.2" + crypto-browserify "3.12.0" + eth-lib "0.2.8" + ethereumjs-util "^7.0.10" + scrypt-js "^3.0.1" + uuid "3.3.2" + web3-core "1.7.4" + web3-core-helpers "1.7.4" + web3-core-method "1.7.4" + web3-utils "1.7.4" + +web3-eth-accounts@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.8.2.tgz#b894f5d5158fcae429da42de75d96520d0712971" + integrity sha512-c367Ij63VCz9YdyjiHHWLFtN85l6QghgwMQH2B1eM/p9Y5lTlTX7t/Eg/8+f1yoIStXbk2w/PYM2lk+IkbqdLA== + dependencies: + "@ethereumjs/common" "2.5.0" + "@ethereumjs/tx" "3.3.2" + eth-lib "0.2.8" + ethereumjs-util "^7.1.5" + scrypt-js "^3.0.1" + uuid "^9.0.0" + web3-core "1.8.2" + web3-core-helpers "1.8.2" + web3-core-method "1.8.2" + web3-utils "1.8.2" + +web3-eth-contract@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.7.4.tgz#e5761cfb43d453f57be4777b2e5e7e1082078ff7" + integrity sha512-ZgSZMDVI1pE9uMQpK0T0HDT2oewHcfTCv0osEqf5qyn5KrcQDg1GT96/+S0dfqZ4HKj4lzS5O0rFyQiLPQ8LzQ== + dependencies: + "@types/bn.js" "^5.1.0" + web3-core "1.7.4" + web3-core-helpers "1.7.4" + web3-core-method "1.7.4" + web3-core-promievent "1.7.4" + web3-core-subscriptions "1.7.4" + web3-eth-abi "1.7.4" + web3-utils "1.7.4" + +web3-eth-contract@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.8.2.tgz#5388b7130923d2b790c09a420391a81312a867fb" + integrity sha512-ID5A25tHTSBNwOPjiXSVzxruz006ULRIDbzWTYIFTp7NJ7vXu/kynKK2ag/ObuTqBpMbobP8nXcA9b5EDkIdQA== + dependencies: + "@types/bn.js" "^5.1.0" + web3-core "1.8.2" + web3-core-helpers "1.8.2" + web3-core-method "1.8.2" + web3-core-promievent "1.8.2" + web3-core-subscriptions "1.8.2" + web3-eth-abi "1.8.2" + web3-utils "1.8.2" + +web3-eth-ens@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.7.4.tgz#346720305379c0a539e226141a9602f1da7bc0c8" + integrity sha512-Gw5CVU1+bFXP5RVXTCqJOmHn71X2ghNk9VcEH+9PchLr0PrKbHTA3hySpsPco1WJAyK4t8SNQVlNr3+bJ6/WZA== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.7.4" + web3-core-helpers "1.7.4" + web3-core-promievent "1.7.4" + web3-eth-abi "1.7.4" + web3-eth-contract "1.7.4" + web3-utils "1.7.4" + +web3-eth-ens@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.8.2.tgz#0a086ad4d919102e28b9fd3036df246add9df22a" + integrity sha512-PWph7C/CnqdWuu1+SH4U4zdrK4t2HNt0I4XzPYFdv9ugE8EuojselioPQXsVGvjql+Nt3jDLvQvggPqlMbvwRw== + dependencies: + content-hash "^2.5.2" + eth-ens-namehash "2.0.8" + web3-core "1.8.2" + web3-core-helpers "1.8.2" + web3-core-promievent "1.8.2" + web3-eth-abi "1.8.2" + web3-eth-contract "1.8.2" + web3-utils "1.8.2" + +web3-eth-iban@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.7.4.tgz#711fb2547fdf0f988060027331b2b6c430505753" + integrity sha512-XyrsgWlZQMv5gRcjXMsNvAoCRvV5wN7YCfFV5+tHUCqN8g9T/o4XUS20vDWD0k4HNiAcWGFqT1nrls02MGZ08w== + dependencies: + bn.js "^5.2.1" + web3-utils "1.7.4" + +web3-eth-iban@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.8.2.tgz#5cb3022234b13986f086353b53f0379a881feeaf" + integrity sha512-h3vNblDWkWMuYx93Q27TAJz6lhzpP93EiC3+45D6xoz983p6si773vntoQ+H+5aZhwglBtoiBzdh7PSSOnP/xQ== + dependencies: + bn.js "^5.2.1" + web3-utils "1.8.2" + +web3-eth-personal@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.7.4.tgz#22c399794cb828a75703df8bb4b3c1331b471546" + integrity sha512-O10C1Hln5wvLQsDhlhmV58RhXo+GPZ5+W76frSsyIrkJWLtYQTCr5WxHtRC9sMD1idXLqODKKgI2DL+7xeZ0/g== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.7.4" + web3-core-helpers "1.7.4" + web3-core-method "1.7.4" + web3-net "1.7.4" + web3-utils "1.7.4" + +web3-eth-personal@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.8.2.tgz#3526c1ebaa4e7bf3a0a8ec77e34f067cc9a750b2" + integrity sha512-Vg4HfwCr7doiUF/RC+Jz0wT4+cYaXcOWMAW2AHIjHX6Z7Xwa8nrURIeQgeEE62qcEHAzajyAdB1u6bJyTfuCXw== + dependencies: + "@types/node" "^12.12.6" + web3-core "1.8.2" + web3-core-helpers "1.8.2" + web3-core-method "1.8.2" + web3-net "1.8.2" + web3-utils "1.8.2" + +web3-eth@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.7.4.tgz#a7c1d3ccdbba4de4a82df7e3c4db716e4a944bf2" + integrity sha512-JG0tTMv0Ijj039emXNHi07jLb0OiWSA9O24MRSk5vToTQyDNXihdF2oyq85LfHuF690lXZaAXrjhtLNlYqb7Ug== + dependencies: + web3-core "1.7.4" + web3-core-helpers "1.7.4" + web3-core-method "1.7.4" + web3-core-subscriptions "1.7.4" + web3-eth-abi "1.7.4" + web3-eth-accounts "1.7.4" + web3-eth-contract "1.7.4" + web3-eth-ens "1.7.4" + web3-eth-iban "1.7.4" + web3-eth-personal "1.7.4" + web3-net "1.7.4" + web3-utils "1.7.4" + +web3-eth@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.8.2.tgz#8562287ae1803c30eb54dc7d832092e5739ce06a" + integrity sha512-JoTiWWc4F4TInpbvDUGb0WgDYJsFhuIjJlinc5ByjWD88Gvh+GKLsRjjFdbqe5YtwIGT4NymwoC5LQd1K6u/QQ== + dependencies: + web3-core "1.8.2" + web3-core-helpers "1.8.2" + web3-core-method "1.8.2" + web3-core-subscriptions "1.8.2" + web3-eth-abi "1.8.2" + web3-eth-accounts "1.8.2" + web3-eth-contract "1.8.2" + web3-eth-ens "1.8.2" + web3-eth-iban "1.8.2" + web3-eth-personal "1.8.2" + web3-net "1.8.2" + web3-utils "1.8.2" + +web3-net@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.7.4.tgz#3153dfd3423262dd6fbec7aae5467202c4cad431" + integrity sha512-d2Gj+DIARHvwIdmxFQ4PwAAXZVxYCR2lET0cxz4KXbE5Og3DNjJi+MoPkX+WqoUXqimu/EOd4Cd+7gefqVAFDg== + dependencies: + web3-core "1.7.4" + web3-core-method "1.7.4" + web3-utils "1.7.4" + +web3-net@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.8.2.tgz#97e1e0015fabc4cda31017813e98d0b5468dd04f" + integrity sha512-1itkDMGmbgb83Dg9nporFes9/fxsU7smJ3oRXlFkg4ZHn8YJyP1MSQFPJWWwSc+GrcCFt4O5IrUTvEkHqE3xag== + dependencies: + web3-core "1.8.2" + web3-core-method "1.8.2" + web3-utils "1.8.2" + +web3-providers-http@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.7.4.tgz#8209cdcb115db5ccae1f550d1c4e3005e7538d02" + integrity sha512-AU+/S+49rcogUER99TlhW+UBMk0N2DxvN54CJ2pK7alc2TQ7+cprNPLHJu4KREe8ndV0fT6JtWUfOMyTvl+FRA== + dependencies: + web3-core-helpers "1.7.4" + xhr2-cookies "1.1.0" + +web3-providers-http@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.8.2.tgz#fbda3a3bbc8db004af36e91bec35f80273b37885" + integrity sha512-2xY94IIEQd16+b+vIBF4IC1p7GVaz9q4EUFscvMUjtEq4ru4Atdzjs9GP+jmcoo49p70II0UV3bqQcz0TQfVyQ== + dependencies: + abortcontroller-polyfill "^1.7.3" + cross-fetch "^3.1.4" + es6-promise "^4.2.8" + web3-core-helpers "1.8.2" + +web3-providers-ipc@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.7.4.tgz#02e85e99e48f432c9d34cee7d786c3685ec9fcfa" + integrity sha512-jhArOZ235dZy8fS8090t60nTxbd1ap92ibQw5xIrAQ9m7LcZKNfmLAQUVsD+3dTFvadRMi6z1vCO7zRi84gWHw== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.7.4" + +web3-providers-ipc@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.8.2.tgz#e52a7250f40c83b99a2482ec5b4cf2728377ae5c" + integrity sha512-p6fqKVGFg+WiXGHWnB1hu43PbvPkDHTz4RgoEzbXugv5rtv5zfYLqm8Ba6lrJOS5ks9kGKR21a0y3NzE3u7V4w== + dependencies: + oboe "2.1.5" + web3-core-helpers "1.8.2" + +web3-providers-ws@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.7.4.tgz#6e60bcefb456f569a3e766e386d7807a96f90595" + integrity sha512-g72X77nrcHMFU8hRzQJzfgi/072n8dHwRCoTw+WQrGp+XCQ71fsk2qIu3Tp+nlp5BPn8bRudQbPblVm2uT4myQ== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.7.4" + websocket "^1.0.32" + +web3-providers-ws@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.8.2.tgz#56a2b701387011aca9154ca4bc06ea4b5f27e4ef" + integrity sha512-3s/4K+wHgbiN+Zrp9YjMq2eqAF6QGABw7wFftPdx+m5hWImV27/MoIx57c6HffNRqZXmCHnfWWFCNHHsi7wXnA== + dependencies: + eventemitter3 "4.0.4" + web3-core-helpers "1.8.2" + websocket "^1.0.32" + +web3-shh@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.7.4.tgz#bee91cce2737c529fd347274010b548b6ea060f1" + integrity sha512-mlSZxSYcMkuMCxqhTYnZkUdahZ11h+bBv/8TlkXp/IHpEe4/Gg+KAbmfudakq3EzG/04z70XQmPgWcUPrsEJ+A== + dependencies: + web3-core "1.7.4" + web3-core-method "1.7.4" + web3-core-subscriptions "1.7.4" + web3-net "1.7.4" + +web3-shh@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.8.2.tgz#217a417f0d6e243dd4d441848ffc2bd164cea8a0" + integrity sha512-uZ+3MAoNcaJsXXNCDnizKJ5viBNeHOFYsCbFhV755Uu52FswzTOw6DtE7yK9nYXMtIhiSgi7nwl1RYzP8pystw== + dependencies: + web3-core "1.8.2" + web3-core-method "1.8.2" + web3-core-subscriptions "1.8.2" + web3-net "1.8.2" + +web3-utils@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.7.4.tgz#eb6fa3706b058602747228234453811bbee017f5" + integrity sha512-acBdm6Evd0TEZRnChM/MCvGsMwYKmSh7OaUfNf5OKG0CIeGWD/6gqLOWIwmwSnre/2WrA1nKGId5uW2e5EfluA== + dependencies: + bn.js "^5.2.1" + ethereum-bloom-filters "^1.0.6" + ethereumjs-util "^7.1.0" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + +web3-utils@1.8.2, web3-utils@^1.0.0-beta.31, web3-utils@^1.3.4: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.2.tgz#c32dec5e9b955acbab220eefd7715bc540b75cc9" + integrity sha512-v7j6xhfLQfY7xQDrUP0BKbaNrmZ2/+egbqP9q3KYmOiPpnvAfol+32slgL0WX/5n8VPvKCK5EZ1HGrAVICSToA== + dependencies: + bn.js "^5.2.1" + ethereum-bloom-filters "^1.0.6" + ethereumjs-util "^7.1.0" + ethjs-unit "0.1.6" + number-to-bn "1.7.0" + randombytes "^2.1.0" + utf8 "3.0.0" + web3-utils@^1.3.6: version "1.8.1" resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.1.tgz#f2f7ca7eb65e6feb9f3d61056d0de6bbd57125ff" @@ -5074,6 +7764,57 @@ web3-utils@^1.3.6: randombytes "^2.1.0" utf8 "3.0.0" +web3@1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.7.4.tgz#00c9aef8e13ade92fd773d845fff250535828e93" + integrity sha512-iFGK5jO32vnXM/ASaJBaI0+gVR6uHozvYdxkdhaeOCD6HIQ4iIXadbO2atVpE9oc/H8l2MovJ4LtPhG7lIBN8A== + dependencies: + web3-bzz "1.7.4" + web3-core "1.7.4" + web3-eth "1.7.4" + web3-eth-personal "1.7.4" + web3-net "1.7.4" + web3-shh "1.7.4" + web3-utils "1.7.4" + +web3@1.8.2: + version "1.8.2" + resolved "https://registry.yarnpkg.com/web3/-/web3-1.8.2.tgz#95a4e5398fd0f01325264bf8e5e8cdc69a7afe86" + integrity sha512-92h0GdEHW9wqDICQQKyG4foZBYi0OQkyg4CRml2F7XBl/NG+fu9o6J19kzfFXzSBoA4DnJXbyRgj/RHZv5LRiw== + dependencies: + web3-bzz "1.8.2" + web3-core "1.8.2" + web3-eth "1.8.2" + web3-eth-personal "1.8.2" + web3-net "1.8.2" + web3-shh "1.8.2" + web3-utils "1.8.2" + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +websocket@^1.0.32: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" @@ -5085,11 +7826,28 @@ which-boxed-primitive@^1.0.2: is-string "^1.0.5" is-symbol "^1.0.3" +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== +which-typed-array@^1.1.2: + version "1.1.9" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -5104,6 +7862,11 @@ wide-align@1.1.3: dependencies: string-width "^1.0.2 || 2" +window-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" + integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== + word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -5119,6 +7882,14 @@ workerpool@6.2.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" @@ -5154,16 +7925,72 @@ ws@7.4.6: resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== +ws@^3.0.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + ws@^7.4.6: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== +xhr-request-promise@^0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" + integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== + dependencies: + xhr-request "^1.1.0" + +xhr-request@^1.0.1, xhr-request@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" + integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== + dependencies: + buffer-to-arraybuffer "^0.0.5" + object-assign "^4.1.1" + query-string "^5.0.1" + simple-get "^2.7.0" + timed-out "^4.0.1" + url-set-query "^1.0.0" + xhr "^2.0.4" + +xhr2-cookies@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" + integrity sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g== + dependencies: + cookiejar "^2.1.1" + +xhr@^2.0.4, xhr@^2.3.3: + version "2.6.0" + resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" + integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== + dependencies: + global "~4.4.0" + is-function "^1.0.1" + parse-headers "^2.0.0" + xtend "^4.0.0" + xmlhttprequest@1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +y18n@^3.2.1: + version "3.2.2" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" + integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== + y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" @@ -5174,7 +8001,12 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.2: +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== + +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== @@ -5197,6 +8029,14 @@ yargs-parser@20.2.4: resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== +yargs-parser@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" + integrity sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA== + dependencies: + camelcase "^3.0.0" + lodash.assign "^4.0.6" + yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" @@ -5250,6 +8090,26 @@ yargs@16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" +yargs@^4.7.1: + version "4.8.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" + integrity sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA== + dependencies: + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + lodash.assign "^4.0.3" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.1" + which-module "^1.0.0" + window-size "^0.2.0" + y18n "^3.2.1" + yargs-parser "^2.4.1" + yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"